Detours Hook普通类成员函数

zhm_joy 2014-12-02 09:43:36
有如下类:

//RealRun.h
CRealRun
{
public:
CRealRun();
int Run(int cmd);
};

//RealRun.cpp
CRealRun::CRealRun()
{

}
int CRealRun::Run(int cmd)
{
return cmd;
}


将上述类封装到realrun.dll中,现在希望通过Detours去Hook CRealRun类的Run函数,可以怎么实现呢?

PS:GetProcAddress函数能获取到api 函数的地址,但是类的非static方法怎么样可以实现啊?
...全文
739 7 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhm_joy 2014-12-11
  • 打赏
  • 举报
回复
引用 5 楼 zhm_joy 的回复:
依据微软提供的detours samples,自己写个了,报下面错,是为啥啊 >e:\projects\avsdk_proj\trunk\pc\avhooktools\src\detourshook.cpp(27): error C2440: 'initializing' : cannot convert from 'void (__thiscall CSessionLogic::* )(uint64,tagFrameData,int8)' to 'void (__thiscall CDetourSessionLogic::* )(uint64,tagFrameData,int8)' 1> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast 1>e:\projects\avsdk_proj\trunk\pc\avhooktools\src\detourshook.cpp(38): error C2440: 'type cast' : cannot convert from 'boolean (__thiscall CSessionLogic::* )(IAVRoom *,uint8 *,uint16)' to 'boolean (__thiscall CDetourSessionLogic::* )(IAVRoom *,uint8 *,uint16)' 1> Pointers to members have different representations; cannot cast between them
这个错在vs2013出现,在vs2010上不报错。
zhm_joy 2014-12-03
  • 打赏
  • 举报
回复
引用 4 楼 Saleayas 的回复:
首先这个类的定义必须是 class __declspec( dllexport ) CRealRun { }; 这样的类才可以被 dll 导出,如果提供 dll 的人没有这样导出,不要说 Detour,甚至于简单的使用都是不可以的。 导出之后,所有的成员函数,包括静态函数,虚函数表,都是可以导出的。 普通成员函数的签名和普通函数有两个区别,第一是 this 参数,该参数作为第一个参数。其次是缺省的呼叫方式为 __thiscall,而普通的函数缺省呼叫方式为 __cdecl 。如果有主动使用呼叫方式,那么以此为准。 至于函数名字,你可以看看 Microsoft 的碾平法则。或者使用 工具查看导出名字。 你可以直接使用这个名字,以普通函数方式来使用。 比如 你的 int Run(int cmd); 成员函数。可以看作是 int __thiscall ?Run@CRealRun@@AAEHH@Z(CRealRun *this, int cmd); 其中 ?Run@CRealRun@@AAEHH@Z 就是 Run 成员函数的碾平。
依据微软提供的detours samples,自己写个了,报下面错,是为啥啊 >e:\projects\avsdk_proj\trunk\pc\avhooktools\src\detourshook.cpp(27): error C2440: 'initializing' : cannot convert from 'void (__thiscall CSessionLogic::* )(uint64,tagFrameData,int8)' to 'void (__thiscall CDetourSessionLogic::* )(uint64,tagFrameData,int8)' 1> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast 1>e:\projects\avsdk_proj\trunk\pc\avhooktools\src\detourshook.cpp(38): error C2440: 'type cast' : cannot convert from 'boolean (__thiscall CSessionLogic::* )(IAVRoom *,uint8 *,uint16)' to 'boolean (__thiscall CDetourSessionLogic::* )(IAVRoom *,uint8 *,uint16)' 1> Pointers to members have different representations; cannot cast between them
fly_dragon_fly 2014-12-02
  • 打赏
  • 举报
回复
这个类需要导出,这样detour就可以通过导出表找到
Saleayas 2014-12-02
  • 打赏
  • 举报
回复
首先这个类的定义必须是 class __declspec( dllexport ) CRealRun { }; 这样的类才可以被 dll 导出,如果提供 dll 的人没有这样导出,不要说 Detour,甚至于简单的使用都是不可以的。 导出之后,所有的成员函数,包括静态函数,虚函数表,都是可以导出的。 普通成员函数的签名和普通函数有两个区别,第一是 this 参数,该参数作为第一个参数。其次是缺省的呼叫方式为 __thiscall,而普通的函数缺省呼叫方式为 __cdecl 。如果有主动使用呼叫方式,那么以此为准。 至于函数名字,你可以看看 Microsoft 的碾平法则。或者使用 工具查看导出名字。 你可以直接使用这个名字,以普通函数方式来使用。 比如 你的 int Run(int cmd); 成员函数。可以看作是 int __thiscall ?Run@CRealRun@@AAEHH@Z(CRealRun *this, int cmd); 其中 ?Run@CRealRun@@AAEHH@Z 就是 Run 成员函数的碾平。
zhm_joy 2014-12-02
  • 打赏
  • 举报
回复
引用 2 楼 zhm_joy 的回复:
[quote=引用 1 楼 fly_dragon_fly 的回复:] 这个类需要导出,这样detour就可以通过导出表找到
首先这个类我动不了,只能这样;后来我去看了detours samples的member.cpp,但是运行会报:

//dllmain.cpp
class CDetour /* add ": public CRealRun" to enable access to member variables... */
{
public:
	int Mine_Target(int cmd)
	static int(CDetour::* Real_Target)(int cmd);

	// Class shouldn't have any member variables or virtual functions.
};

