zoukankan      html  css  js  c++  java
  • Detour Hook COM成员函数present和Hook 类成员函数


    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即可。

  • 相关阅读:
    LeetCode_1.Two Sum
    F#周报2018年第48期
    使用Kdenlive为视频加入马赛克特效
    网络安全从入门到精通(第一章)前言篇
    hdu 5023 线段树染色问题
    poj 2528 线段树离散化+染色
    字符Hash初步
    经典二分:秦腾与教学评估
    国王游戏
    Trie:hdu 4825、1251、1247、Poj 3764
  • 原文地址:https://www.cnblogs.com/hgy413/p/3693462.html
Copyright © 2011-2022 走看看