使用 IDAPython 命令行比较两个 dll 的调用图

逆向工程 艾达 蟒蛇 调用图 比较
2021-06-16 21:48:00

我需要为两个 DLL 生成调用图并使用 IDApython 进行比较,它必须在命令行中自动执行。

如何生成并保存调用图并立即打开下一个DLL并生成并保存调用图然后进行比较?

2个回答

正如@tmr232 所说,您可以使用Diphora,它会自动为您执行此操作。否则,如果您更喜欢命令行工具(顺便说一句,它不需要 IDA),您可以使用Pyewgcluster.py脚本。

如果您更喜欢自己编写一些东西,请记住比较 2 个二进制文件不是一项微不足道的任务。也就是说,我将解释 gcluster.py 和 Diaphora 中 2 个二进制文件的调用图的比较是如何工作的:

  1. 首先,将二进制文件加载到工具中并分析代码。该工具可以是 Pyew (gcluster) 或 IDA (Diaphora)。
  2. 代码分析步骤收集与函数、调用图和流程图(每个函数的基本块及其关系以及函数的关系)相关的信息。
  3. 使用这些信息,我计算了每个具有 1 个以上基本块的函数的圈复杂度。
  4. 使用哥德尔编号,我为每个圈复杂度分配了一个质数(就是这样,对于每个函数)。
  5. 然后,将所有这些质数对应于所有函数,我将它们相乘以获得大量“哈希”。这一步是发明者 Halvar Flake 和 @rolfrolles 在他们的“基于图形的可执行对象比较”论文中所说的“小素数产品”
  6. 乘法的结果是程序的调用图签名。
  7. 如果 2 个二进制文件的调用图签名相等,则两个二进制文件的调用图很可能相同。我说“很可能”是因为忽略了小函数,而且,使用函数的圈复杂度作为模糊标识符是模糊的:2 个完全不同的函数可以具有相同的圈复杂度。在任何情况下,调用图签名在大多数情况下都足够好(我还没有看到情况不是这样)。
  8. 如果调用图签名不同,则分解素数(您已经计算过),在两个集合中删除它们(即,在两个二进制文件中)并计算两个二进制文件中剩余素数(对应于函数)的差异百分比.

比较调用图的另一种方法是遍历两个图并计算两个图之间的差异(考虑到您有某种方法可以确定二进制 A 中的函数 F 等于二进制 B 中的函数 F',这不是不重要的)。我不建议你这样做,除非解决如何这样做是你的问题/你想做什么。

我的 2 美分。

这是一个非常广泛的问题,由一些简单的问题组成。

如何从命令行操作 IDA?

根据此链接,您可以-S在自动分析完成后使用switch从命令行调用 IDA以运行特定脚本。您可以创建 shell 脚本以从命令行运行多个 ida 实例。

如何生成函数图并保存?

#not tested, beware of errors, use on your own risk
# if you find GDL format problematic you can use ODT format
# by replacing idaapi.CHART_GEN_GDL to idaapi.CHART_GEN_ODT
import idaapi
import idc 
import idautils

for ea in idautils.Functions():
    idc.GenFuncGdl("%s.gdl" % idc.GetFunctionName(ea), idc.GetFunctionName(ea), ea , idc.BADADDR, idaapi.CHART_GEN_GDL)

如何生成整个调用图?

很简单:

idc.GenCallGdl("z:\\callgdl.gdl", "TheTitle", CHART_GEN_GDL)

请注意使用 CHART_WINGRAPH 和 CHART_NOLIBFUNCS 作为标志的可能性。

如果你想使用的功能idaapi模块来代替,看idaapi.gen_simple_call_chartidaapi.gen_complex_call_chart文档在这里

如何比较调用图?

这取决于您究竟想从比较中得到什么。

希望能帮助到你。