前面两次栈溢出只是让我们学习原理,是最简单、最基本的栈溢出问题,一般的pwn题不会这么简单,溢出一次就可以到位。今天我们就做第一步进阶,正式进入ROP。
就我目前理解的ROP,就是要通过连续多次栈溢出,利用其原有的gadget(可以叫做代码片段),构造一次系统调用,调用execve()函数,就相当于获得了一个shell。首先我们要知道,系统调用的中断号是0x80,而execve的功能号是11,也就是16进制的0xb。所以在进行系统调用(即执行INT 80H这条语句)之前,我们先要构造出调用execve()函数所需要的参数。
首先,需要将EAX寄存器的内容赋值为0xb,因为系统调用的功能号是默认存储到EAX寄存器当中的,而且我们上面说了,execve()函数的功能号是0xb,所以第一步要先给EAX赋值。然后,将EBX寄存器的内容赋值为"bin/sh"字符串所在的地址,就如下面的0x80BE408.
除此之外,还要将ECX和EDX的内容置零。以上就是调用execve()函数所需要的条件,总结起来就是下面几条语句。
mov eax,0xb
mov ebx,["bin/sh"]
mov ecx,0
mov edx,0
int 80
=>execve("bin/sh")
因为代码中基本不可能会出现这样连续的语句ÿ