Assembly ebp值在此函数中如何变化
在主要功能方面:Assembly ebp值在此函数中如何变化,assembly,stack,stack-overflow,Assembly,Stack,Stack Overflow,在主要功能方面: 0x08049230 <+0>: push %ebp 0x08049231 <+1>: mov %esp,%ebp 0x08049233 <+3>: sub $0x28,%esp 0x08049236 <+6>: movl $0xdeadbeef,-0xc(%ebp) 0x0804923d <+13>: call 0x8048ed4 <getbuf> 0
0x08049230 <+0>: push %ebp
0x08049231 <+1>: mov %esp,%ebp
0x08049233 <+3>: sub $0x28,%esp
0x08049236 <+6>: movl $0xdeadbeef,-0xc(%ebp)
0x0804923d <+13>: call 0x8048ed4 <getbuf>
0x08049242 <+18>: mov -0xc(%ebp),%edx
0x08048ed4 <+0>: push %ebp
0x08048ed5 <+1>: mov %esp,%ebp
0x08048ed7 <+3>: sub $0x28,%esp
0x08048eda <+6>: lea -0x14(%ebp),%eax
0x08048edd <+9>: mov %eax,(%esp)
0x08048ee0 <+12>: call 0x8048de4 <Gets>
0x08048ee5 <+17>: mov $0x1,%eax
0x08048eea <+22>: leave
0x08048eeb <+23>: ret
0x08049230:推送%ebp
0x08049231:mov%esp,%ebp
0x08049233:子$0x28,%esp
0x08049236:movl$0xdeadbeef,-0xc(%ebp)
0x0804923d:调用0x8048ed4
0x08049242:mov-0xc(%ebp),%edx
在getbuf函数中:
0x08049230 <+0>: push %ebp
0x08049231 <+1>: mov %esp,%ebp
0x08049233 <+3>: sub $0x28,%esp
0x08049236 <+6>: movl $0xdeadbeef,-0xc(%ebp)
0x0804923d <+13>: call 0x8048ed4 <getbuf>
0x08049242 <+18>: mov -0xc(%ebp),%edx
0x08048ed4 <+0>: push %ebp
0x08048ed5 <+1>: mov %esp,%ebp
0x08048ed7 <+3>: sub $0x28,%esp
0x08048eda <+6>: lea -0x14(%ebp),%eax
0x08048edd <+9>: mov %eax,(%esp)
0x08048ee0 <+12>: call 0x8048de4 <Gets>
0x08048ee5 <+17>: mov $0x1,%eax
0x08048eea <+22>: leave
0x08048eeb <+23>: ret
0x08048ed4:推送%ebp
0x08048ed5:mov%esp,%ebp
0x08048ed7:子$0x28,%esp
0x08048eda:lea-0x14(%ebp),%eax
0x08048edd:mov%eax,(%esp)
0x08048ee0:调用0x8048de4
0x08048ee5:mov$0x1,%eax
0x08048eea:离开
0x08048eeb:ret
基本上,主函数使用%ebp-0xc检查损坏的堆栈
在getbuf函数中,lea-0x14(%ebp),%eax为输入字符串分配20个字节
如果我提供24个字节,$ebp将被覆盖。我不知道为什么getbuf中ebp的更改会影响main函数中的ebp值
我知道$ebp将推到堆栈上。当getbuf返回时,$ebp将从堆栈中弹出。主函数的$ebp是否从getbuf接收$ebp
我也做了一些测试。我的输入字符串是aaaabbccccdddeee,它是24个字节。我在0x08049242设置了一个断点:mov-0xc(%ebp),%edx,我打印$ebp,但它不是eeee的十六进制表示形式。我注意到$ebp中存储的值确实发生了变化。如果输入小于20字节,则值为0xbffff6c8。如果输入为24字节,则其值变为0xb7fd0ac0
有人能解释它是如何变化的吗?main函数中的$ebp是如何知道gebuf函数中$ebp的值的
谢谢寄存器只有一个副本(每个线程)。除了返回地址所需的
esp
之外,函数调用和返回不会更改寄存器。按下并弹出ebp
的关键是为调用者保留它。同样,如果覆盖堆栈上保存的值,则错误的值将弹出回ebp
,并返回给调用者
我的输入字符串是aaaaaabbccccdddeee
,是24个字节
不,那是20个字节,加上一个用于终止零。这仍然会使缓冲区溢出,并应导致ebp
的低位字节归零。请注意,如果使用长度为24的字符串,例如aaaaaabbccccdddeeeefff
,它将覆盖ebp
到ffff
,后者是0x666666
,但终止的零将覆盖返回地址的低字节,因此您甚至不会返回到正确的位置。可以使用长度为23的字符串,例如aaaabbbbccccdddeeeefff
,在这种情况下,ebp
应该是0x0066666
:
Starting program: /tmp/a.out
aaaabbbbccccddddeeeefff
Program received signal SIGSEGV, Segmentation fault.
8 mov -0xc(%ebp),%edx
(gdb) p/a $ebp
$6 = 0x666666
在堆栈帧上读取,例如