如何从中间函数钩子获取类指针 [英] how to get class pointer from mid function hook

查看:99
本文介绍了如何从中间函数钩子获取类指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个示例中间函数钩子。但是当我取消引用一个指针时遇到了崩溃。假设我挂钩到public的中间: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,大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(裸)void WINAPI MyDipFunc()

{



//这里我得到了这个指针。据我所知,这个指针在EBP + 0x08

__asm mov EAX,DWORD PTR SS:[EBP + 0x08]

__asm mov DWORD PTR DS:[g_deviceInterface], EAX



//替换代码。

__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(裸)void WINAPI MyDipFunc()

{



//这里我得到这个指针。据我所知,这个指针在EBP + 0x08

__asm mov EAX,DWORD PTR SS:[EBP + 0x08]

__asm mov DWORD PTR DS:[g_deviceInterface], EAX



//替换代码。

__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 )//在这一行崩溃

{

if(StreamData!= NULL)

StreamData-> Release();

}

}



__asm jmp [DIPJmpBack] //跳回来电, DIPJmpBack包含要跳转的地址

}

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
}

推荐答案

这篇关于如何从中间函数钩子获取类指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