在 ghidra 反汇编中理解 local_ 的正确方法

逆向工程 拆卸 二元分析 x86 数据库 吉德拉
2021-06-24 09:14:48

附件是由 ghidra 生成的 x86 二进制文件的反汇编部分。

                             **************************************************************
                             *                          FUNCTION                          *
                             **************************************************************
                             undefined main(undefined1 param_1)
             undefined         AL:1           <RETURN>                                XREF[1]:     0804835e(W)  
             undefined1        Stack[0x4]:1   param_1                                 XREF[1]:     08048309(*)  
             undefined4        EAX:4          str_in                                  XREF[1]:     0804835e(W)  
             undefined4        Stack[0x0]:4   local_res0                              XREF[1]:     08048310(R)  
             undefined4        Stack[-0x10]:4 local_10                                XREF[6]:     08048358(R), 
                                                                                                   08048363(W), 
                                                                                                   0804836d(R), 
                                                                                                   08048388(R), 
                                                                                                   08048393(W), 
                                                                                                   0804839d(R)  
             undefined4        Stack[-0x14]:4 local_14                                XREF[2]:     0804831a(W), 
                                                                                                   08048366(R)  
             undefined4        Stack[-0x18]:4 local_18                                XREF[2]:     08048321(W), 
                                                                                                   08048396(R)  
             undefined4        Stack[-0x2c]:4 local_2c                                XREF[3]:     08048369(W), 
                                                                                                   08048399(W), 
                                                                                                   080483ac(W)  
             undefined4        Stack[-0x30]:4 local_30                                XREF[12]:    08048328(*), 
                                                                                                   08048334(*), 
                                                                                                   08048340(*), 
                                                                                                   0804834c(*), 
                                                                                                   0804835b(*), 
                                                                                                   08048370(*), 
                                                                                                   0804837c(*), 
                                                                                                   0804838b(*), 
                                                                                                   080483a0(*), 
                                                                                                   080483b4(*), 
                                                                                                   080483c2(*), 
                                                                                                   080483d0(*)  
                             main                                            XREF[2]:     Entry Point(*), 
                                                                                          _start:08048167(*)  
        08048309 8d 4c 24 04     LEA        ECX=>param_1,[ESP + 0x4]
        0804830d 83 e4 f0        AND        ESP,0xfffffff0
        08048310 ff 71 fc        PUSH       dword ptr [ECX + local_res0]
        08048313 55              PUSH       EBP
        08048314 89 e5           MOV        EBP,ESP
        08048316 51              PUSH       ECX
        08048317 83 ec 24        SUB        ESP,0x24
        0804831a c7 45 f4        MOV        dword ptr [EBP + local_14],DAT_080a6b19          = 6Ah    j
                 19 6b 0a 08
        08048321 c7 45 f0        MOV        dword ptr [EBP + local_18],s_the_ripper_080a6b1e = "the ripper"
                 1e 6b 0a 08

来自 gdb 的相同代码

   0x08048309 <+0>: lea    ecx,[esp+0x4]
   0x0804830d <+4>: and    esp,0xfffffff0
   0x08048310 <+7>: push   DWORD PTR [ecx-0x4]
   0x08048313 <+10>:    push   ebp
   0x08048314 <+11>:    mov    ebp,esp
   0x08048316 <+13>:    push   ecx
   0x08048317 <+14>:    sub    esp,0x24
=> 0x0804831a <+17>:    mov    DWORD PTR [ebp-0xc],0x80a6b19

为什么 ghidra 更改[ebp-0xc][EBP + local_14]. 我发现的类似问题是Ghidra 错误地解释堆栈指针但阅读答案,我没有理解[EBP + local_14]这里的含义,ghidra 只是重命名-0xc为一个易于阅读的名称local_14吗?我不明白如何确切地理解这一点。

在函数头中,显示Stack[-0x10]:4 local_10. 我认为这意味着local_10Stack[-0x10] 处是 4 字节变量,其中 Stack 是进入函数时的堆栈指针。但为什么它被添加到 ebp. ghidra 使用的这种表示是什么意思?

1个回答

由于局部变量通常放在堆栈中,x86并且esp寄存器在函数执行过程中可以改变,因此esp在函数入口处保存寄存器的值并相对于该值访问数据更方便ebp寄存器用于此目的。所以你会经常看到

push ebp
mov ebp, esp

函数开头的行。在您提供的示例中,情况就是这样 - 所有局部变量都以这种方式访问​​,通过ebp.

现在,局部变量有两种不同的命名约定:

  • 第一个也是更自然的一个:如果[ebp - xxx]被访问,它将显示为[ebp + local_xxx]. 这里,local_xxx = -xxx,例如,local_18 = -0x18
  • 第二个不太直观的方法是使用esp函数开头值。在您的示例中,mov ebp, esp在行之前将两个双字压入堆栈这意味着,如果local_xxx在第一个约定中调用某个局部变量,那么在第二个约定中它将被命名为local_xxx+0x8,例如local_18在第一个中将local_20在第二个中命名由 Ghidra 使用。

我们为什么要添加0x8第二个?因为两个双8字节)在esp值被保存到堆栈中之前被压入堆栈,ebp并且在x86架构堆栈中“向下增长”,这意味着如果您将某些东西压入堆栈,该值将被保存在那里并相应esp减少(在这种情况下,两次,按4字节)。因此,在您的特定示例中,您有指令

mov    DWORD PTR [ebp-0xc],0x80a6b19

这将显示为

mov    DWORD PTR [ebp+local_c],0x80a6b19

在第一次公约和

mov    DWORD PTR [ebp+local_14],0x80a6b19

在第二个中,在 Ghidra 中实现,因为0xc + 0x8 = 0x14.