IAT HOOK 簡單實現
阿新 • • 發佈:2020-07-26
注意的事項:
1、操作部分在IAT表中
2、HOOK函式中需要用函式指標接收,因為此時IAT已經被HOOK,如果直接return 原函式
,其實會造成棧溢位,因為此時的原函式已經被HOOK了,會造成類似的遞迴操作
3、最後HOOK完,需要進行 解除安裝HOOK 操作
4、如果debug的時候發現IAT表中是能寫進去的,但是發現寫入異常,則可能跟物理頁的屬性有關,需要進行VirtualProtect設定
#include<Windows.h> #include<cstdio> DWORD dwMessagebox = (DWORD)GetProcAddress(LoadLibrary("user32.dll"), "MessageBoxA"); int WINAPI MyMessageBox(_In_opt_ HWND hWnd, _In_opt_ LPCSTR lpText, _In_opt_ LPCSTR lpCaption, _In_ UINT uType){ typedef int(WINAPI *PMyMessageBox)(_In_opt_ HWND hWnd, _In_opt_ LPCSTR lpText, _In_opt_ LPCSTR lpCaption, _In_ UINT uType); printf("Hook Messagebox Param: hWnd: %x, lpText: %s, lpCation: %s, uType: %x", hWnd, lpText, lpCaption, uType); PMyMessageBox MyMessageBox = (PMyMessageBox)dwMessagebox; return MyMessageBox(0, TEXT("It's My Hook Messagebox!"), 0, 0); } void InstallIatHook(DWORD dwOldFunction, DWORD dwNewFunction) { HMODULE hModule = GetModuleHandle(NULL); // load pe PIMAGE_DOS_HEADER pDosHeader = NULL; PIMAGE_NT_HEADERS pNTHeader = NULL; PIMAGE_FILE_HEADER pPEHeader = NULL; PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL; PIMAGE_SECTION_HEADER pSectionHeader = NULL; PIMAGE_IMPORT_DESCRIPTOR pIMPORT_DESCRIPTOR = NULL; PIMAGE_IMPORT_BY_NAME pImage_IMPORT_BY_NAME = NULL; PDWORD OriginalFirstThunk = NULL; PDWORD FirstThunk = NULL; PIMAGE_THUNK_DATA pImageThunkData = NULL; DWORD Original = 0; pDosHeader = (PIMAGE_DOS_HEADER)hModule; pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)hModule + pDosHeader->e_lfanew); pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader) + 4); pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER); pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + sizeof(IMAGE_OPTIONAL_HEADER32)); pIMPORT_DESCRIPTOR = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)hModule + pOptionHeader->DataDirectory[1].VirtualAddress); DWORD dwOldProtect; // 記憶體頁屬性 BOOL bFlag = TRUE; //這裡可以進行while操作,這裡while的判斷依據為pIMPORT_DESCRIPTOR個數 while (pIMPORT_DESCRIPTOR->FirstThunk && bFlag) { FirstThunk = (PDWORD)((DWORD)hModule + (DWORD)pIMPORT_DESCRIPTOR->FirstThunk); while (*FirstThunk) { if (*FirstThunk == dwOldFunction) { VirtualProtect((LPVOID)FirstThunk, 0x4, PAGE_READWRITE, &dwOldProtect); *FirstThunk = dwNewFunction; bFlag = FALSE; break; } FirstThunk++; } // 進行遍歷操作 pIMPORT_DESCRIPTOR++; } } void UninstallIatHook(DWORD dwOldFunction, DWORD dwNewFunction) { HMODULE hModule = GetModuleHandle(NULL); // load pe PIMAGE_DOS_HEADER pDosHeader = NULL; PIMAGE_NT_HEADERS pNTHeader = NULL; PIMAGE_FILE_HEADER pPEHeader = NULL; PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL; PIMAGE_SECTION_HEADER pSectionHeader = NULL; PIMAGE_IMPORT_DESCRIPTOR pIMPORT_DESCRIPTOR = NULL; PIMAGE_IMPORT_BY_NAME pImage_IMPORT_BY_NAME = NULL; PDWORD OriginalFirstThunk = NULL; PDWORD FirstThunk = NULL; PIMAGE_THUNK_DATA pImageThunkData = NULL; DWORD Original = 0; pDosHeader = (PIMAGE_DOS_HEADER)hModule; pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)hModule + pDosHeader->e_lfanew); pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader) + 4); pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER); pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + sizeof(IMAGE_OPTIONAL_HEADER32)); pIMPORT_DESCRIPTOR = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)hModule + pOptionHeader->DataDirectory[1].VirtualAddress); BOOL bFlag = TRUE; //這裡可以進行while操作,這裡while的判斷依據為pIMPORT_DESCRIPTOR個數 while (pIMPORT_DESCRIPTOR->FirstThunk && bFlag) { FirstThunk = (PDWORD)((DWORD)hModule + (DWORD)pIMPORT_DESCRIPTOR->FirstThunk); while (*FirstThunk) { if (*FirstThunk == dwOldFunction) { *FirstThunk = dwNewFunction; bFlag = FALSE; break; } FirstThunk++; } // 進行遍歷操作 pIMPORT_DESCRIPTOR++; } } int main(int argc, char* argv[]){ InstallIatHook(dwMessagebox, (DWORD)MyMessageBox); MessageBox(0, 0, 0, 0); UninstallIatHook((DWORD)MyMessageBox, dwMessagebox); MessageBox(0, 0, 0, 0); return 0; }