我正在研究缓冲区溢出(在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
的?你展示的程序是完整的吗? - Carl Norumarray
的地址是 0xbffff078,而不是 0xbffff048 吗?也许strcpy
的后续操作尝试进行一些栈操作,覆盖了 0xbffff070 处的 8 个字节? - aschepler