如何使用 angr 获取共享库的函数调用

逆向工程 静态分析 Python 二进制 控制流图 愤怒
2021-07-08 22:55:07

我正在尝试获取二进制文件在 CFG 的预序 DFT 遍历中执行的所有库函数调用。我能够得到像这样的 CFG:

import sys, angr
import networkx as nx
proj = angr.Project(sys.argv[1],auto_load_libs=False)
cfg = proj.analyses.CFG().graph

我能够得到 CFG,我什至可以像这样遍历它(假设我得到了正确的主函数节点):

s = nx.dfs_preorder_nodes(cfg,mainFuncNode)
nodes = []
try:
    while True:
        nodes.append(ns.next())
except:
    pass

但是我不知道如何从节点获取函数调用(如果他们真的这样做的话)。我阅读了一些文档,我能想到的是:

for n in nodes:
    if n.is_simprocedure:
          print n.to_codenode().function

输出全部为 None 并且我确定这是错误的,因为二进制文件正在执行一些 I/O 操作。所以我希望看到类似的东西:

  • libc_puts
  • libc_gets
  • ...

如果您能给我一些更好的指示,我将不胜感激。

1个回答

但是我不知道如何从节点获取函数调用

你是说你想知道一个节点属于哪个函数,或者一个节点调用哪个函数?

对于前者,每个块CFGNode在图中都有一个对应的对象。每个CFGNode都有一个.function_address成员,它告诉您该节点所属的函数的地址。

对于后者,图中的每条边都标有属性,我们使用“jumpkind”来标记边的类型。一个Ijk_Calljumpkind装置,其边缘是从一个块(或节点)的函数的调用。

顺便说一下,angr 的 CFG 类不仅仅是.graph成员(它是一个networkx.DiGraph实例)。有时您可能会发现直接处理CFG而不是手动遍历图形更容易

此外,一旦生成了 CFG,您可以通过访问 来访问所有功能CFG.functions每个Function实例都有两个与之关联的函数内图:a.graph和 a .transition_graph您可能会发现它比遍历整个二进制文件的 CFG 更容易使用。

最后,如果你喜欢 GUI,并且你有很大的耐心,你可能想尝试angr 管理