我这里测试没有问题,你按照我的方法来一遍看看。
首先,到你od安装目录下的udd目录,把所有文件删除,清除od的cache。
第二,创建simple_overflow.c,内容如下:
#include <stdio.h>
#include <string.h>
#pragma comment(linker, "/ENTRY:main")
char largebuff[] = "1234512345123456====ABCD";
int main(void)
{
char smallbuff[16] = {0};
strcpy(smallbuff, largebuff);
return 0;
}
第三,编译cl simple_overflow.c
第四,od加载simple_overflow.exe,看到如下反汇编代码:
00401000 >/$ 55 push ebp
00401001 |. 8BEC mov ebp, esp
00401003 |. 83EC 10 sub esp, 10
00401006 |. C645 F0 00 mov byte ptr [ebp-10], 0
0040100A |. 33C0 xor eax, eax
0040100C |. 8945 F1 mov [ebp-F], eax
0040100F |. 8945 F5 mov [ebp-B], eax
00401012 |. 8945 F9 mov [ebp-7], eax
00401015 |. 66:8945 FD mov [ebp-3], ax
00401019 |. 8845 FF mov [ebp-1], al
0040101C |. 68 00204000 push
00402000 ; ASCII "1234512345123456====ABCD"
00401021 |. 8D4D F0 lea ecx, [ebp-10]
00401024 |. 51 push ecx
00401025 |. E8 16000000 call 00401040
0040102A |. 83C4 08 add esp, 8
0040102D |. 33C0 xor eax, eax
0040102F |. 8BE5 mov esp, ebp
00401031 |. 5D pop ebp
00401032 \. C3 retn
f8单步执行,一直走到call那行打住,观察下堆栈窗口:
0012FFA8 0012FFB0
0012FFAC 00402000 ASCII "1234512345123456====ABCD"
这里是strcpy函数的两个参数,下面这个是largebuff,上面那个则是smallbuff,再仔细观察下它0012FFB0,发现它是个指
针,指向栈内存,观察堆栈窗口:
0012FFB0 00000000
0012FFB4 00000000
0012FFB8 00000000
0012FFBC 00000000
0012FFC0 0012FFF0
0012FFC4 7C816FD7 返回到 kernel32.7C816FD7
发现0012FFB0距离0012FFC4一共6*4=24个字节,也就是说largebuff的内容覆盖过来的话,ABCD正好回覆盖
0012FFC4的那四个字节,你也看到了,这个地方是一个返回地址。继续单步到ret打住,观察堆栈窗口:
0012FFC4 44434241
这里栈顶是44434241,不就是DCBA么,f7单步执行ret,那么下一句的ret指令就会把栈顶的44434241作为eip继续执行程序,于
是成功控制eip,这时候代码窗口啥都没有了,因为44434241地址未影射的内存。观察一下寄存器窗口会发现
EIP 44434241
到此,这个溢出成功。