gdb 显示 EBP 包含某个地址以外的值(这是它应该包含的内容)。这怎么可能?

逆向工程 二元分析 数据库
2021-06-17 16:52:29

我对 RE 和二进制开发相当陌生,我已经学习了二进制开发的基本汇编指令,并且我正在做Protostar 练习 (stack0),其中我必须简单地溢出buffer变量。主要功能的拆解是:-

(gdb) disas main
Dump of assembler code for function main:
0x080483f4 <main+0>:    push   ebp
0x080483f5 <main+1>:    mov    ebp,esp
0x080483f7 <main+3>:    and    esp,0xfffffff0
0x080483fa <main+6>:    sub    esp,0x60
0x080483fd <main+9>:    mov    DWORD PTR [esp+0x5c],0x0
0x08048405 <main+17>:   lea    eax,[esp+0x1c]
0x08048409 <main+21>:   mov    DWORD PTR [esp],eax
0x0804840c <main+24>:   call   0x804830c <gets@plt>
0x08048411 <main+29>:   mov    eax,DWORD PTR [esp+0x5c]
0x08048415 <main+33>:   test   eax,eax
0x08048417 <main+35>:   je     0x8048427 <main+51>
0x08048419 <main+37>:   mov    DWORD PTR [esp],0x8048500
0x08048420 <main+44>:   call   0x804832c <puts@plt>
0x08048425 <main+49>:   jmp    0x8048433 <main+63>
0x08048427 <main+51>:   mov    DWORD PTR [esp],0x8048529
0x0804842e <main+58>:   call   0x804832c <puts@plt>
0x08048433 <main+63>:   leave  
0x08048434 <main+64>:   ret    
End of assembler dump.

我在ret指令上设置了一个断点并运行程序,但是当我检查 中的堆栈时gdb,它显示了这个输出(90 A 后溢出):

(gdb) info registers
eax            0x29 41
ecx            0xb7fd84c0   -1208122176
edx            0xb7fd9340   -1208118464
ebx            0xb7fd7ff4   -1208123404
esp            0xbffff7bc   0xbffff7bc
ebp            0x41414141   0x41414141
esi            0x0  0
edi            0x0  0
eip            0x8048434    0x8048434 <main+64>
eflags         0x200246 [ PF ZF IF ID ]
cs             0x73 115
ss             0x7b 123
ds             0x7b 123
es             0x7b 123
fs             0x0  0
gs             0x33 51

看着ebp我真的很想知道发生了什么导致ebp有价值的事情0x41414141我的理解是当leave执行 istruction堆栈帧被销毁,x/x $esp is 0x41414141这是有道理的,x/x $ebp is Cannot access memory at address 0x41414141 那么值如何ebp更改为0x41414141

PS:我已经解决了那个练习,但是在检查堆栈时我没有得到如何ebp改变并且可以随意编辑问题标签,因为我不确定什么标签是合适的。

2个回答

leave指令等效于:

mov esp, ebp
pop ebp

第二条指令弹出堆栈顶部的值并将其存储在ebp. 在基于堆栈的缓冲区溢出的情况下,您的堆栈布局如下所示:

<--- low addresses           high addresses --->
[ buffer being overflowed ][saved EBP][RET ADDR]
                           ^

leave被执行时,mov esp, ebp指令第一还原esp在上述图中的标记的位置,以点,然后关闭弹出堆栈成值ebp因此,如果您使用“AAAA...”溢出缓冲区,则保存ebp的地址和返回地址都将设置为0x41414141.

对于 CPU,ebp(甚至esp大部分时间)与eax,ebx和其他寄存器并没有真正的区别它们可以包含任何数据,不一定是有效地址。你只有问题(故障/异常),如果你真的尝试执行使用这些寄存器的地址(直接或间接)的指令,或者,在以下情况下ESP一个中断发生