抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

IAT Hook

  • IMAGE_IMPORT_DESCRIPTOR中两个IMAGE_THUNK_DATA结构体,第一个位导入名称表(INT),第二个位导入地址表(IAT)。两个结构在磁盘文件中时是没有差别的,但是当PE文件被装载到内存中后,FirstThunk字段指向的IMAGE_THUNK_DATA的值会被Windows进行填充。该值为一个RVA,该RVA加上映像基址后,虚拟地址就保存了真正的导入函数的入口地址
  • IAT Hook步骤
    1. 获取欲Hook的函数地址
    2. 找到该函数的所保存的IAT地址
    3. 把IAT中该函数的地址修改为Hook函数的地址

遍历64位IAT函数名和地址

遍历64位IAT函数名和地址

  • GetModuleHandle:参数只有1个,是目标模块名,此处填NULL表示当前进程,返回的是一个进程句柄,也就是当前进程的首地址

  • 区别:
    • 64位程序的基地址是Unsigned Long Long类型,用DWORD64表示
    • 运行中的程序,IAT里记录的是VA而不是RVA
    • 运行中的程序,INT里记录的是RVA而不是VA

代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>
#include <Windows.h>

int main()
{
// 获取当前程序的首地址
HMODULE hModuel = GetModuleHandle(NULL);
// 定位DOS头
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)hModule;
// 定位NT头
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((DWORD64)hModule + pDosHeader->e_lfanew);
// 获取导入表RVA
DWORD64 dwImportRVA = pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
// 定位导入表
PIMAGE_IMPORT_DESCRIPTOR pImport = (PIMAGE_IMPORT_DESCRIPTOR)(dwImportRVA + (DWORD64)hModule);
while(pImport->Name)
{
const char* szDllName = (char*)((DWORD64)hModule + pImport->Name);
printf("%s\n", szDllName);
PIMAGE_THUNK_DATA pIAT = (PIMAGE_THUNK_DATA)((DWORD64)hModule + pImport->FirstThunk);
PIMAGE_THUNK_DATA pINT = (PIMAGE_THUNK_DATA)((DWORD64)hModule + pImport->OriginalFirstThunk);
if(pIAT->u1.Oridianl != 0)
{
while(pIAT->u1.Function)

PIMAGE_IMPORT_BY_NAME pFuncName = (PIMAGE_IMPORT_BY_NAME)((DWORD64)hModule + pINT->AddressOfData);
PDWORD64 dwFuncAddr = (PDWORD64)(pIAT->Function);
printf("函数名称:%-50s", pFuncName);
printf("函数地址:%p\n", dwFuncAddr);
pINT++;
pIAT++;
}
}
pImport++;

}
}

Hook CreateFileW

代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#include <Windows.h>

HANDLE
WINAPI
MyCreateFileW(
_In_ LPCWSTR lpFileName,
_In_ DWORD dwDesiredAccess,
_In_ DWORD dwShareMode,
_In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes,
_In_ DWORD dwCreationDisposition,
_In_ DWORD dwFlagsAndAttributes,
_In_opt_ HANDLE hTemplateFile
)
{
if(MessageBox(NULL, L"打开文件操作被拦截", L"提示", MB_YESNO) == IDYES)
{
return CreateFileW(
lpFileName,
dwDesiredAccess,
dwShareMode,
lpSecurityAttributes,
dwCreationDisposition,
dwFlagsAndAttributes,
hTemplateFile
);
}
else
{
MessageBox(NULL, L"文件打开失败", L"警告", NULL);
return FALSE;
}
}

BOOL IATHook(LPCWSTR lpModuleName, const char* szFuncName)
{
DWORD64 dwFuncAddr = (DWROD64)GetProcAddress(GetModuleHandle(lpModuleName), szFuncName);
// 获取程序基址
HMODULE hModule = GetModuleHandle(NULL);
// 定位DOS头
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)hModule;
// 定位NT头
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((DWORD64)hModule + pDosHeader->e_lfanew);
// 获取导入表RVA
DWORD64 dwImportRVA = pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
// 定位导入表
PIMAGE_IMPORT_DESCRIPTOR pImport = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD64)hModule + dwImportRVA);
while(pImport->Nmae)
{
const char* szDllName = (char*)((DWORD64)hModule + pImport->Name);
char szName[MAXBYTE] = { 0 };
strcpy_s(szName, szDllName)
if(strcmp(_strlwr(szName), "kernel32.dll") == 0)
{
PIMAGE_THUNK_DATA pThunk = (PIMAGE_THUNK_DATA)((DWORD64)hModule + pImport->FirstThunk);
while(pThunk->Function)
{
if(pThunk->Function == dwFuncAddr)
{
DWORD64 dwOldProtect;
VirtualProtectEx(GetCurrentProcess(), (LPVOID)&pThunk->Function, 8, PAGE_EXECUTE_READWRITE, &dwOldProtect);
pThunk->Function = (DWORD64)MyCreateFileW;
break;
}
pThunk++;
}
break;
}
pImport++;
}
}

BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
IATHook(L"kernel32.dll", L"CreateFileW");
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

评论