能力值:
( LV13,RANK:410 )
2 楼
IDA里面看不出原型?
你只要搞对参数个数和返回类型就行了啊.参数一律DWORD.
声明对应原型的函数指针.memcpy或者强转成DWORD*赋值就行了.
利用detour只用提供如下3个数据就行了.
1.detoured函数的地址(就是被HOOK的函数地址)
2.detoured函数原型(ASM级别的原型就行.参数数量,返回地址和调用约定)
3.和detoured函数原型一致的detour函数地址(就是用来hook的函数地址.ASM级别上原型一致).
就是C++不支持DWORD向_thiscall *的转换.为了重入方便往往将detoured函数地址存入相应的函数指针.所以赋值的时候要强转成DWORD *.
可以参考Detour Sample
member.cpp
上面讲的类型都是针对x86.
x64没研究过.也没有付费版的detour.
能力值:
( LV2,RANK:10 )
3 楼
看了member.cpp里面的教程跟我上文说到的是一样的:
//////////////////////////////////////////////////////////////// Target Class.
//
class CMember
{
public:
void Target(void);
};
void CMember::Target(void)
{
printf(" CMember::Target! (this:%p)\n", this);
}
//////////////////////////////////////////////////////////////// Detour Class.
//
class CDetour /* add ": public CMember" to enable access to member variables... */
{
public:
void Mine_Target(void);
static void (CDetour::* Real_Target)(void);
// Class shouldn't have any member variables or virtual functions.
};
void CDetour::Mine_Target(void)
{
printf(" CDetour::Mine_Target! (this:%p)\n", this);
(this->*Real_Target)();
}
void (CDetour::* CDetour::Real_Target)(void) = (void (CDetour::*)(void))&CMember::Target ;
//////////////////////////////////////////////////////////////////////////////
上面红色加粗代码&CMember::Target,在我的程序里是未知的,只知道一个地址,这个如何编写?
能力值:
( LV13,RANK:410 )
4 楼
*(DWORD *)&CDetour::Real_Target = 0xXXXXXXXX;
Or
ver = 0xXXXXXXXX;
memcpy((LPVOID)&CDetour::Real_Target,ver,4);
能力值:
( LV2,RANK:10 )
5 楼
typedef void (__cdecl * VPF)(void);
VPF tt ;
#define TTT( a , b ) (a)=(b)
TTT(tt,classTmp.classFn2); 或memcpy( tt,(void*)classTmp.classFn2,4); 都不行,
error C2440: '=' : cannot convert from 'void (__thiscall TestClass::*)(void)' to 'void (__cdecl *)(void)'
能力值:
( LV2,RANK:10 )
6 楼
对于只知道类成员函数地址的情况,detours库貌似是存在问题的,我研究之后发现问题的原因是 :
由于类成员函数会隐式传递this指针,所以在hook函数中返回原函数时,由于堆栈不平衡导致被hook的程序崩溃
解决办法:
1. 迂回解决,hook一个目标函数的附近的函数,利用堆栈信息找到自己需要的地址与内存(现在在我那个项目是这样解决的,解决了99.99%问题)
2. 据某位大大说,在hook函数调用返回原函数时,直接用反汇编call地址,并ret相应的字节(需要一个一个的调整),但我尝试了n次,没能成功
求助:
利用上面的第一个方法解决了当前项目的问题,但我另一个项目遇到的情况是目标函数附近没有独立的函数可以hook(全是类成员函数),所以我必须hook类成员函数- -b 郁闷啊,不知道论坛的大侠有没有办法搞定啊!!
能力值:
( LV5,RANK:70 )
7 楼
传送门 http://bbs.pediy.com/showthread.php?t=115449
能力值:
( LV2,RANK:10 )
8 楼
没有仔细研究这个hook类,但这个好像是用于hook API的自己封装的一个类吧,我现在遇到的麻烦是需要hook一个类成员函数哦- -b
能力值:
( LV5,RANK:70 )
9 楼
只要知道类成员函数地址及可以进行hook了,类成员函数地址可以这样获取
class A
{
public:
void func();
}
(int)A::func
能力值:
( LV2,RANK:10 )
10 楼
已经解决问题了,用的还是detours,方法稍后放出
能力值:
( LV2,RANK:10 )
11 楼
术语说明:
原函数:被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*参数个数
能力值:
( LV2,RANK:10 )
12 楼
可以先查看类内成员函数布局情况,然后找出该成员函数的地址,
代替的函数原型第一个参数加this即可。
能力值:
( LV12,RANK:210 )
13 楼
就这么办即可,自己补加一个参数this即可
能力值:
( LV2,RANK:10 )
14 楼
这才是国人应该有的态度,好多人提问后自己解决了问题从来不说的。
能力值:
( LV2,RANK:10 )
15 楼
参数this的值又怎么去获取呢?
能力值:
( LV12,RANK:210 )
16 楼
/*
ÀûÓÃDetours Hook±ê×¼APIºÍÀà³ÉÔ±º¯Êý
×Ô¼ºÊµÏÖHookÀàµÄÐ麯Êý:Ò»¡¢ÐÞ¸ÄÐé±í ¶þ¡¢Detours Hook
*/
#include "stdafx.h"
#include <windows.h>
#include "Ring3Hook.h"
#include "detours.h"
#pragma comment(lib,"detours.lib")
/*
Detours Hook±ê×¼API£¨µ¼³ö»òδµ¼³öº¯Êý£©: MessageBoxW
*/
typedef int (WINAPI *pfMessageBoxW)(HWND hWnd,LPCWSTR lpText,LPCWSTR lpCaption,UINT uType);
pfMessageBoxW RealMessageBoxW = MessageBoxW;
int WINAPI HookMessageBoxW(HWND hWnd,LPCWSTR lpText,LPCWSTR lpCaption,UINT uType)
{
//¸Ä±ä¿í×Ö·û
return RealMessageBoxW(hWnd,L"caonima",lpCaption,uType);
}
//ÕâÀïÊÇHookÀà³ÉÔ±º¯Êý
typedef void (WINAPI *pfTest)(int a,int b);
pfTest RealTest = (pfTest)0x00401023;
void WINAPI HookTest(int a,int b);
//nakedº¯Êý£º×Ô¼ºÆ½ºâ¶ÑÕ»µÄº¯Êý
_declspec(naked) void StubFunction(int a,int b)
{
_asm
{
push ebp
mov ebp,esp
push ecx
}
HookTest(a,b);
_asm
{
add esp,4
pop ebp
ret 8 //ÕâÀï¶Ñջƽºâ²ÎÊý
}
}
void WINAPI HookTest(int a,int b)
{
//±£´æthisÖ¸Õë
a=a+1;
b=b+1;
_asm
{
push ecx
mov ecx,[ebp+0x10] //ebp+4+²ÎÊý¸öÊý*4+4,Õ»Öб£´æµÄecx
}
RealTest(a,b);
_asm
{
pop ecx
}
}
DetoursHookInfo _StandardWinApi[]=
{
{(DWORD*)&RealMessageBoxW, (DWORD)HookMessageBoxW},
{(DWORD*)&RealTest,(DWORD)StubFunction}
};
VOID StartDetoursHook()
{
//ÀûÓÃÒ»¸öforÑ»·HookÈ«²¿
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
for(int i=0; i< sizeof(_StandardWinApi)/sizeof(DetoursHookInfo); i++)
{
DetourAttach(&(PVOID&)*(DWORD*)(_StandardWinApi[i].OldAddress), (PVOID)_StandardWinApi[i].NewAddress);
}
DetourTransactionCommit();
}
能力值:
( LV1,RANK:0 )
17 楼
我知道这个成员函数的地址 请问怎么hook 实在是没看明白!