需要注意的是:因为IAT具体指某个PE模块的IAT,所以他的作用范围只针对被Hook的模块,且必须在以静态链接的方式调用API时才会被Hook,所以它的作用范围只针对被Hook的模块,且必须以静态链接的方式调用API时才会被Hook(比如你要HOOK“messagebox”,那么这个函数必须在模块里面被使用过,才能Hook成功),在使用Loadlibrary或GetProcAddress进行动态调用时不受影响。要想对已加载的所有模块起作用,就必须遍历进程内的所有模块,对目标API进行Hook。
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"
#include <Windows.h>
#include <stdio.h>
typedef int (WINAPI* oldMessageBoxA)(
_In_opt_ HWND hWnd,
_In_opt_ LPCSTR lpText,
_In_opt_ LPCSTR lpCaption,
_In_ UINT uType);
oldMessageBoxA oldFun = NULL;
int WINAPI MyMessageBoxA(
_In_opt_ HWND hWnd,
_In_opt_ LPCSTR lpText,
_In_opt_ LPCSTR lpCaption,
_In_ UINT uType)
{
return oldFun(hWnd,"HOOK成功","HOOK成功", uType);
}
BOOL IATHook(const char* MoudleName, const char* FunName)
{
oldFun = (oldMessageBoxA)GetProcAddress(GetModuleHandleA(MoudleName), FunName);//源函数地址
if (!oldFun)
{
return FALSE;
}
HMODULE mMoudle = GetModuleHandle(NULL);//获取了主模块的起始地址
PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)mMoudle;//获取Dos头
PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)((DWORD)mMoudle + pDos->e_lfanew);//获取NT头
PIMAGE_OPTIONAL_HEADER pOh = (PIMAGE_OPTIONAL_HEADER)&(pNt->OptionalHeader);//获取可选头
DWORD ImportRVA = pOh->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;//第一张导入表的RVA
PIMAGE_IMPORT_DESCRIPTOR pId = (PIMAGE_IMPORT_DESCRIPTOR)(ImportRVA + (DWORD)mMoudle);//获取第一张导入表
for (; pId->Name; pId++)
{
PIMAGE_THUNK_DATA pTD = (PIMAGE_THUNK_DATA)(pId->FirstThunk + (DWORD)mMoudle);//获取Thunk数组
for (; pTD->u1.Function; pTD++)
{
if (pTD->u1.Function == (DWORD)oldFun)
{
DWORD oldProtect = 0;
VirtualProtect(pTD, 4, PAGE_EXECUTE_READWRITE, &oldProtect);
pTD->u1.Function = (DWORD)MyMessageBoxA;
VirtualProtect(pTD, 4, oldProtect, &oldProtect);
return TRUE;
}
}
}
return FALSE;
}
BOOL unHook()
{
HMODULE mMoudle = GetModuleHandle(NULL);
PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)mMoudle;
PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)((DWORD)mMoudle + pDos->e_lfanew);
PIMAGE_OPTIONAL_HEADER pOh = (PIMAGE_OPTIONAL_HEADER) & (pNt->OptionalHeader);
DWORD ImportRVA = pOh->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
PIMAGE_IMPORT_DESCRIPTOR pId = (PIMAGE_IMPORT_DESCRIPTOR)(ImportRVA + (DWORD)mMoudle);
for (; pId->Name; pId++)
{
PIMAGE_THUNK_DATA pTD = (PIMAGE_THUNK_DATA)(pId->FirstThunk + (DWORD)mMoudle);
for (; pTD->u1.Function; pTD++)
{
if (pTD->u1.Function == (DWORD)MyMessageBoxA)
{
DWORD oldProtect = 0;
VirtualProtect(pTD, 4, PAGE_EXECUTE_READWRITE, &oldProtect);
pTD->u1.Function = (DWORD)oldFun;
VirtualProtect(pTD, 4, oldProtect, &oldProtect);
return TRUE;
}
}
}
return FALSE;
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
IATHook("user32.dll","MessageBoxA");
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
unHook();
break;
}
return TRUE;
}
目标程序
#include<iostream>
#include<Windows.h>
int main()
{
MessageBoxA(NULL, "123", "123", MB_OK);
system("pause");
MessageBoxA(NULL, "456", "456", MB_OK);
system("pause");
MessageBoxA(NULL, "456", "456", MB_OK);
system("pause");
return 0;
}