我在前一个堆栈帧中有一个返回值,它指向后续堆栈帧中的缓冲区。如何让放在缓冲区中的机器指令执行?
这有可能吗?根据我对堆栈的理解,这是无稽之谈。当然,因为堆栈是后进先出的结构。换句话说,一旦PC到达返回地址,缓冲器就已经被弹出。
有什么想法吗?
<test>函数(如下所示)调用<getbuf>函数(如下所示):
08048c53 <test>:
8048c53: 55 push %ebp
8048c54: 89 e5 mov %esp,%ebp
8048c56: 83 ec 28 sub $0x28,%esp
8048c59: e8 63 04 00 00 call 80490c1 <uniqueval>
8048c5e: 89 45 f0 mov %eax,-0x10(%ebp)
8048c61: e8 5f 00 00 00 call 8048cc5 <getbuf>
8048c66: 89 45 f4 mov %eax,-0xc(%ebp)
8048c69: e8 53 04 00 00 call 80490c1 <uniqueval>
8048c6e: 8b 55 f0 mov -0x10(%ebp),%edx
8048c71: 39 d0 cmp %edx,%eax
8048c73: 74 0e je 8048c83 <test+0x30>
8048c75: c7 04 24 f0 a3 04 08 movl $0x804a3f0,(%esp)
8048c7c: e8 9f fc ff ff call 8048920 <puts@plt>
8048c81: eb 40 jmp 8048cc3 <test+0x70>
8048c83: 8b 55 f4 mov -0xc(%ebp),%edx
8048c86: a1 20 e1 04 08 mov 0x804e120,%eax
8048c8b: 39 c2 cmp %eax,%edx
8048c8d: 75 21 jne 8048cb0 <test+0x5d>
8048c8f: 8b 45 f4 mov -0xc(%ebp),%eax
8048c92: 89 44 24 04 mov %eax,0x4(%esp)
8048c96: c7 04 24 19 a4 04 08 movl $0x804a419,(%esp)
8048c9d: e8 ae fb ff ff call 8048850 <printf@plt>
8048ca2: c7 04 24 03 00 00 00 movl $0x3,(%esp)
8048ca9: e8 a0 07 00 00 call 804944e <validate>
8048cae: eb 13 jmp 8048cc3 <test+0x70>
8048cb0: 8b 45 f4 mov -0xc(%ebp),%eax
8048cb3: 89 44 24 04 mov %eax,0x4(%esp)
8048cb7: c7 04 24 36 a4 04 08 movl $0x804a436,(%esp)
8048cbe: e8 8d fb ff ff call 8048850 <printf@plt>
8048cc3: c9 leave
8048cc4: c3 ret
08048cc5 <getbuf>:
8048cc5: 55 push %ebp
8048cc6: 89 e5 mov %esp,%ebp
8048cc8: 83 ec 38 sub $0x38,%esp
8048ccb: 8d 45 d8 lea -0x28(%ebp),%eax
8048cce: 89 04 24 mov %eax,(%esp)
8048cd1: e8 32 01 00 00 call 8048e08 <Gets>
8048cd6: b8 01 00 00 00 mov $0x1,%eax
8048cdb: c9 leave
8048cdc: c3 ret发布于 2015-10-20 21:24:20
这有可能吗?
如果Data Execution Prevention正在运行,则不会。
缓冲区将已被弹出
POP/RET不会更改堆栈上的任何数据。它只更改堆栈指针SP,而数据保留在被PUSH或CALL替换之前的位置。
这就是为什么虫子喜欢
int* foo() {
int i = 123;
return &i;
}在错误显示之前,可能会工作一段时间。在数据在堆栈上的位置被实际覆盖之前,它仍然在那里存在一段不确定的时间。
发布于 2015-10-20 21:39:52
是的,这是可能的预数据执行预防。
一段代码会填充比预期更多的缓冲区,这些缓冲区会漂移到堆栈上。在这一点上,您有两种可用的机制。
1) wikipedia: return into libc
2) wikipedia: stack buffer overflow
返回libc
在这里,您使用一组对函数(通常是程序中预先存在的函数)的调用来覆盖堆栈。这允许你构建更多的代码,并执行你想要的东西。
堆栈缓冲区溢出
此覆盖会修改保存的帧指针或堆栈上的返回地址。这些被更改为函数在堆栈上的预期位置。这在某种程度上是偶然的,所以通常会添加一个缓冲区(nop-slide)来提高可靠性。
wikipedia : address space layout randomization在程序之外增加了这方面的难度,因为您无法预测重要的函数和数据在哪里。
数据执行和地址空间布局随机化有助于缓解这些问题,因为它们通常不是所需的。我强烈建议避免这种形式的动态编程,因为它很容易被一些恶意实体利用。
https://stackoverflow.com/questions/33237786
复制相似问题