本文實例講述了C++封裝IATHOOK類的實現方法。分享給大家供大家參考。具體方法如下:
1. 定義成類的靜態成員,從而實現自動調用
2. ReplaceIATEntryInAllMods中遍歷模塊的框架
3. 遍歷鏈表摘除自己的框架
4. 在cpp中靜態變量寫好后,再編譯,不然容易出現LINK錯誤
源碼:
.cpp源文件如下:
//防止程序運行期間動態調用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頭文件如下:
希望本文所述對大家的C++程序設計有所幫助。
新聞熱點
疑難解答
圖片精選