【发布时间】:2011-06-28 17:01:39
【问题描述】:
我正在研究缓冲区溢出(在 IA32 架构上),我想用这个示例程序澄清一件特别的事情:
int main(int argc, char **argv) {
char array[512];
if(argc > 1)
strcpy(array, argv[1]);
}
我在执行汇编代码期间跟踪了 ebp,esp 寄存器的变化: 函数 main 的汇编代码转储:
0x080483c4 <+0>: push ebp
0x080483c5 <+1>: mov ebp,esp
0x080483c7 <+3>: sub esp,0x208
0x080483cd <+9>: cmp DWORD PTR [ebp+0x8],0x1
0x080483d1 <+13>: jle 0x80483ed <main+41>
0x080483d3 <+15>: mov eax,DWORD PTR [ebp+0xc]
0x080483d6 <+18>: add eax,0x4
0x080483d9 <+21>: mov eax,DWORD PTR [eax]
0x080483db <+23>: mov DWORD PTR [esp+0x4],eax
0x080483df <+27>: lea eax,[ebp-0x200]
0x080483e5 <+33>: mov DWORD PTR [esp],eax
0x080483e8 <+36>: call 0x80482f4 <strcpy@plt>
0x080483ed <+41>: leave
0x080483ee <+42>: ret
esp,ebp 寄存器值为:
program start
esp: 0xbffff24c
ebp: 0xbffff2c8
push ebp
esp: 0xbffff248
ebp: 0xbffff2c8
mov ebp,esp
esp: 0xbffff248
ebp: 0xbffff248
sub esp,0x208
esp: 0xbffff040
ebp: 0xbffff248
strcpy call (ebp is overwritten)
esp: 0xbffff250
ebp: 0x41414141
当我输入 520 个字符“a”时,导致 EBP、EIP 溢出。而内存是这样的:
Lower Memory Addresses
0xbffff070: 0xbffff078 0xbffff492 0xaaaaaaaa 0xaaaaaaaa
0xbffff080: 0xaaaaaaaa 0xaaaaaaaa 0xaaaaaaaa 0xaaaaaaaa
0xbffff090: 0xaaaaaaaa 0xaaaaaaaa 0xaaaaaaaa 0xaaaaaaaa
0xbffff0a0: 0xaaaaaaaa 0xaaaaaaaa 0xaaaaaaaa 0xaaaaaaaa
0xbffff0b0: 0xaaaaaaaa 0xaaaaaaaa 0xaaaaaaaa 0xaaaaaaaa
...
0xbffff270: 0xaaaaaaaa 0xaaaaaaaa 0xaaaaaaaa 0xaaaaaaaa
Higher Memory Addresses
我感兴趣的是:为什么缓冲区从地址 0xbffff078 开始,如果 ESP 指向地址 0xbffff040(当局部变量的位置 - 缓冲区 - 在堆栈上保留时)。缓冲区应该保存在 0xbffff040 地址。谁能解释为什么不是?
【问题讨论】:
-
你的
'a'字符是如何变成0xaaaaaaaa的?您是在向我们展示整个节目吗? -
你确定
array的地址是0xbffff078,而不是0xbffff048?也许strcpy的后奏曲试图做一些堆栈的事情,覆盖了 0xbffff070 的 8 个字节? -
内存转储是否来自与寄存器跟踪相同的程序调用?
-
嗨,我想我解决了:aaz 你的回答帮助了我。我当然在想什么,答案是如此明显。输出不是来自程序的同一次调用:一个来自 gdb 运行,另一个直接来自 bash,所以当然不一样,因为 gdb 在堆栈上使用更多空间,所以它的地址从 bash 调用开始,局部变量较低。我会标记为:问题已解决。谢谢
标签: c++ c linux security debugging