我有一个简单的C函数:
void vulnerable(char *arg){
char buf[100];
strcpy(buf, arg);
}
当我在GDB中分解它时,我得到了这个:
0x08048ee0 <+0>: push %ebp
0x08048ee1 <+1>: mov %esp,%ebp
0x08048ee3 <+3>: sub $0x88,%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 $0x88,%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?
我想知道布夫的地址。当我尝试p &buf
时,它会返回一个地址,但即使我在呼叫线后中断,它也是空的。
有人能帮我更好地理解代码吗。谢谢
0x08048ee3 <+3>: sub $0x88,%esp #why is 136 bytes being subtracted? Buf is only 100
buf
只有100个字节长,但堆栈上也需要空间来容纳strcpy()
的两个参数,每个参数为4个字节,因此为108个字节。再加4个字节,使堆栈指针保持8字节对齐,得到112。这仍然远远低于编译器实际分配的136个字节——很可能编译器已经为一些临时和/或保存寄存器分配了堆栈空间,然后优化了实际的临时和寄存器溢出。
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)
的地址(即本地阵列buf
)加载到%eax
中。
0x08048ef3 <+19>: mov %eax,(%esp) # now back to eax?
buf
的地址是从%eax
复制到堆栈的地址,作为strcpy()
的第一个参数。