如何从汇编指令生成CFG?

逆向工程 部件 控制流图
2021-06-11 09:26:36

我想知道是否有任何工具可以使用汇编文件并将其转换为中间语言,例如 RREIL,然后从中间语言生成控制流图?这是我的程序集文件的示例:

7c90e430:   lea 0x10(%esp), %edi    R@edi[0xd38e0500][4](W) T0  A@0x0012fd30[0x00000000][4](R) T0
7c90e434:   popl  %eax  R@eax[0x0041771b][4](W) T0  M@0x0012fd20[0x7c901166][4](R) T0
7c90e435:   calll  %eax R@eax[0x7c901166][4](R) T0  M@0x0012fd20[0x7c901166][4](W) T0
7c901166:   lea 0x10(%esp), %eax    R@eax[0x7c901166][4](W) T0  A@0x0012fd30[0x00000000][4](R) T0
7c90116a:   movl  %eax, 0x4(%esp)   M@0x0012fd24[0x00000000][4](W) T0   R@eax[0x0012fd30][4](R) T0
7c90116e:   xor %ebp, %ebp  R@ebp[0x00150748][4](RW) T0 R@ebp[0x00150748][4](R) T0
7c901170:   jmp 0x7c91b057  J@0x00000000[0x00019ee7][4](R) T0
7c91b057:   mov %edi, %edi  R@edi[0x0012fd30][4](W) T0  R@edi[0x0012fd30][4](R) T0
7c91b059:   pushl  %ebp R@ebp[0x00000000][4](R) T0  M@0x0012fd1c[0x00000000][4](W) T0
7c91b05a:   mov %esp, %ebp  R@ebp[0x00000000][4](W) T0  R@esp[0x0012fd1c][4](R) T0
7c91b05c:   cmpb  $0x0, 0x7c97b20c  M@0x7c97b20c[0x00000000][1](R) T0   I@0x00000000[0x00000000][1](R) T0
7c91b063:   jz 0x7c9226ed   J@0x00000000[0x0000768a][4](R) T0

该文件是在沙箱中运行二进制文件后生成的,因此我不想将其转换为二进制文件并执行该过程。

PS:据我所知,所有现有工具都使用二进制文件并在我有一个程序集文件并想要执行此过程时执行此过程。

2个回答

大约 20 年前,我写了一篇关于这个主题的文章。它的标题是汇编语言控制流图,发表在 1998 年 9 月的 Dr. Dobb 杂志上。它使用 Perl 来解析汇编代码以生成控制流图的 Postscript 表示。然后可以通过任何可以呈现 Postscript 的方式在屏幕上打印或查看该图形。它是为现在已经过时的 8 位微控制器编写的,但该代码可以适用于任何指令集。它也可以毫无困难地适应输出 SVG。

该汇编语言中简单冒泡排序的示例输出如下所示: 在此处输入图片说明

左边的数字代表原始bubble.asm文件中的行号流向底部的流位于垂直线的右侧。流向顶部的流在左侧。

事实上,您拥有许多这样的工具。大多数情况下,您似乎需要的是所谓的二进制程序符号执行,它需要将汇编语言的语义转换为中间语言,以将其传递给处理位向量逻辑公式(通常是 Z3)的 SMT 求解器。但是,请注意,并非所有工具都支持翻译成中间语言。

以下是这些工具的一个小样本(虽然不是详尽无遗),按字典顺序给出(以避免任何偏见):

如果我意识到我忘记了一些,我会回到这个列表。

而且,关于你得到汇编代码的事实,然后只需编译它,你就会得到二进制文件。:-)