searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

基于Ghidra Pcode 实现后向数据流分析

2025-12-11 01:52:50
0
0

vul函数分析

WORKING WITH GHIDRA'S P-CODE TO IDENTIFY VULNERABLE FUNCTION CALLS

https://www.riverloopsecurity.com/blog/2019/05/pcode/

ghidra-bridge

使用ghidra-bridge,可以调用别的package

图结构

ghidra自定义的图结构在以下文件中实现,常用API也可以从下边文件中寻找

常用成员

  • VertexSet vertices
  • EdgeSet edges
  • AttributeManager<Vertex> vertexAttributes
  • AttributeManager<Vertex> edgeAttributes

其中vertices和edges是记录节点和边的集合,vertexAttributes和edgeAttributes是管理节点和边属性的实例,具体的用法可以参考下边的实例代码:

from ghidra.util.graph import DirectedGraph
from ghidra.util.graph.attributes import *

self.graph = DirectedGraph()
self.graph.add(Vertex(1))
e = Edge(Vertex(1), Vertex(2))
self.graph.add(e)
edgeAttrm = self.graph.edgeAttributes()
att = edgeAttrm.createAttribute("type",AttributeManager.INTEGER_TYPE)
att.setValue(e, 123)
print(att.getValue(e))

构建程序依赖图

  • 图中结点
    • Varnode 和 pcodeAST (方便符号执行?)
    • Varnode - 调用getDef - 返回 pcode - 添加边
      • 获取pcodeAST的op类型,根据不同op类型进行处理
      • Load 、 cast等
  • 图中边的类型定义(看到这里我怎么觉得ghidra应该是有内置的图结构的?):

P-code

http://galaxylab.com.cn/使用ghidra-p-code进行辅助逆向分析/

基本概念:

https://blog.csdn.net/weixin_49393427/article/details/123201539

概述

  • Ghidra P-Code是专为逆向工程设计的寄存器传输语言,能够对许多不同的处理器进行建模。
  • P-Code会将单个处理器指令转化为一系列的P-Code操作, 这些操作将处理器状态的一部分作为输入和输出变量(VarNodes)。
    • 通过getInput函数可以方便的获取P-Code的input参数

VarNode和Pcode

Varnode是pcode输入输出状态变量

  • VarnodeAST 继承自 Varnode,是其抽象语法树中的节点,其中def和descend的是当前varnodeAST的入边和出边
private PcodeOp def;				// Operation which defines this varnode (in-edge)
private LinkedList<PcodeOp> descend;		// List of operations which use this varnode (out-edges)

@Override
public PcodeOp getDef() {
    return def;
}

@Override
public Iterator<PcodeOp> getDescendants() {
    return descend.iterator();
}
  • PcodeOp和PcodeOpAST也是上述类似的关系
  • PcodeOpBank是PcodeOpAST的容器
  • varnode对象有很多类型,如unique、register、const等,其中unique类型的对象需要进一步分析

常用接口

遍历pcode

Iterator<PcodeOpAST> pcodeAst = hf.getPcodeOps();
		
while (pcodeAst.hasNext()) {
		
	PcodeOpAST pcodeast = pcodeAst.next();

	PrintAST(pcodeast);
}

获取变量名

HighVariable getNamedVariable(Varnode vnode) {
     HighVariable hvar = vnode.getHigh();
     if (hvar.getName() != null)
       return hvar;

     // Calling back getNamedVariable() on all of the pcode's input nodes
}

遍历所有的symbol

https://github.com/NationalSecurityAgency/ghidra/issues/1561

有时候会有想获取DAT变量的需求

while (addrIter.hasNext() && !monitor.isCancelled()) {
		Address addr = addrIter.next();
		Symbol sym = getSymbolAt(addr); 
		
		if (sym != null) {
			printf("Symbol at 0x%x", addr.getOffset());
			printf(" = %s\n", sym.getName());
		} 
	}

PcodeOP

PTRADD

类似数组的表示 input0 + input1 * input2,其中

  • 0 是数组基地址
  • 1 是数组的index
  • 2 是常量,每次的步长

PTRADD生成数组中指定索引处元素的指针值,并将其存储在输出中。

PTRSUB

PTRSUB执行简单的指针计算,即input0 + input1,但也显式地指示input0是对结构化数据类型的引用

  • 0 是基址
  • 1 是偏移

INDIRECT

INDIRECT操作符将input0复制到输出中,但是该值可以通过input1引用的操作以间接的方式改变, Output1不是机器状态的一部分,但实际上是对特定p-code操作符的内部引用,该操作符可能会影响输出varnode的值。和MULTIEQUAL一样,这个操作用于生成静态单赋值表。

0条评论
0 / 1000
c****p
3文章数
0粉丝数
c****p
3 文章 | 0 粉丝
c****p
3文章数
0粉丝数
c****p
3 文章 | 0 粉丝
原创

