我一直在阅读this article关于“面向返回的编程”的问题,并且对带有“调用参数”的部分有疑问
我了解的是,我们需要使用正确格式的堆栈。参数,然后返回我们不关心的地址。他们以这种方式设置堆栈:
| 0x8048580 <not_used> |
| 0x43434343 <fake return address> |
| 0x8048360 <address of system> |
| 0x42424242 <fake old %ebp> |
| 0x41414141 ... |
| ... (0x6c bytes of 'A's) |
| ... 0x41414141 |
地址0x8048360
是损坏的函数完成后将跳转到的地址,而地址0x8048580
是自变量。
我不明白的是,我们如何拥有假的EBP地址。我的理解是,从函数返回之前,会弹出堆栈上的EBP地址,然后使用EBP来访问参数和局部变量。如果我们在堆栈上放置了伪地址,system
函数是否会使用该伪EBP地址访问其参数而没有成功?
“系统”功能是否会使用该伪造的EBP地址访问其参数而没有成功?如果我们在堆栈上放置伪地址,那么“ system”函数不会使用该伪EBP地址访问其参数而没有成功吗?
没有如果您覆盖EBP,然后从函数真正返回到调用者,则会发生这种情况。由于您还将覆盖寄信人地址,因此您实际上不会返回到呼叫者,而是输入system
。与任何其他功能一样,system
要做的第一件事是:
0x08048360 <+0>: push %ebp
0x08048361 <+1>: mov %esp,%ebp ; <== now %ebp is valid
这就是您所引用的文章说“假EBP”的原因,因为您并不真正在乎其价值。只要您的函数没有真正返回给调用者,就可以了,您的ROP链将继续存在而不会出现问题,因为您跳入的每个函数都会像上面的函数一样有一个序言。