手机
当前位置:查字典教程网 >编程开发 >C语言 >C++封装IATHOOK类实例
C++封装IATHOOK类实例
摘要:本文实例讲述了C++封装IATHOOK类的实现方法。分享给大家供大家参考。具体方法如下:1.定义成类的静态成员,从而实现自动调用复制代码代码...

本文实例讲述了C++封装IATHOOK类的实现方法。分享给大家供大家参考。具体方法如下:

1. 定义成类的静态成员,从而实现自动调用

复制代码 代码如下:static CAPIHOOK sm_LoadLibraryA;

static CAPIHOOK sm_LoadLibraryW;

static CAPIHOOK sm_LoadLibraryExA;

static CAPIHOOK sm_LoadLibraryExW;

static CAPIHOOK sm_GetProcAddress;

2. ReplaceIATEntryInAllMods中遍历模块的框架

复制代码 代码如下:void CAPIHOOK::ReplaceIATEntryInAllMods(LPCTSTR pszExportMod, PROC pfnCurrent, PROC pfnNewFunc, BOOL bExcludeAPIHookMod)

{

//取得当前模块句柄

HMODULE hModThis = NULL;

if (bExcludeAPIHookMod)

{

MEMORY_BASIC_INFORMATION mbi;

if (0 != ::VirtualQuery(ReplaceIATEntryInAllMods, &mbi, sizeof(MEMORY_BASIC_INFORMATION))) //ReplaceIATEntryInAllMods必须为类的static函数

{

hModThis = (HMODULE)mbi.AllocationBase;

}

}

//取得本进程的模块列表

HANDLE hModuleSnap = INVALID_HANDLE_VALUE;

MODULEENTRY32 me32;

hModuleSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId());

if (INVALID_HANDLE_VALUE == hModuleSnap)

{

return;

}

me32.dwSize = sizeof( MODULEENTRY32 );

if( !Module32First( hModuleSnap, &me32 ) )

{

return;

}

do

{ //对每一个模块

if (me32.hModule != hModThis)

{

ReplaceIATEntryInOneMod(pszExportMod, pfnCurrent, pfnNewFunc, me32.hModule);

}

} while( Module32Next( hModuleSnap, &me32 ) );

::CloseHandle(hModuleSnap); //配对写

}

3. 遍历链表摘除自己的框架

复制代码 代码如下:CAPIHOOK::~CAPIHOOK(void)

{

//取消对函数的HOOK

ReplaceIATEntryInAllMods(m_pszModName, m_pfnHook, m_pfnOrig, TRUE);

//把自己从链表中删除

CAPIHOOK* p = sm_pHeader;

if (p == this)

{

sm_pHeader = this->m_pNext;

}

else

{

while(p != NULL)

{

if (p->m_pNext == this)

{

p->m_pNext = this->m_pNext;

break;

}

p = p->m_pNext;

}

}

}

4. 在cpp中静态变量写好后,再编译,不然容易出现LINK错误

复制代码 代码如下:CAPIHOOK *CAPIHOOK::sm_pHeader = NULL;

源码:

.cpp源文件如下:

复制代码 代码如下:#include "APIHOOK.h"

#include <Tlhelp32.h>

CAPIHOOK *CAPIHOOK::sm_pHeader = NULL;

CAPIHOOK CAPIHOOK::sm_LoadLibraryA("kernel32.dll", "LoadLibraryA", (PROC)CAPIHOOK::LoadLibraryA, TRUE);

CAPIHOOK CAPIHOOK::sm_LoadLibraryW("kernel32.dll", "LoadLibraryW", (PROC)CAPIHOOK::LoadLibraryW, TRUE);

CAPIHOOK CAPIHOOK::sm_LoadLibraryExA("kernel32.dll", "LoadLibraryExA", (PROC)CAPIHOOK::LoadLibraryExA, TRUE);

CAPIHOOK CAPIHOOK::sm_LoadLibraryExW("kernel32.dll", "LoadLibraryExW", (PROC)CAPIHOOK::LoadLibraryExW, TRUE);

CAPIHOOK CAPIHOOK::sm_GetProcAddress("kernel32.dll", "GetProcAddress", (PROC)CAPIHOOK::GetProcess, TRUE);

CAPIHOOK::CAPIHOOK(LPTSTR lpszModName, LPSTR pszFuncName, PROC pfnHook, BOOL bExcludeAPIHookMod)

{

//初始化变量

m_pszModName = lpszModName;

m_pszFuncName = pszFuncName;

m_pfnOrig = ::GetProcAddress(::GetModuleHandleA(lpszModName), pszFuncName);

m_pfnHook = pfnHook;

//将此对象加入链表中

m_pNext = sm_pHeader;

sm_pHeader = this;

//在当前已加载的模块中HOOK这个函数

ReplaceIATEntryInAllMods(lpszModName, m_pfnOrig, m_pfnHook, bExcludeAPIHookMod);

}

