为小型 C 程序解释的 x86 代码

x86 code explained for small c program

我有这个简单的 C 函数:

void vulnerable(char *arg){
    char buf[100];
    strcpy(buf, arg);
}

当我在 GDB 中反汇编它时,我得到了这个:

0x08048ee0 <+0>:    push   %ebp
0x08048ee1 <+1>:    mov    %esp,%ebp
0x08048ee3 <+3>:    sub    [=11=]x88,%esp
=> 0x08048ee9 <+9>: mov    0x8(%ebp),%eax
0x08048eec <+12>:   mov    %eax,0x4(%esp)
0x08048ef0 <+16>:   lea    -0x6c(%ebp),%eax
0x08048ef3 <+19>:   mov    %eax,(%esp)
0x08048ef6 <+22>:   call   0x8048200
0x08048efb <+27>:   leave  
0x08048efc <+28>:   ret

我不是很懂这些台词。

0x08048ee3 <+3>:    sub    [=12=]x88,%esp  #why is 136 bytes being subtracted? Buf is only 100
0x08048ee9 <+9>:    mov    0x8(%ebp),%eax  #I didnt think anything was in eax to move to ebp
0x08048eec <+12>:   mov    %eax,0x4(%esp) #whats being moved here
0x08048ef0 <+16>:   lea    -0x6c(%ebp),#eax #loading from the stack to ebp?
0x08048ef3 <+19>:   mov    %eax,(%esp) # now back to eax?

而且我想知道buf的地址。当我尝试 p &buf 它返回一个地址,但它是空的,即使我在呼叫线后中断。

谁能帮助我更好地理解代码。 谢谢!

0x08048ee3 <+3>:    sub    [=10=]x88,%esp  #why is 136 bytes being subtracted? Buf is only 100

buf 只有 100 个字节长,但是 strcpy() 的两个参数在堆栈上也需要 space - 每个参数 4 个字节,所以是 108 个字节。再添加 4 个字节以保持堆栈指针 8 字节对齐,您将得到 112。这仍然远远低于编译器实际分配的 136 个字节——可能编译器已为某些临时对象分配了堆栈 space and/or 保存寄存器,然后优化掉实际的临时文件和寄存器溢出。

0x08048ee9 <+9>:    mov    0x8(%ebp),%eax  #I didnt think anything was in eax to move to ebp

这是 AT&T 语法,源后面跟着目标。所以这是将第一个函数参数 arg 的值 0x8(%ebp) 移动到 %eax.

0x08048eec <+12>:   mov    %eax,0x4(%esp) #whats being moved here

然后将 arg 的值复制到堆栈,作为 strcpy() 的第二个参数。

0x08048ef0 <+16>:   lea    -0x6c(%ebp),%eax #loading from the stack to ebp?

lea 是加载有效地址。这是将 -0x6c(%ebp) 的地址加载到 %eax.

中,这是本地数组 buf
0x08048ef3 <+19>:   mov    %eax,(%esp) # now back to eax?

buf的地址是从%eax复制到堆栈的,作为strcpy()的第一个参数。