封装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:%X\n", 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;
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值