能力值:
( LV3,RANK:30 )
|
-
-
2 楼
你的代码不太全,所以我说说我的理解,我觉得问题出在下面的定义:
int CHook::HookProcDispatch(int nHookAddress, t_Context *pContext)
这是一个类成员函数,不同于一般的函数。
然后这一句
mov edx, CHook::HookProcDispatch
是将该函数的地址压入edx中,这样可能会有问题,你将这个函数改为一般的函数,而不是类的函数,或者类的静态成员函数,应该就可以获取到该函数的地址了。
|
能力值:
( LV2,RANK:10 )
|
-
-
3 楼
memcpy_s 是memcpy的安全版本
使用memcpy_s需要添加头文件memory.h 或者是 string.h
如果VC6中无法识别memcpy_s函数,可将第二个参数删除后使用memcpy函数。
你可以看看下面这个链接
http://technet.microsoft.com/zh-tw/library/8ef0s5kh(v=vs.110)
|
能力值:
( LV2,RANK:10 )
|
-
-
4 楼
__declspec(naked) void CHook::HookProcHandle()
{
//查表,调用相应的函数
__asm
{
pushad
mov eax, esp
push eax //压入CONTEXT结构
add eax, 0x20 //移动到nHookAddress的地址处
mov edx, dword ptr [eax] //修正返回地址
sub edx, 0x5
mov dword ptr [eax], edx
push edx //压入hook地址
mov ebx, eax
lea eax, [ebx-0x14]
mov eax, dword ptr [eax]
add eax, 4
mov dword ptr [ebx-0x14], eax
mov edx, CHook::HookProcDispatch ///////编译错误:error C2420: 'CHook' : illegal symbol in second operand
call edx
mov dword ptr [ebx], eax
popad
ret //返回到原来的代码
}
}
int CHook::HookProcDispatch(int nHookAddress, t_Context *pContext)
{
CHook *pHook = CHook::GetHookInstance();
EnterCriticalSection(&pHook->m_Cs);
map<int, t_HookInfo*>::iterator iter = pHook->m_mapHookInfo.find(nHookAddress);
LeaveCriticalSection(&pHook->m_Cs);
if (iter != pHook->m_mapHookInfo.end())
{
CHook::t_HookInfo *pHookInfo = (CHook::t_HookInfo*)((*iter).second);
if (pHookInfo->pfnProc.pThis == NULL)
{
//C 函数
CHook::HookCProc pfnHookCProc = pHookInfo->pfnProc.u.pfnHookCProc;
pfnHookCProc(nHookAddress, pContext);
}
else
{
//C++类成员函数
CHook::HookProc pfnHookProc = pHookInfo->pfnProc.u.pfnHookProc;
void *pThis = pHookInfo->pfnProc.pThis;
__asm
{
pushad
mov ecx, pThis
push pContext
push nHookAddress
mov edx, pfnHookProc
call edx
popad
}
}
//返回地址
return (int)(pHookInfo->szOldCode);
}
return 0;
}
//hook类
class CHook
{
protected:
CHook(void);
public:
~CHook(void);
struct t_HookInfo;
struct t_Context;
//函数类型
typedef void (__cdecl *HookCProc)(int nHookAddress, t_Context *pContext);
typedef void (__cdecl CHook::*HookProc)(int nHookAddress, t_Context *pContext);
public:
bool AddHook(int nHookAddress, CHook::HookCProc nHookProc);
bool AddHook(int nHookAddress, CHook::HookProc nHookProc, void *pThis);
void RemoveHook(int nHookAddress);
protected:
//返回当前指令的长度
int GetOpCodeSize(BYTE* startaddress);
//Hook指定代码地址处
int HookAddress(int nHookAddress, t_HookInfo *pHookInfo);
//恢复指定代码处的地址
int RemoveAddress(int nHookAddress, t_HookInfo *pHookInfo);
public:
struct t_HookProc
{
void *pThis;
union
{
HookCProc pfnHookCProc;
HookProc pfnHookProc;
}u;
};
struct t_HookInfo
{
int nHookAddress;
t_HookProc pfnProc;
int nRetAddress; //返回地址
char szOldCode[32];
int nOldCodeSize;
};
struct t_Context
{
int nEdi;
int nEsi;
int nEbp;
int nEsp;
int nEbx;
int nEdx;
int nEcx;
int nEax;
};
protected:
public:
map<int, t_HookInfo*> m_mapHookInfo;
CRITICAL_SECTION m_Cs;
public:
static CHook *m_pHook;
static CHook* GetHookInstance();
static void HookProcHandle();
static int __stdcall HookProcDispatch(int nHookAddress, t_Context *pContext);
};
确实是静态成员函数.
这个代码是从下面下载的:
http://bbs.pediy.com/showthread.php?t=115449
我只是把hash_map改成了map,因为vc6没有hash_map.
就剩下这个错误,估计是vc6编译有问题,不知道怎么改了...
|
能力值:
( LV2,RANK:10 )
|
-
-
5 楼
静态成员函数声明:
static int __stdcall HookProcDispatch(int nHookAddress, t_Context *pContext);
函数指针定义:
typedef int (__stdcall * MYFUN)(int nHookAddress, CHook::t_Context *pContext);
MYFUN pFun = CHook::HookProcDispatch;
__declspec(naked) void CHook::HookProcHandle()
{
//查表,调用相应的函数
__asm
{
pushad
mov eax, esp
push eax //压入CONTEXT结构
add eax, 0x20 //移动到nHookAddress的地址处
mov edx, dword ptr [eax] //修正返回地址
sub edx, 0x5
mov dword ptr [eax], edx
push edx //压入hook地址
mov ebx, eax
lea eax, [ebx-0x14]
mov eax, dword ptr [eax]
add eax, 4
mov dword ptr [ebx-0x14], eax
//mov edx, HookProcDispatch
mov edx, pFun //改成函数指针,就能调用了 call edx
mov dword ptr [ebx], eax
popad
ret //返回到原来的代码
}
}
上面这样修改一翻后,可以编译成功.
估计是VC6版本老,不支持直接嵌入C++静态成员函数
请高手解释下,谢谢
|
能力值:
( LV2,RANK:10 )
|
-
-
6 楼
mov edx, CHook::HookProcDispatch
改成 mov edx,&CHook::HookProcDispatch 可以吗?
你原来的mov edx, CHook::HookProcDispatch 编译器可能认为把函数的返回值放入edx,比如返回值是int,放入edx,但是你并没有call CHook::HookProcDispatch ,所以没有int返回值。
|
能力值:
( LV2,RANK:10 )
|
-
-
7 楼
成员函数的地址不是象你这样写的。
|
能力值:
( LV2,RANK:10 )
|
-
-
8 楼
这样肯定不行的,编译错误告警提示 CHook都不能用
|
能力值:
( LV2,RANK:10 )
|
-
-
9 楼
mov edx,offset CHook::HookProcDispatch
编译通过。
|
能力值:
( LV2,RANK:10 )
|
-
-
10 楼
lea edx, CHook::HookProcDispatch
编译通过
|
能力值:
( LV2,RANK:10 )
|
-
-
11 楼
我也正在学习VC!
|
能力值:
( LV2,RANK:10 )
|
-
-
12 楼
你的编译器版本不是VC6吧? 这个源码应该在高级版本应该是通过的,我一直怀疑是vc6的问题呢
|
能力值:
( LV2,RANK:10 )
|
-
-
13 楼
厄,是VS2010。
|