【2021.01.15】IAT HOOK

IAT

IAT(Import Address Table),导入地址表。

#include <iostream>
#include <Windows.h>

DWORD g_dwIATHookFlag = FALSE;	        //HOOK状态 是否已经HOOK
DWORD g_dwOldAddr = NULL;		//保存原始函数的地址
DWORD g_dwNewAddr = NULL;		//保存HOOK函数的地址

BOOL SetIATHOOK(DWORD dwOldAddr, DWORD dwNewAddr)
{
	BOOL bFlag = FALSE;
	DWORD dwImageBase = NULL;
	PDWORD pFuncAddr = NULL;
	PIMAGE_NT_HEADERS pNtHeader = NULL;
	PIMAGE_IMPORT_DESCRIPTOR pImportDescriptor = NULL;
	DWORD dwOldProtect = NULL;

	//取模块基址
	dwImageBase = (DWORD)::GetModuleHandle(NULL);
	pNtHeader = (PIMAGE_NT_HEADERS)(dwImageBase + ((PIMAGE_DOS_HEADER)dwImageBase)->e_lfanew);
	pImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)(dwImageBase + pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);

	//遍历IAT表 找到函数地址
	while (pImportDescriptor->FirstThunk != 0 && bFlag == FALSE)
	{
		pFuncAddr = (PDWORD)(dwImageBase + pImportDescriptor->FirstThunk);

		while (*pFuncAddr)
		{
			if (dwOldAddr == *pFuncAddr)
			{
				//如果找到要HOOK的函数, 先修改内存页的属性
				VirtualProtect(pFuncAddr, sizeof(DWORD), PAGE_READWRITE, &dwOldProtect);
				*pFuncAddr = dwNewAddr;

				//恢复内存页属性
				VirtualProtect(pFuncAddr, sizeof(DWORD), dwOldProtect, NULL);
				bFlag = TRUE;
				break;
			}
			pFuncAddr++;
		}
		pImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)pImportDescriptor + sizeof(IMAGE_IMPORT_DESCRIPTOR));
	}
	//修改状态
	g_dwOldAddr = dwOldAddr;
	g_dwNewAddr = dwNewAddr;
	g_dwIATHookFlag = TRUE;

	return bFlag;
}

BOOL UnIATHOOK()
{
	BOOL bFlag = FALSE;
	DWORD dwImageBase = NULL;
	PDWORD pFuncAddr = NULL;
	PIMAGE_NT_HEADERS pNtHeader = NULL;
	PIMAGE_IMPORT_DESCRIPTOR pImportDescriptor = NULL;
	DWORD dwOldProtect = NULL;

	//判断是否HOOK
	if (!g_dwIATHookFlag)
	{
		OutputDebugString(L"UnIATHOOK识别:尚未进行IAT HOOK!");
		return bFlag;
	}

	//取模块基址
	dwImageBase = (DWORD)::GetModuleHandle(NULL);
	pNtHeader = (PIMAGE_NT_HEADERS)(dwImageBase + ((PIMAGE_DOS_HEADER)dwImageBase)->e_lfanew);
	pImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)(dwImageBase + pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);

	//遍历IAT表 找到函数地址
	while (pImportDescriptor->FirstThunk != 0 && bFlag == FALSE)
	{
		pFuncAddr = (PDWORD)(dwImageBase + pImportDescriptor->FirstThunk);

		while (*pFuncAddr)
		{
			if (g_dwNewAddr == *pFuncAddr)
			{
				//如果找到要HOOK的函数, 先修改内存页的属性
				VirtualProtect(pFuncAddr, sizeof(DWORD), PAGE_READWRITE, &dwOldProtect);
				*pFuncAddr = g_dwOldAddr;

				//恢复内存页属性
				VirtualProtect(pFuncAddr, sizeof(DWORD), dwOldProtect, NULL);
				bFlag = TRUE;
				break;
			}
			pFuncAddr++;
		}
		pImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)pImportDescriptor + sizeof(IMAGE_IMPORT_DESCRIPTOR));
	}
	//修改状态
	g_dwOldAddr = NULL;
	g_dwNewAddr = NULL;
	g_dwIATHookFlag = FALSE;

	return bFlag;
}

int WINAPI MyMessageBox(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType)
{
	char lpNewText[] = "修改后的内容";

	//定义MessageBox函数指针
	typedef int (WINAPI* PFNMESSAGEBOX)(HWND, LPCSTR, LPCSTR, UINT);

	//执行真正的函数
	int ret = ((PFNMESSAGEBOX)g_dwOldAddr)(hWnd, lpNewText, lpCaption, uType);

	return ret;
}

DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
	//保存原始函数地址
	DWORD pOldFuncAddr = (DWORD)GetProcAddress(LoadLibraryA("user32.dll"), "MessageBoxA");

	//安装或卸载HOOK
	if (!g_dwIATHookFlag)
	{
		return SetIATHOOK(pOldFuncAddr, (DWORD)MyMessageBox);
	}
	else
	{
		return UnIATHOOK();
	}

	return FALSE;
}

int main()
{
	MessageBoxA(NULL, "This is lpText", "MSG", NULL);

	ThreadProc(NULL);

	MessageBoxA(NULL, "This is lpText", "MSG", NULL);

	std::cout << "按任意键继续..." << std::endl;

	std::cin.get();

	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_18120361/article/details/112685645