这是显示我的问题的最简单示例。一切都在禁用 DEP 的 WinXp sp3 中。
char f() {
// shellcode starting with some NOPs,
char shellcode[400]= {
0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
0x66, ... some basic shellcode here ... 0x30.
0xCC
};
// Overwriting Return address in stack to return to NOPs in shellcode above
b[404]=0xf0;
b[405]=0xfb;
b[406]=0x12;
b[407]=0x00;
}
这以失败告终:
(920.e7c): Illegal instruction - code c000001d (!!! second chance !!!)
eax=7c801d7b ebx=7c80262c ecx=7c801bfa edx=00060002 esi=00000000 edi=7c802654
eip=0012fc15 esp=0012ff08 ebp=7e410000 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
0012fc15 d9907ca5e490 fst dword ptr [eax-6F1B5A84h] ds:0023:0d64c2f7=????????
但是如果我直接执行shellcode,它的工作原理是:
char f() {
// shellcode starting with some NOPs,
char shellcode[400]= {
0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
0x66, ... some basic shellcode here ... 0x30.
0xCC
};
void *exec = shellcode;
((void(*)())exec)();
}
这将正常工作。
我确实跟踪了上述两种情况下的执行情况。并且在这两种情况下,EIP 确实成功登陆 NOPs 区域并继续执行。但我不知道为什么第一个案例失败了。
一种猜测是,在第一种情况下,当 f() 返回到 0x0012fbf0 时,堆栈帧外区域中的 shellcode(即,此时 ESP 位于 SHELLCODE 区域下方)。
任何人都可以知道为什么第一个案例失败了?