基本上我正在利用的功能是这样的:
int getbufn()
{
char buf[512];
Gets(buf);
return 1;
}
当我运行主程序时,该函数执行 5 次,每次 buf 的位置发生变化,%ebp 的位置也发生变化。我应该做的是将一个特定的十六进制值,比如说 0xFFFFFFFF,放入一个变量中,并且主程序每次都会检查该变量是否存在。如果是,它会再次执行,直到所有 5 次都完成并且程序安静地退出。
我遇到的问题是,在检查十六进制值之前,检查另一个恒定值,比如说 0x12345678。如果我损坏了 0x12345678 并且它不存在,程序就会在我身上爆炸。
我发现 0x12345678 存储在 -0x10(%ebp) 中,所以我知道它是基于 %ebp 的,而且我每次都知道 %ebp 的地址,但我只能让漏洞利用第一次工作。我通过基本上 nopsled-ing 496 字节和字节格式的机器代码来做到这一点:
mov 0xFFFFFFFF, %eax
movl address old ebp, %ebp
push correct return adress in function main
ret
最终是 5 个字和一个用于返回 long 的字节,我用 0x313131 填充以使其长 6 个字。在这一点上,我的漏洞利用字符串是 520 字节长,这正是缓冲区低于 %ebp 的长度,所以我添加了旧 ebp 的地址和我的 nopsled 内某处的地址,覆盖了 %ebp 的当前值以及返回getbufn 的地址。
问题是当程序第二次执行时,%ebp 位于比其先前地址低 0x10 的地址中,因此我的不破坏 %ebp 的方法不起作用,并且 main 检测到 0x12345678 不在 -0x10(%ebp) 处。如何清除 %ebp?