IAT挂钩实现和检测
2017-08-28 16:04
148 查看
IAT - Import Address Table ,导入地址列表。这里保存着各个导入的函数加载后的地址,它是动态的,随着Dll的加载的位置不同而不同。
PE - Portable Execute 可执行的程序结构。在PE结构中有个数据目录(Data Directory) 内部保存导入表的数据。格式大概如下:
dll-数据 1
函数数据1
函数数据2
函数数据3
…
dll-数据 2
…
我们根据PE的格式找到函数的已经定位的位置,然后修改这个位置,就能用自己的函数替换这个函数。(再此之前保留好原来的函数)
下面以win32 的程序为例,代码如下
PE - Portable Execute 可执行的程序结构。在PE结构中有个数据目录(Data Directory) 内部保存导入表的数据。格式大概如下:
dll-数据 1
函数数据1
函数数据2
函数数据3
…
dll-数据 2
…
我们根据PE的格式找到函数的已经定位的位置,然后修改这个位置,就能用自己的函数替换这个函数。(再此之前保留好原来的函数)
下面以win32 的程序为例,代码如下
#include <windows.h> #include <stdio.h> void* test() { void* a = MessageBoxA; return a; } VOID* g_lpMsgBox = NULL; typedef int(WINAPI *LpMsgBox)(HWND wnd, char* msg, char* title, UINT btn); int WINAPI MyMessageBox(HWND wnd, char* msg, char* title, UINT btn) { char buf[256] = {0}; strcpy(buf, msg); strcat(buf, "+mybox"); ((LpMsgBox)g_lpMsgBox)(wnd, buf, title, btn); return 0; } BOOL checkIATHook() { PIMAGE_DOS_HEADER dos_header = GetModuleHandle(NULL); PIMAGE_NT_HEADERS nt_headers = (LPBYTE)dos_header + dos_header->e_lfanew; DWORD import_rva = nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress; LPBYTE import_va = (LPBYTE)dos_header + import_rva; PIMAGE_IMPORT_DESCRIPTOR imp_desc = import_va; while (1){ if (imp_desc->Name) { char* name = (LPBYTE)dos_header + imp_desc->Name; HMODULE imp_dll = GetModuleHandleA(name); PIMAGE_THUNK_DATA thunk = (LPBYTE)dos_header + imp_desc->FirstThunk; PIMAGE_THUNK_DATA thunk1 = (LPBYTE)dos_header + imp_desc->OriginalFirstThunk; for (;;) { if (thunk->u1.ForwarderString == 0) { break; } //序号导入 if (thunk->u1.ForwarderString & IMAGE_ORDINAL_FLAG) { // __asm nop; } else { //名称导入 PIMAGE_IMPORT_BY_NAME fnName = (LPBYTE)dos_header + thunk1->u1.AddressOfData; DWORD proc_addr = GetProcAddress(imp_dll, fnName->Name); if (thunk->u1.Function != proc_addr) { printf("%s be hooked : 0x%x\n", fnName->Name, thunk->u1.Function); } __asm nop; } thunk += 1; thunk1 += 1; } imp_desc += 1; } else { break; } } return TRUE; } void hookMessageBoxA() { PIMAGE_DOS_HEADER dos_header = GetModuleHandle(NULL); PIMAGE_NT_HEADERS nt_headers = (LPBYTE)dos_header + dos_header->e_lfanew; DWORD import_rva = nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress; LPBYTE import_va = (LPBYTE)dos_header + import_rva; PIMAGE_IMPORT_DESCRIPTOR imp_desc = import_va; while (1){ if (imp_desc->Name) { char* name = (LPBYTE)dos_header + imp_desc->Name; if (stricmp(name, "user32.dll") == 0) { PIMAGE_THUNK_DATA thunk = (LPBYTE)dos_header + imp_desc->FirstThunk; PIMAGE_THUNK_DATA thunk1 = (LPBYTE)dos_header + imp_desc->OriginalFirstThunk; for (;;) { if (thunk->u1.ForwarderString == 0) { break; } if (thunk->u1.ForwarderString&IMAGE_ORDINAL_FLAG) { // __asm nop; } else { PIMAGE_IMPORT_BY_NAME fnName = (LPBYTE)dos_header + thunk1->u1.AddressOfData; if (strcmp(fnName->Name, "MessageBoxA")==0) { g_lpMsgBox = thunk->u1.Function; DWORD prFlag; BOOL b = VirtualProtect(&imp_desc->FirstThunk, 4, PAGE_EXECUTE_READWRITE, &prFlag); if (b) { *(DWORD*)thunk = MyMessageBox; } VirtualProtect(&imp_desc->FirstThunk, 4, prFlag, &prFlag); } return; __asm nop; } thunk += 1; } } imp_desc += 1; } else { break; } } } int main(int argc, char** argv) { test(); hookMessageBoxA(); checkIATHook(); MessageBoxA(NULL, "msg", "haha", MB_OK); return 0; }
相关文章推荐
- NAT检测实现方法
- Android实现检测耳机插入和拔出
- tensorflow 轻松实现自己的目标检测
- 技术转载:游戏里实现碰撞检测方法
- iOS程序自动检测更新的实现
- vc ++ 实现检测变速齿轮,变速精灵, 变速类辅助工具
- 遗留物检测算法及实现
- 检测实现OpenCV2.4.4实现Shi-Tomasi角点检测(goodFeaturesToTrack)
- 目标检测学习(用opencv自带hog实现行人检测)
- Sobel算子边缘检测Matlab实现(转)
- 利用hog+svm(梯度方向直方图和支持向量机)实现物体检测
- opencv 实现对摄像头输入图像中文件及证件等的实时跟踪,四边形检测及提取
- JS和css实现检测移动设备方向的变化并判断横竖屏幕
- J2ME中的自己实现碰撞检测
- PHP+AJAX实现无刷新注册(带用户名实时检测)
- 基于Spark技术实现大规模时间序列异常检测成功落地
- openCV实现多人脸检测,多眼部检测,完整代码和详细注释
- OpenCV实现人脸检测
- 轻松实现APP自动检测更新
- 使用GestureDetector实现手指左右滑动检测