C++封装IATHOOK类实例
本文实例讲述了C++封装IATHOOK类的实现方法。分享给大家供大家参考。具体方法如下:
1.定义成类的静态成员,从而实现自动调用
staticCAPIHOOKsm_LoadLibraryA; staticCAPIHOOKsm_LoadLibraryW; staticCAPIHOOKsm_LoadLibraryExA; staticCAPIHOOKsm_LoadLibraryExW; staticCAPIHOOKsm_GetProcAddress;
2.ReplaceIATEntryInAllMods中遍历模块的框架
voidCAPIHOOK::ReplaceIATEntryInAllMods(LPCTSTRpszExportMod,PROCpfnCurrent,PROCpfnNewFunc,BOOLbExcludeAPIHookMod)
{
//取得当前模块句柄
HMODULEhModThis=NULL;
if(bExcludeAPIHookMod)
{
MEMORY_BASIC_INFORMATIONmbi;
if(0!=::VirtualQuery(ReplaceIATEntryInAllMods,&mbi,sizeof(MEMORY_BASIC_INFORMATION)))//ReplaceIATEntryInAllMods必须为类的static函数
{
hModThis=(HMODULE)mbi.AllocationBase;
}
}
//取得本进程的模块列表
HANDLEhModuleSnap=INVALID_HANDLE_VALUE;
MODULEENTRY32me32;
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;
CAPIHOOKCAPIHOOK::sm_LoadLibraryA("kernel32.dll","LoadLibraryA",(PROC)CAPIHOOK::LoadLibraryA,TRUE);
CAPIHOOKCAPIHOOK::sm_LoadLibraryW("kernel32.dll","LoadLibraryW",(PROC)CAPIHOOK::LoadLibraryW,TRUE);
CAPIHOOKCAPIHOOK::sm_LoadLibraryExA("kernel32.dll","LoadLibraryExA",(PROC)CAPIHOOK::LoadLibraryExA,TRUE);
CAPIHOOKCAPIHOOK::sm_LoadLibraryExW("kernel32.dll","LoadLibraryExW",(PROC)CAPIHOOK::LoadLibraryExW,TRUE);
CAPIHOOKCAPIHOOK::sm_GetProcAddress("kernel32.dll","GetProcAddress",(PROC)CAPIHOOK::GetProcess,TRUE);
CAPIHOOK::CAPIHOOK(LPTSTRlpszModName,LPSTRpszFuncName,PROCpfnHook,BOOLbExcludeAPIHookMod)
{
//初始化变量
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;
}
}
}
//防止程序运行期间动态加载模块
voidCAPIHOOK::HookNewlyLoadedModule(HMODULEhModule,DWORDdwFlags)
{
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函数 FARPROCWINAPICAPIHOOK::GetProcess(HMODULEhModule,PCSTRpszProcName) { //得到函数的真实地址 FARPROCpfn=::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; } returnpfn; } voidCAPIHOOK::ReplaceIATEntryInOneMod(LPCTSTRpszExportMod,PROCpfnCurrent,PROCpfnNewFunc,HMODULEhModCaller) { 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); BOOLbFindDll=FALSE; while(pImportDesc->FirstThunk) { char*pszDllName=(char*)((BYTE*)hModCaller+pImportDesc->Name); if(stricmp(pszDllName,pszExportMod)==0)//如果找到pszExportMod模块,相当于hookmessageboxa时的“user32.dll” { bFindDll=TRUE; break; } pImportDesc++; } if(bFindDll) { DWORDn=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("functionname:%-25s, ",pszFuncName); //取得函数地址 PDWORDlpAddr=(DWORD*)((BYTE*)hModCaller+pImportDesc->FirstThunk)+n;//从第一个函数的地址,以后每次+4字节 //printf("addrss:%X\n",lpAddr); //在这里是比较的函数地址 if(*lpAddr==(DWORD)pfnCurrent) //找到iat中的函数地址 { DWORD*lpNewProc=(DWORD*)pfnNewFunc; MEMORY_BASIC_INFORMATIONmbi; DWORDdwOldProtect; //修改内存页的保护属性 ::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 } } } voidCAPIHOOK::ReplaceIATEntryInAllMods(LPCTSTRpszExportMod,PROCpfnCurrent,PROCpfnNewFunc,BOOLbExcludeAPIHookMod) { //取得当前模块句柄 HMODULEhModThis=NULL; if(bExcludeAPIHookMod) { MEMORY_BASIC_INFORMATIONmbi; if(0!=::VirtualQuery(ReplaceIATEntryInAllMods,&mbi,sizeof(MEMORY_BASIC_INFORMATION)))//ReplaceIATEntryInAllMods必须为类的static函数 { hModThis=(HMODULE)mbi.AllocationBase; } } //取得本进程的模块列表 HANDLEhModuleSnap=INVALID_HANDLE_VALUE; MODULEENTRY32me32; 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);//配对写 } //防止自动加载 HMODULEWINAPICAPIHOOK::LoadLibraryA(LPCTSTRlpFileName) { HMODULEhModule=LoadLibraryA(lpFileName); HookNewlyLoadedModule(hModule,0);//这个函数中忆检测hModule了 returnhModule; } HMODULEWINAPICAPIHOOK::LoadLibraryW(LPCTSTRlpFileName) { HMODULEhModule=LoadLibraryW(lpFileName); HookNewlyLoadedModule(hModule,0);//这个函数中忆检测hModule了 returnhModule; } HMODULEWINAPICAPIHOOK::LoadLibraryExA(LPCTSTRlpFileName,HANDLEhFile, DWORDdwFlags) { HMODULEhModule=LoadLibraryExA(lpFileName,hFile,dwFlags); HookNewlyLoadedModule(hModule,dwFlags);//这个函数中忆检测hModule了 returnhModule; } HMODULEWINAPICAPIHOOK::LoadLibraryExW(LPCTSTRlpFileName,HANDLEhFile, DWORDdwFlags) { HMODULEhModule=LoadLibraryExW(lpFileName,hFile,dwFlags); HookNewlyLoadedModule(hModule,dwFlags);//这个函数中忆检测hModule了 returnhModule; }