您的位置:首页 > 其它

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 的程序为例,代码如下

#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  PE IAT 操作系统