我创建了一个示例中间函数钩子。但是当我取消引用一个指针时遇到了崩溃。
让我说我挂到中间
公开:virtual long __stdcall CD3DBase:DrawIndexedPrimitive(enum _D3DPRIMITIVETYPE, int, unsigned int, unsigned int, unsigned int, unsigned int)
位于d3d9.dll中。以下是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
钩子从.text:10029765 push 0FFFFFFFFh
开始
我只是改变它来跳转到我的功能。跳转语句像往常一样只有5个字节,0xE9(JMP) [Offset]
在我的函数中,我尝试获取类指针,因为我想用它来调用calss中的其他函数。下面是我的代码
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
}
结果是在调用原始函数时遇到MyDipFunc
但是当我执行g_deviceInterface->GetStreamSource(....)
时它崩溃了。
注意:我知道类指针将通过被调用者CD3DBase:DrawIndexedPrimitive
的第一个参数,即[EBP+8]
。
如果有人做错了,有人可以提出建议吗?
谢谢,
已编辑:有关我的问题的更清晰
我的假设是g_deviceInterface
可能没有正确设置,因为类指针可能不在[EBP+0x08]
中。我不知道如何获得应该存储在由CD3DBase:DrawIndexedPrimitive
的调用者管理的堆栈中的某个位置的类指针。
已编辑2:我的完整挂钩功能
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
}