I created a sample midfunction hook. But struck at crashing when I dereference a pointer. Let say I hook to the middle of public: virtual long __stdcall CD3DBase:DrawIndexedPrimitive(enum _D3DPRIMITIVETYPE, int, unsigned int, unsigned int, unsigned int, unsigned int)
which is located in d3d9.dll. Below is an start assembly code of CD3DBase:DrawIndexedPrimitive:
.text:10029760 mov edi, edi
.text:10029762 push ebp
.text:10029763 mov ebp, esp
.text:10029765 push 0FFFFFFFFh
.text:10029767 push offset loc_1014A0AC
.text:1002976C mov eax, large fs:0
.text:10029772 push eax
.text:10029773 sub esp, 28h
.text:10029776 push ebx
The hook start at .text:10029765 push 0FFFFFFFFh I just change it to jump to my function. The jump statement is only 5 byte as usual, 0xE9(JMP) [Offset] In my function I try to get class pointer because I want to use it to call other function in the calss. Below is my code to get it
LPDIRECT3DDEVICE9 g_deviceInterface;
__declspec(naked) void WINAPI MyDipFunc()
{
//Here I get this pointer. As I know the this pointer is in EBP + 0x08
__asm mov EAX, DWORD PTR SS:[EBP + 0x08]
__asm mov DWORD PTR DS:[g_deviceInterface], EAX
//Replace code.
__asm PUSH 0xFFFFFFFF //2
__asm PUSH 0x67F3A0AC //7
__asm MOV EAX,DWORD PTR FS:[0] //12
__asm PUSH EAX //13
__asm SUB ESP,0x28 //16
}
The result is that MyDipFunc is hit when the original function is called but when I execute g_deviceInterface->GetStreamSource(....) it crash.
Note: I know that class pointer will be pass through the first argument of callee, CD3DBase:DrawIndexedPrimitive, which is [EBP+8].
Can someone advice if it do something wrong?
Thanks,
Edited: For more clear on my problem
My assumption is that g_deviceInterface may not be set properly as the class pointer may not be in [EBP+0x08]. I don't how can I get the class pointer which should be store in some place on the stack which is managed by CD3DBase:DrawIndexedPrimitive's caller.
Edited2: My full hook function
LPDIRECT3DDEVICE9 g_deviceInterface = NULL;
__declspec(naked) void WINAPI MyDipFunc()
{
//Here I get this pointer. As I know the this pointer is in EBP + 0x08
__asm mov EAX, DWORD PTR SS:[EBP + 0x08]
__asm mov DWORD PTR DS:[g_deviceInterface], EAX
//Replace code.
__asm PUSH 0xFFFFFFFF //2
__asm PUSH 0x67F3A0AC //7
__asm MOV EAX,DWORD PTR FS:[0] //12
__asm PUSH EAX //13
__asm SUB ESP,0x28 //16
if(g_deviceInterface != NULL)
{
LPDIRECT3DVERTEXBUFFER9 StreamData;
UINT OffsetInBytes;
UINT Stride;
if(g_deviceInterface->GetStreamSource(0,&StreamData,&OffsetInBytes,&Stride) == D3D_OK) //Crash at this line
{
if(StreamData != NULL)
StreamData->Release();
}
}
__asm jmp [DIPJmpBack] //Jump back to caller, DIPJmpBack contain address to jump
}