您如何将 C 源代码与 IDA Pro 中相应的二进制程序集进行比较?

逆向工程 艾达 拆卸 部件 C 反汇编者
2021-07-04 06:49:08

我想知道是否有办法将源代码与 IDA Pro 中的反汇编程序集进行比较?(例如,我在 Linux 中编译 hello.c,然后在 OS X 中的 IDA Pro 中打开二进制文件,并希望将程序集与源代码进行比较,以便更容易地找出发生了什么)。有这样的功能吗?

添加来自评论: 顺便说一句,我忘了提,我在 OS-X 中,二进制文件是由 Lunux 编译的

4个回答

你可以用DWARF信息编译你的文件,因为 IDA 支持它:

IDA中的矮人

并不真地。但是,例如 Visual Studio 有一个调试器,如果您在加载解决方案的同一实例中启动调试器,它可以直接指向源(从发生问题的地方)。Visual Studio 还支持输出 PDB 文件(和 MAP 文件,如果需要),这些文件将为您提供所有函数名称、变量名称、参数等。这在 IDA 中调试时也很有帮助。

您应该了解您的编译器是否还可以输出一种可以在 IDA Pro 中导入的“调试”文件。如果没有,那么在这种情况下是不可能的。

我之前在寻找 IP 盗窃时已经这样做了,虽然您不太可能恢复完美的 1 对 1 匹配,但仍有某些结构和流程会潜入从其他地方复制的功能中。阅读一段代码然后复制它并且不让原始想法影响您的设计是非常困难的。您有类似的情况,只是您正在寻找匹配函数以简化逆向工程。

这就是我会做的:

  • 找到我怀疑包含我有兴趣识别的代码的二进制文件。
  • 如果我有我有兴趣在二进制文件中查找的参考源:
    • 找出用于构建可疑二进制文件的编译器。
    • 使用相同的编译器来编译参考源。现在我们有了参考二进制文件和可疑二进制文件。
  • 一旦我有两个二进制文件,引用并怀疑我会通过分析流图和调用图形的东西来运行它们,例如BinDiff
  • 然后你会得到一组你必须深入分析的候选人。

我已经成功地使用这种策略成功地识别和分析了用母语编写的软件和用托管语言编写的软件之间的相似性。这是一个相当强大的技术。如果您的预算有限,并且参考二进制文件和可疑二进制文件都使用相同的编译器针对相同的平台,则可以从参考二进制文件构建FLIRT数据库。不过,这可能会错过大量优秀的候选人。

如果您不分析其他人生成的任何二进制文件,只需使用调试信息构建您的目标,您将获得所需的所有信息,如果您使用 GCC ,请参阅DWARF,如果您使用 MSVC ,请参阅PDB。或者只是告诉编译器产生汇编输出:GCCMSVC

如果这是为了学习目的并且您想了解如何为您的源代码行生成程序集创建程序集列表每个主要编译器都应该有选项

例如,使用 Visual Studio,您可以发出 /FAcs 开关以生成扩展名为 .cod
程序集列表文件,该列表文件将显示源中的每一行如何转换为程序集

comparesrc:\>dir /b
comparesrc.cpp

comparesrc:\>type comparesrc.cpp
#include <stdio.h>  // standard include file
int main (void)
{ // this line will become prolog
    printf("hello my dear source compare\n");  // see str in .data section
    puts("c");  // will put a char* with line break to console
    puts("om");
    puts("pare");
    int a,b,c,d;
    a = 2; b =3 ; c = 4;
    d = a+b-c;    // 2+3 -4 = 1
    printf("%d\n",d);  // should print 1
    d = (a*b)/c;  // 2*3 /4 = 6 /4  numerator = 1
    printf("%d\n",d);  // should printf 1
    d = (a*b)%c;   // 2 * 3 % 4 denominator = 2
    printf("%d\n",d);  // should print 2
    return 0;   // lets generate a cod file and see the assembly
}   // this line will get converted to epilog



comparesrc:\>cl /FAcs /nologo /Zi  comparesrc.cpp /link /RELEASE
comparesrc.cpp

comparesrc:\>type comparesrc.cod
; Listing generated by Microsoft (R) Optimizing Compiler Version 16.00.30319.01


        TITLE   XXXX\comparesrc.cpp
        .686P
        .XMM
        include listing.inc
        .model  flat

INCLUDELIB LIBCMT
INCLUDELIB OLDNAMES

CONST   SEGMENT
$SG3850 DB      'hello my dear source compare', 0aH, 00H
        ORG $+2
$SG3851 DB      'c', 00H
        ORG $+2
$SG3852 DB      'om', 00H
        ORG $+1
$SG3853 DB      'pare', 00H
        ORG $+3
