我正在尝试构建一个通过调用objdump -d返回的汇编结果的控制流图。目前我提出的最好的方法是将结果的每一行放入链表中,并将每行的内存地址,操作码和操作数分开。我依靠objdump结果的常规性质将它们分开(内存地址是字符串2到字符串中代表每一行的字符7)。
一旦完成,我就开始实际的CFG指令。 CFG中的每个节点都包含一个起始和结束内存地址,一个指向前一个基本块的指针,以及指向任何子基本块的指针。然后我将浏览objdump结果并将操作码与x86_64中所有控制流操作码的数组进行比较。如果操作码是控制流操作码,我将地址记录为基本块的末尾,并根据操作码添加两个子指针(条件操作码)或一个(调用或返回)。
我正在用C实现这个过程,看起来它会起作用但感觉非常脆弱。有没有人有任何建议,或者我没有考虑的任何事情?
感谢您花时间阅读本文!
修改
我的想法是使用它来比较DynamoRIO生成的系统调用的堆栈跟踪与目标二进制文件的预期CFG,我希望像这样构建它将有助于此。我没有重复使用可用的东西,因为A)我真的没有关于它和B)我需要将图形转换为可用的数据结构,以便我可以进行路径比较。我将看一下您排行的页面上的一些实用程序,感谢您指出我正确的方向。感谢您的评论,我真的很感激!
答案 0 :(得分:3)
您应该使用专为程序分析而设计的IL。有几个。
DynInst项目(dyninst.org)有一个升级器,可以从ELF二进制文件转换为函数/程序的CFG(或者我最后一次查看)。 DynInst是用C ++编写的。
BinNavi使用来自IDA(交互式反汇编程序)的输出来构建IDA识别的IL失控流程图。我还推荐一份IDA副本,它会让你直观地检查CFG。一旦你在BinNavi有一个程序,你就可以获得它的函数/ CFG的IL表示。
函数指针只是静态识别控制流图的麻烦的开始。跳转表(在某些情况下为交换机用语句生成的类型,在其他情况下手动生成)也会引起攻击。我所知道的每个代码分析框架都采用了一种非常具有启发式的方法。然后,您有异常和异常处理,以及自修改代码。
祝你好运!您已经从DynamoRIO跟踪中获取了大量信息,我建议您尽可能多地利用该跟踪信息......答案 1 :(得分:0)
我找到了你的问题,因为我有兴趣寻找相同的东西。 我没有找到任何东西,为此写了一个简单的python脚本并将其扔在github上: https://github.com/zestrada/playground/blob/master/objdump_cfg/objdump_to_cfg.py
请注意,我有一些启发式方法来处理永不返回的函数,32位x86上的gcc堆栈保护程序等等......你可能会也可能不会想要这样的东西。
我对间接调用的处理方式与你的工作方式类似(图中的节点基本上是从间接返回时的源节点)。
希望这对那些希望以类似限制进行类似分析的人有用。