int CDetour::Mine_Target(int cmd)
{
	printf("  CDetour::Mine_Target! (this:%p)\n", this);
	(this->*Real_Target)();
}

int (CDetour::* CDetour::Real_Target)(int cmd) = (int (CDetour::*)(int cmd))&CRealRun::Run;


////////
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
					 )
{
	if (DLL_PROCESS_ATTACH == ul_reason_for_call)
	{
		MessageBox(NULL, _T("DLL已从目标进程。"), _T("信息"), MB_ICONINFORMATION);
		DetourTransactionBegin();
		DetourUpdateThread(GetCurrentThread());
		//DetourAttach(&(PVOID&)CDataHook::RealRun, DetourRunapi);
		DetourTransactionCommit();
	}
	else if (DLL_PROCESS_DETACH == ul_reason_for_call)
	{
		MessageBox(NULL, _T("DLL已从目标进程卸载。"), _T("信息"), MB_ICONINFORMATION);
		DetourTransactionBegin();
		DetourUpdateThread(GetCurrentThread());
		DetourDetach(&(PVOID&)SysMessageBox, HookMessageBox);
	DetourAttach(&(PVOID&)CDetour::Real_Target,
		(PVOID)(&(PVOID&)CDetour::Mine_Target));
		DetourTransactionCommit();
	}
	return TRUE;
}

[/quote] 囧,上面的还没写完就莫名其妙的被提交了。以下面的为准。 首先这个类我动不了,只能这样;后来我去看了detours samples的member.cpp,但是运行会报:1>e:\projects\classdtours\classdtours\classdtours.cpp(109): error C2440: 'type cast' : cannot convert from 'void (__thiscall CDetour::* )(void)' to 'PVOID &' 1> Reason: cannot convert from 'overloaded-function' to 'PVOID *' 1> There is no context in which this conversion is possible 1>e:\projects\classdtours\classdtours\classdtours.cpp(109): error C2660: 'DetourAttach' : function does not take 1 arguments

//classdtours.cpp
class CDetour /* add ": public CRealRun" to enable access to member variables... */
{
public:
	int Mine_Target(int cmd)
	static int(CDetour::* Real_Target)(int cmd);

	// Class shouldn't have any member variables or virtual functions.
};

int CDetour::Mine_Target(int cmd)
{
	printf("  CDetour::Mine_Target! (this:%p)\n", this);
	(this->*Real_Target)();
}

int (CDetour::* CDetour::Real_Target)(int cmd) = (int (CDetour::*)(int cmd))&CRealRun::Run;


////////
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
					 )
{
	if (DLL_PROCESS_ATTACH == ul_reason_for_call)
	{
		MessageBox(NULL, _T("DLL已从目标进程。"), _T("信息"), MB_ICONINFORMATION);
		DetourTransactionBegin();
		DetourUpdateThread(GetCurrentThread());
		DetourAttach(&(PVOID&)CDetour::Real_Target, (PVOID)(&(PVOID&)CDetour::Mine_Target);
		DetourTransactionCommit();
	}
	else if (DLL_PROCESS_DETACH == ul_reason_for_call)
	{
		MessageBox(NULL, _T("DLL已从目标进程卸载。"), _T("信息"), MB_ICONINFORMATION);
		DetourTransactionBegin();
		DetourUpdateThread(GetCurrentThread());
		DetourDetach(&(PVOID&)SysMessageBox, HookMessageBox);
	        DetourDetach(&(PVOID&)CDetour::Real_Target, (PVOID)(&(PVOID&)CDetour::Mine_Target));
		DetourTransactionCommit();
	}
	return TRUE;
}
zhm_joy 2014-12-02
  • 打赏
  • 举报
回复
引用 1 楼 fly_dragon_fly 的回复:
这个类需要导出,这样detour就可以通过导出表找到
首先这个类我动不了,只能这样;后来我去看了detours samples的member.cpp,但是运行会报:

//dllmain.cpp
class CDetour /* add ": public CRealRun" to enable access to member variables... */
{
public:
	int Mine_Target(int cmd)
	static int(CDetour::* Real_Target)(int cmd);

	// Class shouldn't have any member variables or virtual functions.
};

int CDetour::Mine_Target(int cmd)
{
	printf("  CDetour::Mine_Target! (this:%p)\n", this);
	(this->*Real_Target)();
}

int (CDetour::* CDetour::Real_Target)(int cmd) = (int (CDetour::*)(int cmd))&CRealRun::Run;


////////
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
					 )
{
	if (DLL_PROCESS_ATTACH == ul_reason_for_call)
	{
		MessageBox(NULL, _T("DLL已从目标进程。"), _T("信息"), MB_ICONINFORMATION);
		DetourTransactionBegin();
		DetourUpdateThread(GetCurrentThread());
		//DetourAttach(&(PVOID&)CDataHook::RealRun, DetourRunapi);
		DetourTransactionCommit();
	}
	else if (DLL_PROCESS_DETACH == ul_reason_for_call)
	{
		MessageBox(NULL, _T("DLL已从目标进程卸载。"), _T("信息"), MB_ICONINFORMATION);
		DetourTransactionBegin();
		DetourUpdateThread(GetCurrentThread());
		DetourDetach(&(PVOID&)SysMessageBox, HookMessageBox);
	DetourAttach(&(PVOID&)CDetour::Real_Target,
		(PVOID)(&(PVOID&)CDetour::Mine_Target));
		DetourTransactionCommit();
	}
	return TRUE;
}

65,198

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