IAT HOOK 简单实现

注意的事项:

1、操作部分在IAT表中

2、HOOK函数中需要用函数指针接收,因为此时IAT已经被HOOK,如果直接return 原函数,其实会造成栈溢出,因为此时的原函数已经被HOOK了,会造成类似的递归操作

3、最后HOOK完,需要进行 卸载HOOK 操作

4、如果debug的时候发现IAT表中是能写进去的,但是发现写入异常,则可能跟物理页的属性有关,需要进行VirtualProtect设置

#include<Windows.h>
#include<cstdio>


DWORD dwMessagebox = (DWORD)GetProcAddress(LoadLibrary("user32.dll"), "MessageBoxA");

int WINAPI MyMessageBox(_In_opt_ HWND hWnd, _In_opt_ LPCSTR lpText, _In_opt_ LPCSTR lpCaption, _In_ UINT uType){
	typedef int(WINAPI *PMyMessageBox)(_In_opt_ HWND hWnd, _In_opt_ LPCSTR lpText, _In_opt_ LPCSTR lpCaption, _In_ UINT uType);

	printf("Hook Messagebox Param: hWnd: %x, lpText: %s, lpCation: %s, uType: %x", hWnd, lpText, lpCaption, uType);

	PMyMessageBox MyMessageBox = (PMyMessageBox)dwMessagebox;
	return MyMessageBox(0, TEXT("It's My Hook Messagebox!"), 0, 0);
}


void InstallIatHook(DWORD dwOldFunction, DWORD dwNewFunction)
{

	HMODULE hModule = GetModuleHandle(NULL);

	// load pe
	PIMAGE_DOS_HEADER pDosHeader = NULL;
	PIMAGE_NT_HEADERS pNTHeader = NULL;
	PIMAGE_FILE_HEADER pPEHeader = NULL;
	PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
	PIMAGE_SECTION_HEADER pSectionHeader = NULL;
	PIMAGE_IMPORT_DESCRIPTOR pIMPORT_DESCRIPTOR = NULL;
	PIMAGE_IMPORT_BY_NAME pImage_IMPORT_BY_NAME = NULL;

	PDWORD OriginalFirstThunk = NULL;
	PDWORD FirstThunk = NULL;
	PIMAGE_THUNK_DATA pImageThunkData = NULL;

	DWORD Original = 0;

	pDosHeader = (PIMAGE_DOS_HEADER)hModule;
	pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)hModule + pDosHeader->e_lfanew);
	pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader) + 4);
	pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER);
	pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + sizeof(IMAGE_OPTIONAL_HEADER32));
	
	pIMPORT_DESCRIPTOR = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)hModule + pOptionHeader->DataDirectory[1].VirtualAddress);

	DWORD dwOldProtect; // 内存页属性
	BOOL bFlag = TRUE;
	//这里可以进行while操作,这里while的判断依据为pIMPORT_DESCRIPTOR个数
	while (pIMPORT_DESCRIPTOR->FirstThunk && bFlag) {
		FirstThunk = (PDWORD)((DWORD)hModule + (DWORD)pIMPORT_DESCRIPTOR->FirstThunk);
		while (*FirstThunk) {
			if (*FirstThunk == dwOldFunction)
			{
				VirtualProtect((LPVOID)FirstThunk, 0x4, PAGE_READWRITE, &dwOldProtect);
				*FirstThunk = dwNewFunction;
				bFlag = FALSE;
				break;
			}
		
			FirstThunk++;
		}

		// 进行遍历操作
		pIMPORT_DESCRIPTOR++;
	}

}

void UninstallIatHook(DWORD dwOldFunction, DWORD dwNewFunction)
{
	HMODULE hModule = GetModuleHandle(NULL);

	// load pe
	PIMAGE_DOS_HEADER pDosHeader = NULL;
	PIMAGE_NT_HEADERS pNTHeader = NULL;
	PIMAGE_FILE_HEADER pPEHeader = NULL;
	PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
	PIMAGE_SECTION_HEADER pSectionHeader = NULL;
	PIMAGE_IMPORT_DESCRIPTOR pIMPORT_DESCRIPTOR = NULL;
	PIMAGE_IMPORT_BY_NAME pImage_IMPORT_BY_NAME = NULL;

	PDWORD OriginalFirstThunk = NULL;
	PDWORD FirstThunk = NULL;
	PIMAGE_THUNK_DATA pImageThunkData = NULL;

	DWORD Original = 0;

	pDosHeader = (PIMAGE_DOS_HEADER)hModule;
	pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)hModule + pDosHeader->e_lfanew);
	pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader) + 4);
	pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER);
	pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + sizeof(IMAGE_OPTIONAL_HEADER32));

	pIMPORT_DESCRIPTOR = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)hModule + pOptionHeader->DataDirectory[1].VirtualAddress);

	BOOL bFlag = TRUE;
	//这里可以进行while操作,这里while的判断依据为pIMPORT_DESCRIPTOR个数
	while (pIMPORT_DESCRIPTOR->FirstThunk && bFlag) {
		FirstThunk = (PDWORD)((DWORD)hModule + (DWORD)pIMPORT_DESCRIPTOR->FirstThunk);
		while (*FirstThunk) {
			if (*FirstThunk == dwOldFunction)
			{
				*FirstThunk = dwNewFunction;
				bFlag = FALSE;
				break;
			}

			FirstThunk++;
		}

		// 进行遍历操作
		pIMPORT_DESCRIPTOR++;
	}
}

int main(int argc, char* argv[]){
	InstallIatHook(dwMessagebox, (DWORD)MyMessageBox);
	MessageBox(0, 0, 0, 0);
	UninstallIatHook((DWORD)MyMessageBox, dwMessagebox);
	MessageBox(0, 0, 0, 0);

	return 0;
}

posted @ 2020-07-26 11:51  zpchcbd  阅读(808)  评论(0编辑  收藏  举报