assembly - 在 Art of Exploitation 示例中被 [ebp-0xc] 而不是 [ebp-4] 混淆

标签 assembly gcc x86

我正在阅读这本书 Hacking: The Art of Exploitation, 2nd Edition
并在简单的 C 程序中

#include <stdio.h>
int main()
{
    int i;  
    for (i = 0; i < 10; i++)
    {
        puts("Hello, world!\n");
    }
    return 0;
}
书中列出gdb调试会先修改ebp寄存器:
(gdb) x/i $eip 0x8048384 <main+16>: mov DWORD PTR [ebp-4],0x0
正如它所解释的那样
这条汇编指令将把 0 的值移动到内存中
在存储在 EBP 寄存器中的地址处,减去 4。这是 C 变量的位置
能够 i 存储在内存中; i 被声明为一个使用 4 个字节的整数
x86 处理器上的内存
这对我来说很有意义,但是当我在我的“非常旧的 I386”Linux 笔记本电脑上测试确切的步骤时,我得到了:
(gdb) x/i $eip => 0x4011b6 <main+29>:   mov    DWORD PTR [ebp-0xc],0x0
所以在我的笔记本电脑上,它显示 [ebp-0xc],而不是 [ebp-4]。
根据我的理解,“0xc”作为十六进制将是 12,所以它将是 12 个字节?如果是这样,为什么?
这是我笔记本电脑上这个简单程序的整个组装转储
(gdb) 反汇编主
Dump of assembler code for function main:
   0x00401199 <+0>: lea    ecx,[esp+0x4]
   0x0040119d <+4>: and    esp,0xfffffff0
   0x004011a0 <+7>: push   DWORD PTR [ecx-0x4]
   0x004011a3 <+10>:    push   ebp
   0x004011a4 <+11>:    mov    ebp,esp
   0x004011a6 <+13>:    push   ebx
   0x004011a7 <+14>:    push   ecx
   0x004011a8 <+15>:    sub    esp,0x10
   0x004011ab <+18>:    call   0x4010a0 <__x86.get_pc_thunk.bx>
   0x004011b0 <+23>:    add    ebx,0x2e50
=> 0x004011b6 <+29>:    mov    DWORD PTR [ebp-0xc],0x0
   0x004011bd <+36>:    jmp    0x4011d5 <main+60>
   0x004011bf <+38>:    sub    esp,0xc
   0x004011c2 <+41>:    lea    eax,[ebx-0x1ff8]
   0x004011c8 <+47>:    push   eax
   0x004011c9 <+48>:    call   0x401030 <puts@plt>
   0x004011ce <+53>:    add    esp,0x10
   0x004011d1 <+56>:    add    DWORD PTR [ebp-0xc],0x1
   0x004011d5 <+60>:    cmp    DWORD PTR [ebp-0xc],0x9
   0x004011d9 <+64>:    jle    0x4011bf <main+38>
   0x004011db <+66>:    mov    eax,0x0
   0x004011e0 <+71>:    lea    esp,[ebp-0x8]
   0x004011e3 <+74>:    pop    ecx
   0x004011e4 <+75>:    pop    ebx
   0x004011e5 <+76>:    pop    ebp
   0x004011e6 <+77>:    lea    esp,[ecx-0x4]
   0x004011e9 <+80>:    ret    
End of assembler dump.

最佳答案

sub esp,0x10在堆栈上为变量和其他东西分配了 16 个字节(相当于四个寄存器)的空间。mov DWORD PTR [ebp-0xc],0x0似乎是第一个引用插槽 ebp-0xc ,并且它被初始化为零。看了之后cmp DWORD PTR [ebp-0xc],0x9main+60我确定这是 i = 0来自 for 的初始化部分环形。
编译器可以将变量放在它想要的地方,虽然确定性,它会随着编译器的补丁版本而改变。

关于assembly - 在 Art of Exploitation 示例中被 [ebp-0xc] 而不是 [ebp-4] 混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66090921/

相关文章:

c - 参数长度可变的宏

c++ - 将 x86 代码注入(inject) x64 进程

linux - 为什么clflush需要+m常量

c - 在 L1 和 L2 预取数据

C++ 当您从函数返回结构时,汇编中实际发生了什么?

assembly - 在 x86 asm 中输出变量值

assembly - 用汇编语言定义 "variables"

c++ - OllyDbg 无法调试visual studio exe

c - 程序集中的线程本地存储

gcc - 原生树莓派编译问题