zoukankan      html  css  js  c++  java
  • 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;
    }
    

  • 相关阅读:
    600+ 道 Java面试题及答案整理(2021最新版)
    Spring Boot + Web Socket 实现扫码登录,这种方式太香了!!
    小团队适合引入 Spring Cloud 微服务吗?
    Netty 通道怎么区分对应的用户?
    软件开发打败了 80 %的程序员
    一个最简单的消息队列,带你理解 RabbitMQ!
    厉害了,Netty 轻松实现文件上传!
    Netty 是如何解决 TCP 粘包拆包的?
    图解 Git,一目了然!
    面试官:谈谈分布式一致性机制,我一脸懵逼。。
  • 原文地址:https://www.cnblogs.com/zpchcbd/p/13379896.html
Copyright © 2011-2022 走看看