Detour Hook COM成员函数present和Hook 类成员函数

原创 2012年09月06日 15:06:36

void * pPresent=NULL;//IDirect3DDevice9::Present函数地址指针 

pPresent=(void*)*(DWORD*)(*(DWORD*)Device+0x44);//IDirect3DDevice9* Device

	DetourTransactionBegin();
	DetourUpdateThread(GetCurrentThread());
	DetourAttach((PVOID *)&pPresent, New_Present);
	DWORD nErr = DetourTransactionCommit();

HRESULT __stdcall New_Present( 
							 LPDIRECT3DDEVICE9 pDxdevice,	//类的this指针 
							 CONST RECT * pSourceRect,		//此参数请参考dx sdk 
							 CONST RECT * pDestRect,		//同上 
							 HWND hDestWindowOverride,		//同上 
							 CONST RGNDATA * pDirtyRegion	//同上 

							 ) 
{ 
	__asm pushad 
	static float lastTime = (float)timeGetTime(); 
	float currTime  = (float)timeGetTime();
	float timeDelta = (currTime - lastTime)*0.001f;
	Device->BeginScene();
	Device->Clear(0, NULL, D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,0), 1.0f, 0);
	fps.CalcFPS(timeDelta);
	fps.Show();
	Device->EndScene();
	__asm popad 
	__asm
	{	
		push pDirtyRegion
		push hDestWindowOverride
		push pDestRect
		push pSourceRect
		push pDxdevice
		call pPresent
	}

	lastTime = currTime;
}

 

另一种方式,采用__declspec(naked)方式,注意的是这种方式不需要编译器添加任何汇编代码,在标明naked的函数中是不可以使用任何赋值,所以把它单独提出来:还要注意子函数New_Present_Sub最好用__stdcall,这样不用考虑堆栈平衡

void __stdcall New_Present_Sub( LPDIRECT3DDEVICE9 pDxdevice)
{
	if (pDxdevice)
	{
		static BOOL bInitFps = FALSE;
		if (!bInitFps)
		{
			bInitFps = g_fps.Create(pDxdevice);
			MyOutputDebugString("tpfps-[New_Present] g_fps.Create");
		}

		if (bInitFps)
		{
			static DWORD lastTime = timeGetTime(); 
			DWORD currTime  = timeGetTime();
			DWORD timeDelta = (currTime - lastTime);
			pDxdevice->BeginScene();
			g_fps.CalcFPS(timeDelta);//传入的是毫秒
			switch (g_nOpe)
			{
			case SHOW_FPS:
				{
					g_fps.Show();
				}
				break;

			case RECODE_FPS:
				{	
					g_fps.RecordShow(pDxdevice, g_bAutoRecord, g_nAutoRecordTime);
					if (g_fps.bAutoRecordExit())
					{
						MyOutputDebugString("[New_Present]bAutoRecordExit");
						g_nOpe = UNRECODE_FPS;
					}
				}
				break;

			case UNRECODE_FPS:
				{
					g_fps.EndRecord(pDxdevice);
					g_nOpe = SHOW_FPS;
				}
				break;

			default:
				break;
			}

			pDxdevice->EndScene();
			lastTime = currTime;

		}
	}
}
__declspec(naked) HRESULT __stdcall New_Present( 
							  LPDIRECT3DDEVICE9 pDxdevice,	//类的this指针 
							  CONST RECT * pSourceRect,		//此参数请参考dx sdk 
							  CONST RECT * pDestRect,		//同上 
							  HWND hDestWindowOverride,		//同上 
							  CONST RGNDATA * pDirtyRegion	//同上 
							  ) 
{ 
	__asm// 必不可少的,把ebp代码去掉或pushad去掉,都会程序OVER
	{
		push ebp
	    mov ebp, esp
		pushad
		pushfd
	}

	__asm
	{	
	    mov esi, pDxdevice
		push esi
		mov eax, New_Present_Sub
		call eax
	}
	__asm
	{
		popfd
		popad
		mov esp, ebp
		pop ebp
		jmp g_pPresent
	}
}


 

 

 

Hook类成员函数:

