IAT Hook

IAT Hook 本质就是将PE的导入表中的IAT中指定函数的地址进行替换,从而实现Hook。

我的IAT Hook 是配合CreateRemoteThread进行注入Hook的。关于CreateRemoteThread请参照:CreateRemoteThread

// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"
#include <tlhelp32.h>
#include <imagehlp.h>
#pragma  comment (lib, "imagehlp")
#include <tchar.h>

typedef int (WINAPI *PfnMsgW)(_In_opt_ HWND hWnd, _In_opt_ LPCWSTR lpText, _In_opt_ LPCWSTR lpCaption, _In_ UINT uType);

PfnMsgW __OldPfnMsgW = nullptr;
BOOL HookAPI(LPCSTR HookModule, LPCSTR HookFuncName, PfnMsgW HookFuncs);

int WINAPI MyMessageBox(_In_opt_ HWND hWnd, _In_opt_ LPCWSTR lpText, _In_opt_ LPCWSTR lpCaption, _In_ UINT uType)
{
	if (__OldPfnMsgW != nullptr)
	{
		return __OldPfnMsgW(hWnd, L"HookSuccess", lpCaption, uType);//调用以前的
	}
	return 0;
}


BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:

		HookAPI("user32.dll", "MessageBoxW", MyMessageBox);

    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:

        break;
    }
    return TRUE;
}


BOOL HookAPI(LPCSTR HookModule, LPCSTR HookFuncName, PfnMsgW HookFuncs)
{
	//HookAddress = user32.dll!0x766a2530 (加载符号以获取其他信息)
	LPVOID HookAddress = GetProcAddress(GetModuleHandleA(HookModule), HookFuncName);

	__OldPfnMsgW = (PfnMsgW)HookAddress; //保存旧的函数指针.

	//在DLL内部调用GetModuleHandle(NULL),获取的是主模块(EXE)基址
	//ModuleHandle = test.exe!0x00380000 {unused = 0x00905a4d }
	HMODULE ModuleHandle = GetModuleHandle(NULL);

	ULONG ModuleSize = 0;

	PIMAGE_IMPORT_DESCRIPTOR pImport = (PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryEntryToData(ModuleHandle,
		TRUE,
		IMAGE_DIRECTORY_ENTRY_IMPORT,
		&ModuleSize);

	DWORD Temp;
	PIMAGE_IMPORT_DESCRIPTOR   CurrentImportTable = pImport;
	DWORD *FirstThunk; //导入表子表,也就是IAT,存储函数地址的表.
	//遍历导入表
	while (CurrentImportTable->Characteristics && CurrentImportTable->FirstThunk != NULL)
	{
		Temp = CurrentImportTable->FirstThunk + (DWORD)GetModuleHandle(NULL);
		FirstThunk = (DWORD *)Temp;
		while (*FirstThunk != NULL)
		{
			//遍历子表
			if (*FirstThunk == (DWORD)__OldPfnMsgW)
			{
				//找到要修改的导入表了//修改内存保护属性.写入我们新的函数地址.
				DWORD oldProtected;
				VirtualProtect(FirstThunk, 0x1000, PAGE_EXECUTE_READWRITE, &oldProtected);
				Temp = (DWORD)MyMessageBox;
				memcpy(FirstThunk, (DWORD *)&Temp, 4); //将变量中保存的函数地址拷贝到导入表中.
				VirtualProtect(FirstThunk, 0x1000, oldProtected, &oldProtected);
			}
			FirstThunk++; //继续遍历.
		}
		CurrentImportTable++; //每次是加一个导入表结构.
	}
	return TRUE;
}

写的过程中遇到以下一些问题。

1.ImageDirectoryEntryToData的头文件和链接库

2.在DLL内部调用GetModuleHandle(NULL),获取的是主模块(EXE)基址

   最开始我还用模块快照的方式获得的基址,想想都觉得hhh。

3.在遍历IAT时,注意指针的转换。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值