IAT-Hook 劫持进程Api调用
?ω?
劫持API的各種Hook方式的時候,IAT-Hook應(yīng)該算是最簡單的一個。比IAT-Hook更難的是R3的5字節(jié)Hook,然后是熱補丁Hook,SSDT-Hook…
5字節(jié)Hook在前兩篇進程隱藏中用過了,7字節(jié)主要是對API的要求比較高,這篇就更新IAT-Hook的實現(xiàn)代碼,后續(xù)再更新復(fù)制原始API部分代碼的熱補丁Hook和SSDT-Hook
T_T
本來昨晚打算花個40分鐘左右搞定的,結(jié)果出了各種奇怪的問題,調(diào)試到2點搞定!結(jié)果宿舍還有1/3的人還沒睡…當代大學(xué)生日常???
Tips & Problems
1.原理很簡單啊,把DLL注入到想Hook的進程(進程隱藏有注入器代碼),然后DLL在進程空間找到程序進程句柄,句柄指向的就是MZ頭的指針,然后就可以通過各種結(jié)構(gòu)體操作找到輸入表,找到IID結(jié)構(gòu)體,找到需要修改的IAT,然后把它改掉~~OVER!!,再具體一些,IAT-Hook的原理就是程序call func的實現(xiàn)是call [func所在的IAT],對這個iat取地址值然后call,這個地址值是PE Loader在PE裝載的時候動態(tài)獲取的。
2.遇到的第一個問題是編譯器的優(yōu)化問題,為了偷懶我沒用DLL注入工具注入DLL而是編寫了一個程序直接LoadLibrary,然后再彈窗,DLL負責(zé)劫持MessageBoxW函數(shù),但是怎么都劫持不了…后來一步步調(diào)試發(fā)現(xiàn)編譯器把調(diào)用MessageBoxW函數(shù)寫成 call esi,然后esi=[MessageBoxW的iat地址],但是Loadlibrary在esi=[MessageBoxW的iat地址]之后,也就是說不管怎么修改call esi最終都會調(diào)用原本的MessageBoxW…
3.字符串比較函數(shù)strcmp(char *,char *)結(jié)果只比了一個字符…我記得這個函數(shù)應(yīng)該是不到’\0’不返回的啊…花了5s,手擼一個字符串比較函數(shù)
4.Hook原函數(shù)到新函數(shù)的時候一定要注意處理好堆棧平衡問題
5.因為基本MZ頭結(jié)構(gòu)PE頭結(jié)構(gòu)中的關(guān)鍵值都是RVA,直接加上進程句柄就得到VA了,真的超級方便
6.因為DLL沒有需要卸載的需要,一般注入的DLL被卸載進程也退出了,所以沒啥必要寫UnHook函數(shù)
下面是代碼
IAT.h
#include "windows.h"HMODULE Current_Handle; //進程句柄 PBYTE pfile; //指向MZ PIMAGE_DOS_HEADER Dos_Header; //Dos頭 PIMAGE_NT_HEADERS Nt_Header; //NT頭 DWORD IATSection_Base; //IAT所在段基址 DWORD IATSection_Size; //IAT所在段大小BOOL str_cmp(char *a,char *b);void PeInit();BOOL IatHook(LPCSTR DllName,LPCSTR ProcName);int WINAPI NewMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType);IAT.cpp
#include "IAT.h"BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {switch (fdwReason) {case DLL_PROCESS_ATTACH:Current_Handle = NULL;pfile = NULL;Dos_Header = NULL;Nt_Header = NULL;IATSection_Base = 0;IATSection_Size = 0;PeInit();IatHook("USER32.dll","MessageBoxW");break;case DLL_PROCESS_DETACH:break;}return TRUE; }BOOL str_cmp(char *a,char *b){while(*a==*b && *a!='\0' && *b!='\0'){a++;b++;}if(*a=='\0' && *b=='\0') return true;return false; }int WINAPI NewMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType) {return MessageBoxW(NULL,L"123",L"123", NULL); }BOOL IatHook(LPCSTR DllName,LPCSTR ProcName) {DWORD oldprotect = 0;FARPROC ori_func = GetProcAddress(GetModuleHandleA(DllName), ProcName);PIMAGE_THUNK_DATA pthunk=NULL;PIMAGE_IMPORT_DESCRIPTOR Current_IID = (PIMAGE_IMPORT_DESCRIPTOR)(pfile + IATSection_Base);while (Current_IID) {if (str_cmp((char *)DllName,(char *)(pfile + Current_IID->Name))) {pthunk = (PIMAGE_THUNK_DATA)(pfile+Current_IID->FirstThunk);while (pthunk->u1.Function) {if (pthunk->u1.Function == (DWORD)ori_func) {VirtualProtect((LPVOID)&pthunk->u1.Function, 4, PAGE_EXECUTE_READWRITE, &oldprotect);pthunk->u1.Function = (DWORD)NewMessageBoxW;VirtualProtect((LPVOID)&pthunk->u1.Function, 4, oldprotect, &oldprotect);break;}pthunk++;}return true;}Current_IID++;}return false; }void PeInit() {Current_Handle = GetModuleHandle(NULL); pfile = (PBYTE)Current_Handle;Dos_Header = (PIMAGE_DOS_HEADER)pfile;if (Dos_Header->e_magic != IMAGE_DOS_SIGNATURE){OutputDebugString(L"Is Not PE");return;}Nt_Header = (PIMAGE_NT_HEADERS)(pfile + Dos_Header->e_lfanew);if (Nt_Header->Signature != IMAGE_NT_SIGNATURE) {OutputDebugString(L"Is Not PE");return;}IMAGE_DATA_DIRECTORY IAT_Section = (IMAGE_DATA_DIRECTORY)(Nt_Header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]);IATSection_Base = IAT_Section.VirtualAddress;IATSection_Size = IAT_Section.Size; }總結(jié)
以上是生活随笔為你收集整理的IAT-Hook 劫持进程Api调用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 阈值分割方法总结
- 下一篇: otsu阈值分割算法原理_otsu(大津