$SG3858 DB      '%d', 0aH, 00H
$SG3859 DB      '%d', 0aH, 00H
$SG3860 DB      '%d', 0aH, 00H
CONST   ENDS
PUBLIC  _main
EXTRN   _puts:PROC
EXTRN   _printf:PROC
; Function compile flags: /Odtp
; File xxx\comparesrc.cpp

_TEXT   SEGMENT
_c$ = -16                                               ; size = 4
_d$ = -12                                               ; size = 4
_b$ = -8                                                ; size = 4
_a$ = -4                                                ; size = 4
_main   PROC

; 3    : { // this line will become prolog

  00000 55               push    ebp
  00001 8b ec            mov     ebp, esp
  00003 83 ec 10         sub     esp, 16                        ; 00000010H

; 4    :     printf("hello my dear source compare\n");  // see str in .data sect
ion

  00006 68 00 00 00 00   push    OFFSET $SG3850
  0000b e8 00 00 00 00   call    _printf
  00010 83 c4 04         add     esp, 4

; 5    :     puts("c");  // will put a char* with line break to console

  00013 68 00 00 00 00   push    OFFSET $SG3851
  00018 e8 00 00 00 00   call    _puts
  0001d 83 c4 04         add     esp, 4

; 6    :     puts("om");

  00020 68 00 00 00 00   push    OFFSET $SG3852
  00025 e8 00 00 00 00   call    _puts
  0002a 83 c4 04         add     esp, 4

; 7    :     puts("pare");

  0002d 68 00 00 00 00   push    OFFSET $SG3853
  00032 e8 00 00 00 00   call    _puts
  00037 83 c4 04         add     esp, 4

; 8    :     int a,b,c,d;
; 9    :     a = 2; b =3 ; c = 4;

  0003a c7 45 fc 02 00
        00 00            mov     DWORD PTR _a$[ebp], 2
  00041 c7 45 f8 03 00
        00 00            mov     DWORD PTR _b$[ebp], 3
  00048 c7 45 f0 04 00
        00 00            mov     DWORD PTR _c$[ebp], 4

; 10   :     d = a+b-c;    // 2+3 -4 = 1

  0004f 8b 45 fc         mov     eax, DWORD PTR _a$[ebp]
  00052 03 45 f8         add     eax, DWORD PTR _b$[ebp]
  00055 2b 45 f0         sub     eax, DWORD PTR _c$[ebp]
  00058 89 45 f4         mov     DWORD PTR _d$[ebp], eax

; 11   :     printf("%d\n",d);  // should print 1

  0005b 8b 4d f4         mov     ecx, DWORD PTR _d$[ebp]
  0005e 51               push    ecx
  0005f 68 00 00 00 00   push    OFFSET $SG3858
  00064 e8 00 00 00 00   call    _printf
  00069 83 c4 08         add     esp, 8

; 12   :     d = (a*b)/c;  // 2*3 /4 = 6 /4  numerator = 1

  0006c 8b 45 fc         mov     eax, DWORD PTR _a$[ebp]
  0006f 0f af 45 f8      imul    eax, DWORD PTR _b$[ebp]
  00073 99               cdq
  00074 f7 7d f0         idiv    DWORD PTR _c$[ebp]
  00077 89 45 f4         mov     DWORD PTR _d$[ebp], eax

; 13   :     printf("%d\n",d);  // should printf 1

  0007a 8b 55 f4         mov     edx, DWORD PTR _d$[ebp]
  0007d 52               push    edx
  0007e 68 00 00 00 00   push    OFFSET $SG3859
  00083 e8 00 00 00 00   call    _printf
  00088 83 c4 08         add     esp, 8

; 14   :     d = (a*b)%c;   // 2 * 3 % 4 denominator = 2

  0008b 8b 45 fc         mov     eax, DWORD PTR _a$[ebp]
  0008e 0f af 45 f8      imul    eax, DWORD PTR _b$[ebp]
  00092 99               cdq
  00093 f7 7d f0         idiv    DWORD PTR _c$[ebp]
  00096 89 55 f4         mov     DWORD PTR _d$[ebp], edx

; 15   :     printf("%d\n",d);  // should print 2

  00099 8b 45 f4         mov     eax, DWORD PTR _d$[ebp]
  0009c 50               push    eax
  0009d 68 00 00 00 00   push    OFFSET $SG3860
  000a2 e8 00 00 00 00   call    _printf
  000a7 83 c4 08         add     esp, 8

; 16   :     return 0;   // lets generate a cod file and see the assembly

  000aa 33 c0            xor     eax, eax

; 17   : }   // this line will get converted to epilog

  000ac 8b e5            mov     esp, ebp
  000ae 5d               pop     ebp
  000af c3               ret     0
_main   ENDP
_TEXT   ENDS
END

comparesrc:\>