为小型 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()
的第一个参数。
我有这个简单的 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()
的第一个参数。