术语说明:
原函数:被hook的target
hook函数:指自己写的函数,也即让原函数jmp到该函数
原因分析:
用detours hook类成员函数,因为成员函数会有一个this指针,如果在hook函数中调用原函数,没有传入this指针,那么原函数的调用将会出错。
解决方法是:
1. 首先在ollydbg中找到这个this指针。其实也就是那个类的对象地址,一般来说,在ollydbg中调用原函数时,也即在call原函数之前,总会有一条指令mov ecx,xxx或者lea ecx,xxx,那个ecx就是我们要找的this指针!
2. 在hook函数调用原函数时使用内联汇编代码调用,push所有的参数之后,然后初始化ecx为this指针的值!然后在call原函数,这样call原函数就不会出现崩溃。

需要注意的地方:
1. 注意原函数是否能自动平衡堆栈,如不行,则需要在hook函数中自己手动平衡堆栈
2. hook函数返回时,必须是手动编写汇编返回(ret),不要让系统帮忙返回!在带有参数的hook例子中,系统帮忙放回必定出错!
3. ret后面的值与传入hook函数的参数有关,一般来说,该值=4*参数个数

或者如上面:代替的函数原型第一个参数加this即可。

Hook IDirect3DDevice9::Present

其实很简单.主要针对D3D游戏.主要思路:Hook IDirect3DDevice9::Present,在其中加入sleep函数.让系统获得更多的CPU时间片. 试验游戏:剑网三(以D3D9为例...
  • hgy413
  • hgy413
  • 2012年09月05日 19:54
  • 7314

C++成员函数的HOOK

今天HOOK D3D9中的SetMaterial发现出现堆栈失衡现象,后来研究发现是因为,对于如下的调用:HRESULT _stdcall SetMaterial(D3DMATERIAL9 *pMat...
  • winsunxu
  • winsunxu
  • 2011年03月22日 20:05
  • 1721

Windows Hook经验总结之四:COM组件Hook原理及实践

前面已经介绍过API的hook方法及具体实践,本文则讲述COM组件的Hook方式。COM组件可简单理解为一个二进制可执行程序或DLL,内部包含一系列的接口和函数。Hook COM本质上也是进行函数地址...
  • u011559599
  • u011559599
  • 2016年11月17日 14:31
  • 1230

简明的Detours Hook教程

tag: Hook, Detours,Windows,CreateRemoteThread,MessageBox 前言     项目开发中需要跟踪其它程序的API调用情况。但厂商又无源码提供,故只...
  • allenq
  • allenq
  • 2012年12月24日 14:48
  • 5963

COM接口Hook的用法

// Dsound.h 中的定义 HRESULT CreateSoundBuffer(   LPCDSBUFFERDESC pcDSBufferDesc,   LPDIRECTSOUNDBUFF...
  • wxl1986622
  • wxl1986622
  • 2015年03月11日 14:51
  • 1451

D3D9 hook Present优化CPU

D3D9 hook Present优化CPU 具体实现步骤: 1.HOOK Direct3DCreate9来获得类型为LPDIRECT3D9的Direct3D对象的接口指针,它有一个成员函数为 I...
  • hewei0241
  • hewei0241
  • 2014年08月04日 20:27
  • 4554

C++ Hook(钩子)编程,通过内联汇编,使类成员函数代替全局函数(静态函数)

编程语言:C/C++ 编译环境:Visual Studio 2008 核心方法::通过内联汇编,构造类对象独享的函数(委托),完成了类成员函数到普通全局函数的转化,并在Windows Hook(钩...
  • realzyc8847
  • realzyc8847
  • 2011年03月07日 15:54
  • 1460

浅谈inline HOOk之ring0下的进程保护

浅谈inline HOOk之ring0下的进程保护 在上一篇中说了一下ring3下简单的inline HOOK,写函数开头的方法还是比较通用的,而Call钩子虽然有隐蔽的优点,却需要...
  • linuxheik
  • linuxheik
  • 2012年05月09日 12:15
  • 1043

Windows平台Ring3下DLL注入(HOOK)方法整理汇总

1.dll劫持,粗略整理了下,可以劫持的dll有(持续更新): lpk.dll、usp10.dll、msimg32.dll、midimap.dll、ksuser.dll、comres.dll...
  • asmcvc
  • asmcvc
  • 2016年03月21日 13:08
  • 1566

D3D游戏降帧的动态创建D3D设备以及ShellCode HOOK玩法

欢迎转载,转载请注明出处:http://blog.csdn.net/gnorth/article/details/9327971 说白了,也就是HOOK掉Present,这种代码,其实百度上...
  • hewei0241
  • hewei0241
  • 2014年08月05日 11:21
  • 3621
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Detour Hook COM成员函数present和Hook 类成员函数
举报原因:
原因补充:

(最多只允许输入30个字)