CAPIHOOK::~CAPIHOOK(void)

{

//取消对函数的HOOK

ReplaceIATEntryInAllMods(m_pszModName, m_pfnHook, m_pfnOrig, TRUE);

//把自己从链表中删除

CAPIHOOK* p = sm_pHeader;

if (p == this)

{

sm_pHeader = this->m_pNext;

}

else

{

while(p != NULL)

{

if (p->m_pNext == this)

{

p->m_pNext = this->m_pNext;

break;

}

p = p->m_pNext;

}

}

}

//防止程序运行期间动态加载模块

void CAPIHOOK::HookNewlyLoadedModule(HMODULE hModule, DWORD dwFlags)

{

if (hModule!=NULL && (dwFlags&LOAD_LIBRARY_AS_DATAFILE)==0)

{

CAPIHOOK* p = sm_pHeader; //循环遍历链表,对每个CAPIHOOK进入HOOK

if (p != NULL)

{

ReplaceIATEntryInOneMod(p->m_pszModName, p->m_pfnOrig, p->m_pfnHook, hModule);

p = p->m_pNext;

}

}

}

//防止程序运行期间动态调用API函数

FARPROC WINAPI CAPIHOOK::GetProcess(HMODULE hModule, PCSTR pszProcName)

{

//得到函数的真实地址

FARPROC pfn = ::GetProcAddress(hModule, pszProcName);

//遍历列表 看是不是要HOOK的函数

CAPIHOOK* p = sm_pHeader;

while(p != NULL)

{

if (p->m_pfnOrig == pfn) //是要HOOK的函数

{

pfn = p->m_pfnHook; //HOOK掉

break;

}

p = p->m_pNext;

}

return pfn;

}

void CAPIHOOK::ReplaceIATEntryInOneMod(LPCTSTR pszExportMod, PROC pfnCurrent, PROC pfnNewFunc, HMODULE hModCaller)

{

IMAGE_DOS_HEADER* pDosHeader = (IMAGE_DOS_HEADER*)hModCaller;

IMAGE_OPTIONAL_HEADER* pOpNtHeader = (IMAGE_OPTIONAL_HEADER*)((BYTE*)hModCaller + pDosHeader->e_lfanew + 24); //这里加24

IMAGE_IMPORT_DESCRIPTOR* pImportDesc = (IMAGE_IMPORT_DESCRIPTOR*)((BYTE*)hModCaller + pOpNtHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);

BOOL bFindDll = FALSE;

while (pImportDesc->FirstThunk)

{

char* pszDllName = (char*)((BYTE*)hModCaller + pImportDesc->Name);

if (stricmp(pszDllName, pszExportMod) == 0)//如果找到pszExportMod模块,相当于hook messageboxa时的“user32.dll”

{

bFindDll = TRUE;

break;

}

pImportDesc++;

}

if (bFindDll)

{

DWORD n = 0;

//一个IMAGE_THUNK_DATA就是一个导入函数

IMAGE_THUNK_DATA* pThunk = (IMAGE_THUNK_DATA*)((BYTE*)hModCaller + pImportDesc->OriginalFirstThunk);

while (pThunk->u1.Function)

{

//取得函数名称

char* pszFuncName = (char*)((BYTE*)hModCaller+pThunk->u1.AddressOfData+2); //函数名前面有两个..

//printf("function name:%-25s, ", pszFuncName);

//取得函数地址

PDWORD lpAddr = (DWORD*)((BYTE*)hModCaller + pImportDesc->FirstThunk) + n; //从第一个函数的地址,以后每次+4字节

//printf("addrss:%Xn", lpAddr);

//在这里是比较的函数地址

if (*lpAddr == (DWORD)pfnCurrent) //找到iat中的函数地址

{

DWORD* lpNewProc = (DWORD*)pfnNewFunc;

MEMORY_BASIC_INFORMATION mbi;

DWORD dwOldProtect;

//修改内存页的保护属性

::VirtualQuery(lpAddr, &mbi, sizeof(MEMORY_BASIC_INFORMATION));

::VirtualProtect(lpAddr, sizeof(DWORD), PAGE_READWRITE, &dwOldProtect);

::WriteProcessMemory(GetCurrentProcess(), lpAddr, &lpNewProc, sizeof(DWORD), NULL);

::VirtualProtect(lpAddr, sizeof(DWORD), dwOldProtect, NULL);

return;

}

n++; //每次增加一个DWORD

}

}

}

void CAPIHOOK::ReplaceIATEntryInAllMods(LPCTSTR pszExportMod, PROC pfnCurrent, PROC pfnNewFunc, BOOL bExcludeAPIHookMod)

