0%

CULHook

CULHook类

这个类写起来时很暴力的,和书上说的一样,我喜欢。
思路也比较简单粗暴,就是将我们的API指向地址的前八个字节写成:

1
2
mov eax,0xXXXX
jmp eax

也就是:
汇编代码
这里比较难搞的就是地址我们怎么赋值,可能有人就要考虑到一个大端小段,但是我们强转成DWOD类型就可以解决这个困惑了。

头文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#ifndef __ULHOOK_H__
#define __ULHOOK_H__

#include <Windows.h>

class CULHook
{
public:
CULHook(LPSTR pszModName,LPSTR pszFuncName,PROC pfnHook);//这个新的函数是需要naked的,不要处理堆栈平衡
~CULHook();
void Unhook();
void Rehook();

protected:
PROC m_pfnOrig;
BYTE m_btNewBytes[8];
BYTE m_btOldBytes[8];
HMODULE m_hModule;
};

#endif //__ULHOOK_H__

这里就一个构造函数就可以进行HOOK了,但是非常注意的就是由于我们是直接暴力的写汇编,所以我们是不能要堆栈操作的。

源文件

构造函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
CULHook::CULHook(LPSTR pszModName,LPSTR pszFuncName,PROC pfnHook)
{
BYTE btNewBytes[8] = {0xB8,0x00,0x00,0x40,0x00,0xFF,0xE0,0x00};
memcpy(m_btNewBytes,btNewBytes,8);
*(DWORD *)(m_btNewBytes+1) = (DWORD)pfnHook;
m_hModule = LoadLibrary(pszModName);
if (m_hModule == NULL)
{
m_pfnOrig = NULL;
return ;
}
m_pfnOrig = GetProcAddress(m_hModule,pszFuncName);

if (m_pfnOrig != NULL)
{
DWORD dwOldProtect;
MEMORY_BASIC_INFORMATION mbi;
VirtualQuery(m_pfnOrig,&mbi,sizeof(mbi));
VirtualProtect(m_pfnOrig,8,PAGE_READWRITE,&dwOldProtect);
memcpy(m_btOldBytes,m_pfnOrig,8);
WriteProcessMemory(GetCurrentProcess(),(LPVOID)m_pfnOrig,m_btNewBytes,sizeof(DWORD)*2,NULL);
VirtualProtect(m_pfnOrig,8,dwOldProtect,0);
}
}

首先将我们的汇编代码改一下,这里可以看到非常的巧妙,先转成DWORD然后再赋值,然后我们再将2,3,4,5这四个字节替换成我们的地址,这个是真的巧妙,之后我们就获取要HOOK函数的地址,再将这个地址的前八个字节的保护属性改掉,改完之后,写我们的这八个字节。

取消HOOK和重新HOOK:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
void CULHook::Unhook()
{
if (m_pfnOrig != NULL)
{
DWORD dwOldProtect;
MEMORY_BASIC_INFORMATION mbi;
VirtualQuery(m_pfnOrig,&mbi,sizeof(mbi));
VirtualProtect(m_pfnOrig,8,PAGE_READWRITE,&dwOldProtect);
memcpy(m_btOldBytes,m_pfnOrig,8);
WriteProcessMemory(GetCurrentProcess(),(LPVOID)m_pfnOrig,m_btOldBytes,sizeof(DWORD)*2,NULL);
VirtualProtect(m_pfnOrig,8,dwOldProtect,0);
}
}

void CULHook::Rehook()
{
if (m_pfnOrig != NULL)
{
DWORD dwOldProtect;
MEMORY_BASIC_INFORMATION mbi;
VirtualQuery(m_pfnOrig,&mbi,sizeof(mbi));
VirtualProtect(m_pfnOrig,8,PAGE_READWRITE,&dwOldProtect);
memcpy(m_btOldBytes,m_pfnOrig,8);
WriteProcessMemory(GetCurrentProcess(),(LPVOID)m_pfnOrig,m_btNewBytes,sizeof(DWORD)*2,NULL);
VirtualProtect(m_pfnOrig,8,dwOldProtect,0);
}
}

取消HOOK和重新HOOK就是一样,也就是修改前八个字节。

析构函数就是先取消HOOK,然后再释放DLL句柄

1
2
3
4
5
6
CULHook::~CULHook()
{
Unhook();
if(m_hModule != NULL)
FreeLibrary(m_hModule);
}