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; }