{

//取得当前模块句柄

HMODULE hModThis = NULL;

if (bExcludeAPIHookMod)

{

MEMORY_BASIC_INFORMATION mbi;

if (0 != ::VirtualQuery(ReplaceIATEntryInAllMods, &mbi, sizeof(MEMORY_BASIC_INFORMATION))) //ReplaceIATEntryInAllMods必须为类的static函数

{

hModThis = (HMODULE)mbi.AllocationBase;

}

}

//取得本进程的模块列表

HANDLE hModuleSnap = INVALID_HANDLE_VALUE;

MODULEENTRY32 me32;

hModuleSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId());

if (INVALID_HANDLE_VALUE == hModuleSnap)

{

return;

}

me32.dwSize = sizeof( MODULEENTRY32 );

if( !Module32First( hModuleSnap, &me32 ) )

{

return;

}

do

{ //对每一个模块

if (me32.hModule != hModThis)

{

ReplaceIATEntryInOneMod(pszExportMod, pfnCurrent, pfnNewFunc, me32.hModule);

}

} while( Module32Next( hModuleSnap, &me32 ) );

::CloseHandle(hModuleSnap); //配对写

}

//防止自动加载

HMODULE WINAPI CAPIHOOK::LoadLibraryA(LPCTSTR lpFileName)

{

HMODULE hModule = LoadLibraryA(lpFileName);

HookNewlyLoadedModule(hModule, 0); //这个函数中忆检测hModule 了

return hModule;

}

HMODULE WINAPI CAPIHOOK::LoadLibraryW(LPCTSTR lpFileName)

{

HMODULE hModule = LoadLibraryW(lpFileName);

HookNewlyLoadedModule(hModule, 0); //这个函数中忆检测hModule 了

return hModule;

}

HMODULE WINAPI CAPIHOOK::LoadLibraryExA(LPCTSTR lpFileName, HANDLE hFile, DWORD dwFlags)

{

HMODULE hModule = LoadLibraryExA(lpFileName, hFile, dwFlags);

HookNewlyLoadedModule(hModule, dwFlags); //这个函数中忆检测hModule 了

return hModule;

}

HMODULE WINAPI CAPIHOOK::LoadLibraryExW(LPCTSTR lpFileName, HANDLE hFile, DWORD dwFlags)

{

HMODULE hModule = LoadLibraryExW(lpFileName, hFile, dwFlags);

HookNewlyLoadedModule(hModule, dwFlags); //这个函数中忆检测hModule 了

return hModule;

}

.h头文件如下:

复制代码 代码如下:#pragma once

#include <Windows.h>

class CAPIHOOK

{

public:

CAPIHOOK(LPTSTR lpszModName, LPSTR pszFuncName, PROC pfnHook, BOOL bExcludeAPIHookMod = TRUE);

~CAPIHOOK(void);

private:

static void ReplaceIATEntryInOneMod(LPCTSTR pszExportMod, PROC pfnCurrent, PROC pfnNewFunc, HMODULE hModCaller);

static void ReplaceIATEntryInAllMods(LPCTSTR pszExportMod, PROC pfnCurrent, PROC pfnNewFunc, BOOL bExcludeAPIHookMod);

//防止程序运行期间动态加载模块, 当一个新DLL被加载时调用

static void HookNewlyLoadedModule(HMODULE hModule, DWORD dwFlags);

//跟踪当前进程加载新的DLL

static HMODULE WINAPI LoadLibraryA(LPCTSTR lpFileName);

static HMODULE WINAPI LoadLibraryW(LPCTSTR lpFileName);

static HMODULE WINAPI LoadLibraryExA(LPCTSTR lpFileName, HANDLE hFile, DWORD dwFlags);

static HMODULE WINAPI LoadLibraryExW(LPCTSTR lpFileName, HANDLE hFile, DWORD dwFlags);

//防止程序运行期间动态调用API函数 对于请求已HOOK的API函数,返回用户自定义的函数地址

static FARPROC WINAPI GetProcess(HMODULE hModule, PCSTR pszProcName);

private: //定义成静态的,会自动调用,从而实现自动HOOK

static CAPIHOOK sm_LoadLibraryA;

static CAPIHOOK sm_LoadLibraryW;

static CAPIHOOK sm_LoadLibraryExA;

static CAPIHOOK sm_LoadLibraryExW;

static CAPIHOOK sm_GetProcAddress;

private:

static CAPIHOOK* sm_pHeader; //钩子链表

CAPIHOOK* m_pNext;

//要钩子的函数

PROC m_pfnOrig;

PROC m_pfnHook;

//要钩子的函数所在的dll

LPSTR m_pszModName;

//要钩子的函数名称

LPSTR m_pszFuncName;

};

希望本文所述对大家的C++程序设计有所帮助。

【C++封装IATHOOK类实例】相关文章:

C++产生随机数的实现代码

C++求斐波那契数的实例代码

贪心算法 WOODEN STICKS 实例代码

C语言实现逆波兰式实例

C++ 构造双向链表的实现代码

8皇后问题的解法实例代码

C++中抽象类和接口的区别介绍

VC实现图片拖拽及动画的实例

C++类中的常量介绍

数组循环移位操作实例

精品推荐
分类导航