0x01 HOOK函数的编写
有一定的格式要求
直接直接hook MessageBoxA
函数格式
int WINAPI NewMessageBox( HWND hWnd, // handle to owner window LPCTSTR lpText, // text in message box LPCTSTR lpCaption, // message box title UINT uType // message box style ) { //拿到原来的MessageBox typedef int (WINAPI *pfMessageBox)(HWND, LPCTSTR, LPCTSTR, UINT); pfMessageBox myMessageBox = NULL; myMessageBox = (pfMessageBox)GetProcAddress(LoadLibrary("User32.DLL"),"MessageBoxA"); //监测数据 OutputDebugStringF("hWnd:%08X,lpText:%s,lpCaption:%s,uType:%d ",hWnd,lpText,lpCaption,uType); //继续执行MessageBox myMessageBox(hWnd,"www.gyarmy.com","流沙",uType); myMessageBox(hWnd,lpText,lpCaption,uType); return 0; }
0x02 IAT表的遍历
由于导入表的复杂性, 每次遍历导入表,我都是到处找资料, 导入表, 有一个INT表和一个IAT表, 每次使用,都需要看看一张图
这里主要用来配合理解导入表的结构
需要理解PE的运行载入过程
IAT表是载入PE后进行修复得到的, 我们直接修改 IAT表中的数据即可
代码如下;
BOOL ImportDirectoryHOOK(DWORD imagebase,DWORD pOldAddr,DWORD pNewAddr) { 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_SECTION_HEADER pSectionHeader_ADD = NULL; PIMAGE_DATA_DIRECTORY pDataDirectory = NULL; //Header信息 pDosHeader = (PIMAGE_DOS_HEADER)imagebase; pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)imagebase+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+pPEHeader->SizeOfOptionalHeader); pDataDirectory = pOptionHeader->DataDirectory; //确定导入表 IMAGE_DATA_DIRECTORY pImportDirectory = pDataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]; DWORD ImportVirtualAddress = pImportDirectory.VirtualAddress; PIMAGE_IMPORT_DESCRIPTOR pImp = NULL; pImp = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)imagebase + ImportVirtualAddress); PIMAGE_THUNK_DATA pOrgThunk, pFirstThunk; //遍历IAT表 while (NULL != pImp->FirstThunk) { pImp->Name += imagebase; OutputDebugStringF("DLL: %s", pImp->Name); //FARPROC fpFun; HINSTANCE hInstance = LoadLibraryA((LPCSTR)pImp->Name); if (NULL == hInstance) { OutputDebugStringF("Load library %s failed, error: %d\n", pImp->Name, GetLastError()); return FALSE; } pOrgThunk = (PIMAGE_THUNK_DATA)(imagebase + pImp->OriginalFirstThunk); pFirstThunk = (PIMAGE_THUNK_DATA)(imagebase + pImp->FirstThunk); while (NULL != *(DWORD *)pFirstThunk) { if(pOldAddr == *((PDWORD)pFirstThunk)) { OutputDebugStringF("11111111111"); *((PDWORD)pFirstThunk)= pNewAddr; break; } ++pFirstThunk; ++pOrgThunk; } FreeLibrary(hInstance); ++pImp; } return TRUE; }
0x03 最后贴上主程序的代码,关键在于思路的理解!
// 20180202_05.cpp : Defines the entry point for the application.
// #include "stdafx.h" #include "PEOperate.h" #include "DebugTool.h" #include <windows.h> #include <stdio.h> BOOL ImportDirectoryHOOK(DWORD imagebase,DWORD pOldAddr,DWORD pNewAddr) { 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_SECTION_HEADER pSectionHeader_ADD = NULL; PIMAGE_DATA_DIRECTORY pDataDirectory = NULL; //Header信息 pDosHeader = (PIMAGE_DOS_HEADER)imagebase; pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)imagebase+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+pPEHeader->SizeOfOptionalHeader); pDataDirectory = pOptionHeader->DataDirectory; //确定导入表 IMAGE_DATA_DIRECTORY pImportDirectory = pDataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]; DWORD ImportVirtualAddress = pImportDirectory.VirtualAddress; PIMAGE_IMPORT_DESCRIPTOR pImp = NULL; pImp = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)imagebase + ImportVirtualAddress); PIMAGE_THUNK_DATA pOrgThunk, pFirstThunk; //遍历IAT表 while (NULL != pImp->FirstThunk) { pImp->Name += imagebase; OutputDebugStringF("DLL: %s", pImp->Name); //FARPROC fpFun; HINSTANCE hInstance = LoadLibraryA((LPCSTR)pImp->Name); if (NULL == hInstance) { OutputDebugStringF("Load library %s failed, error: %d\n", pImp->Name, GetLastError()); return FALSE; } pOrgThunk = (PIMAGE_THUNK_DATA)(imagebase + pImp->OriginalFirstThunk); pFirstThunk = (PIMAGE_THUNK_DATA)(imagebase + pImp->FirstThunk); while (NULL != *(DWORD *)pFirstThunk) { if(pOldAddr == *((PDWORD)pFirstThunk)) { OutputDebugStringF("11111111111"); *((PDWORD)pFirstThunk)= pNewAddr; break; } ++pFirstThunk; ++pOrgThunk; } FreeLibrary(hInstance); ++pImp; } return TRUE; } int WINAPI NewMessageBox( HWND hWnd, // handle to owner window LPCTSTR lpText, // text in message box LPCTSTR lpCaption, // message box title UINT uType // message box style ) { //拿到原来的MessageBox typedef int (WINAPI *pfMessageBox)(HWND, LPCTSTR, LPCTSTR, UINT); pfMessageBox myMessageBox = NULL; myMessageBox = (pfMessageBox)GetProcAddress(LoadLibrary("User32.DLL"),"MessageBoxA"); //监测数据 OutputDebugStringF("hWnd:%08X,lpText:%s,lpCaption:%s,uType:%d ",hWnd,lpText,lpCaption,uType); //继续执行MessageBox myMessageBox(hWnd,"www.gyarmy.com","流沙",uType); myMessageBox(hWnd,lpText,lpCaption,uType); return 0; } VOID TestIATHook() { //定位MessageBox typedef int (WINAPI *pfMessageBox)(HWND, LPCTSTR, LPCTSTR, UINT); pfMessageBox myMessageBox = NULL; myMessageBox = (pfMessageBox)GetProcAddress(LoadLibrary("User32.DLL"),"MessageBoxA"); OutputDebugStringF("myMessageBox: %08X",myMessageBox); //myMessageBox(0,"111","222",MB_OK); DWORD pOldArr = (DWORD)myMessageBox; //定位导入表 HMODULE hModule = GetModuleHandle(NULL); DWORD ImageBase = (DWORD)hModule; DWORD pNewAddr = (DWORD)NewMessageBox; //对IAT表进行HOOK ImportDirectoryHOOK(ImageBase,pOldArr,pNewAddr); } int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { // TODO: Place code here. TestIATHook(); MessageBox(0,0,0,0); return 0; }
项目源代码下载地址:
0则评论给“IATHOOK详细讲解”