1. 程式人生 > 實用技巧 >《逆向工程核心原理》——IAThook

《逆向工程核心原理》——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……