《逆向工程核心原理》——IAThook
hook逻辑写入dll中,注入dll。
#include "pch.h" #include <tchar.h> #include "windows.h" //WINBASEAPI //BOOL //WINAPI //WriteFile( // _In_ HANDLE hFile, // _In_reads_bytes_opt_(nNumberOfBytesToWrite) LPCVOID lpBuffer, // _In_ DWORD nNumberOfBytesToWrite, // _Out_opt_ LPDWORD lpNumberOfBytesWritten, // _Inout_opt_ LPOVERLAPPED lpOverlapped //); typedef BOOL(WINAPI* PFWRITEFILE)(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped); FARPROC g_pOrgFunc = NULL;//全局变量 BOOL hook_iat(LPCSTR szDllName, PROC pfnOrg, PROC pfnNew)//负责勾取IAT { LPCSTR szLibName; PIMAGE_IMPORT_DESCRIPTOR pImportDesc; PIMAGE_THUNK_DATA64 pThunk; DWORD dwOldProtect; DWORD dwRVA; PBYTE pAddr;//8字节 pAddr = (PBYTE)GetModuleHandle(NULL);//pAddr = ImageBase;获得内存中装载的地址 PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pAddr;//指向dos头 PIMAGE_NT_HEADERS64 pNT = (PIMAGE_NT_HEADERS64)(pAddr + pDosHeader->e_lfanew);//指向pe头 dwRVA = pNT->OptionalHeader.DataDirectory[1].VirtualAddress;//pe头--》可选头--》数据目录--》第2项 输入表;取得输入表rva pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)(pAddr + dwRVA);//输入表的内存地址 for (; pImportDesc->Name; pImportDesc++)//循环遍历IDT;(IMAGE_IMPORT_DESCRIPTOR数组) { szLibName = (LPCSTR)(pAddr + pImportDesc->Name);// szLibName = VA to IMAGE_IMPORT_DESCRIPTOR.Name if (!_stricmp(szLibName, szDllName))//找到对应dll名的IID;(IMAGE_IMPORT_DESCRIPTOR) { // pThunk = IMAGE_IMPORT_DESCRIPTOR.FirstThunk // = VA to IAT(Import Address Table) pThunk = (PIMAGE_THUNK_DATA64)(pAddr + pImportDesc->FirstThunk);//系统装载结束后,FirstThunk指向IAT, pThunk就是IAT for (; pThunk->u1.Function; pThunk++)// pThunk->u1.Function = VA to API 遍历IAT { if (pThunk->u1.Function == (ULONGLONG)pfnOrg)//查找要hook函数的地址 { VirtualProtect((LPVOID)&pThunk->u1.Function, 8, PAGE_EXECUTE_READWRITE, &dwOldProtect); pThunk->u1.Function = (ULONGLONG)pfnNew;//修改IAT的值 VirtualProtect((LPVOID)&pThunk->u1.Function, 8, dwOldProtect, &dwOldProtect); return TRUE; } } } } return FALSE; } BOOL WINAPI MyFunc(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped) { char* pc = (char*)lpBuffer; //小写转大写-0x20 while (*pc) { if (*pc >= 'a' && *pc <= 'z') *pc -= 0x20; pc++; } return ((PFWRITEFILE)g_pOrgFunc)(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped);//调用原WriteFile } BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: g_pOrgFunc = GetProcAddress(GetModuleHandle(_T("kernel32.dll")), "WriteFile");//保存原始API地址 hook_iat("kernel32.dll", g_pOrgFunc, (PROC)MyFunc);//使用hookiat!MySetWindowText()勾取kernel32.dll中的WriteFile函数 break; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: break; case DLL_PROCESS_DETACH: hook_iat("kernel32.dll", (PROC)MyFunc, g_pOrgFunc);//unhook,恢复IAT原来的值 break; } return TRUE; }
64位和32位pe有些结构大小不同,IMAGE_NT_HEADERS64;IMAGE_OPTIONAL_HEADER64;IMAGE_THUNK_DATA64……