基于Ghidra Pcode 实现后向数据流分析

2025-12-11 01:52:50
0
0

vul函数分析

WORKING WITH GHIDRA'S P-CODE TO IDENTIFY VULNERABLE FUNCTION CALLS

https://www.riverloopsecurity.com/blog/2019/05/pcode/

ghidra-bridge

使用ghidra-bridge,可以调用别的package

图结构

ghidra自定义的图结构在以下文件中实现,常用API也可以从下边文件中寻找

常用成员

  • VertexSet vertices
  • EdgeSet edges
  • AttributeManager<Vertex> vertexAttributes
  • AttributeManager<Vertex> edgeAttributes

其中vertices和edges是记录节点和边的集合,vertexAttributes和edgeAttributes是管理节点和边属性的实例,具体的用法可以参考下边的实例代码:

from ghidra.util.graph import DirectedGraph
from ghidra.util.graph.attributes import *

self.graph = DirectedGraph()
self.graph.add(Vertex(1))
e = Edge(Vertex(1), Vertex(2))
self.graph.add(e)
edgeAttrm = self.graph.edgeAttributes()
att = edgeAttrm.createAttribute("type",AttributeManager.INTEGER_TYPE)
att.setValue(e, 123)
print(att.getValue(e))

构建程序依赖图

  • 图中结点
    • Varnode 和 pcodeAST (方便符号执行?)
    • Varnode - 调用getDef - 返回 pcode - 添加边
      • 获取pcodeAST的op类型,根据不同op类型进行处理
      • Load 、 cast等
  • 图中边的类型定义(看到这里我怎么觉得ghidra应该是有内置的图结构的?):

P-code

http://galaxylab.com.cn/使用ghidra-p-code进行辅助逆向分析/

基本概念:

https://blog.csdn.net/weixin_49393427/article/details/123201539

概述

  • Ghidra P-Code是专为逆向工程设计的寄存器传输语言,能够对许多不同的处理器进行建模。
  • P-Code会将单个处理器指令转化为一系列的P-Code操作, 这些操作将处理器状态的一部分作为输入和输出变量(VarNodes)。
    • 通过getInput函数可以方便的获取P-Code的input参数

VarNode和Pcode

Varnode是pcode输入输出状态变量

  • VarnodeAST 继承自 Varnode,是其抽象语法树中的节点,其中def和descend的是当前varnodeAST的入边和出边
private PcodeOp def;				// Operation which defines this varnode (in-edge)
private LinkedList<PcodeOp> descend;		// List of operations which use this varnode (out-edges)

@Override
public PcodeOp getDef() {
    return def;
}

@Override
public Iterator<PcodeOp> getDescendants() {
    return descend.iterator();
}
  • PcodeOp和PcodeOpAST也是上述类似的关系
  • PcodeOpBank是PcodeOpAST的容器
  • varnode对象有很多类型,如unique、register、const等,其中unique类型的对象需要进一步分析

常用接口

遍历pcode

Iterator<PcodeOpAST> pcodeAst = hf.getPcodeOps();
		
while (pcodeAst.hasNext()) {
		
	PcodeOpAST pcodeast = pcodeAst.next();

	PrintAST(pcodeast);
}

获取变量名

HighVariable getNamedVariable(Varnode vnode) {
     HighVariable hvar = vnode.getHigh();
     if (hvar.getName() != null)
       return hvar;

     // Calling back getNamedVariable() on all of the pcode's input nodes
}

遍历所有的symbol

https://github.com/NationalSecurityAgency/ghidra/issues/1561

有时候会有想获取DAT变量的需求

while (addrIter.hasNext() && !monitor.isCancelled()) {
		Address addr = addrIter.next();
		Symbol sym = getSymbolAt(addr); 
		
		if (sym != null) {
			printf("Symbol at 0x%x", addr.getOffset());
			printf(" = %s\n", sym.getName());
		} 
	}

PcodeOP

PTRADD

类似数组的表示 input0 + input1 * input2,其中

  • 0 是数组基地址
  • 1 是数组的index
  • 2 是常量,每次的步长

PTRADD生成数组中指定索引处元素的指针值,并将其存储在输出中。

PTRSUB

PTRSUB执行简单的指针计算,即input0 + input1,但也显式地指示input0是对结构化数据类型的引用

  • 0 是基址
  • 1 是偏移

INDIRECT

INDIRECT操作符将input0复制到输出中,但是该值可以通过input1引用的操作以间接的方式改变, Output1不是机器状态的一部分,但实际上是对特定p-code操作符的内部引用,该操作符可能会影响输出varnode的值。和MULTIEQUAL一样,这个操作用于生成静态单赋值表。

文章来自个人专栏
文章 | 订阅
0条评论
0 / 1000
请输入你的评论
0
0