我正在尝试获取二进制文件在CFG的pre-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
...更好的指针。

评论

嗯,在这个SE网站上,我们有IDApro,Radare2等专家,但是我并没有看到Angr的很多人...尝试吸引他们一些社区真是太好了! :-) @anon:感谢您对Angr的提问!

我知道OP已经在那里,但是,对于其他在这里浏览的人来说,存在一个带有自动邀请的Slack频道。希望可以在这里找到angr标签。

#1 楼


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


您是想知道节点属于哪个函数还是节点属于哪个函数

对于前者,每个块在图形中都有一个对应的CFGNode对象。每个CFGNode都有一个.function_address成员,该成员告诉您该节点所属的函数的地址。标记边缘的类型。 Ijk_Call跳变表示边缘是从块(或节点)到函数的调用。

顺便说一下,angr的CFG类不仅仅是.graph成员(这是networkx.DiGraph实例)。您可能会发现有时直接在CFG上进行操作比手动遍历图更容易。每个CFG.functions实例都有两个与其关联的功能内图:Function.graph。与遍历整个二进制文件的CFG相比,您可能会发现它更容易使用。试试。

评论


谢谢你的指点。是的,我指的是后者。我也想知道CFG如何表示共享库函数调用。它是否具有使用相应符号名到共享库的位置(实际上为@ptr)的跳转边缘?

– anon
17年8月16日在15:09

感谢GUI,我能够获得我期望的功能,例如memset,memcpy,_controlfp等。但是我需要知道是否可以在CFG节点中找到这些功能。

– anon
17年8月16日在15:44

即使共享库未随项目一起加载,它的确也指向共享库中的函数。

–鱼
17年8月16日在20:27



谢谢!您知道如何查看该节点是否为共享库函数吗?

– anon
17年8月16日在21:09

首先获取节点的地址。如果它是一个函数,则可以通过cfg.functions [addr]获取Function实例,然后访问.binary和.binary_name。如果不是函数,则可以调用project.loader.whats_at(addr)。

–鱼
17年8月16日在22:43