C++实现IAT HOOK细节部分

admin 2018年5月29日15:59:14评论35 views字数 3089阅读10分17秒阅读模式

IATHook的主要原理是替换导入的api的地址,将其地址改成我们的函数的地址,其缺点也很明显,如果你不知道我的函数叫什么,或者我的函数没 存在导入表中,你就无法使用IATHook了,IATHook主要是通过修改PE中IAT表来实现的,IAT表在运行之前,里面存的是函数名和序号,并没有函数地址,所以需要在目标程序运行以后才能进行IATHook~关于IAT表的具体内容可以参考《windows PE 权威指南》的相关章节

#include <windows.h>#include <tchar.h>#include <winsock.h>#include <windows.h>#include <stdio.h>#include <stdlib.h>using namespace std;HANDLE g_hModuleHandle;HMODULE hModuleInject = NULL;HANDLE hInjectThread = NULL;IMAGE_DOS_HEADER* pDosHeader = NULL;IMAGE_OPTIONAL_HEADER* pOpNtHeader = NULL; //这里加24  IMAGE_IMPORT_DESCRIPTOR* pImportDesc = NULL;HANDLE hInfoFile = INVALID_HANDLE_VALUE;int WINAPI MyMsgBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType){ 	MessageBoxW(hWnd, lpText, L"拦截的消息", uType); 	return IDYES;}VOID WINAPI MyPostQuitMessage(_In_ int nExitCode){ 	MessageBoxW(NULL, L"Fuck", L"拦截的消息", MB_OK); 	PostQuitMessage(nExitCode);}DWORD GetProcessAddrss(char * libname, char * funname){ 	HMODULE htmp = LoadLibraryA(libname); 	DWORD hret = 0; 	if (htmp != NULL) 	{ 		hret = (DWORD)GetProcAddress(htmp, funname); 	} 	return hret;}DWORD WINAPI injectThread(LPARAM lparam){  	char modulefilename[MAX_PATH];  	GetModuleFileNameA(NULL, modulefilename, MAX_PATH); 	MessageBoxA(NULL, modulefilename, "DLL已进入目标进程", MB_OK);  	hModuleInject = ::GetModuleHandleA(NULL);//获取模块基址 	pDosHeader = (IMAGE_DOS_HEADER*)hModuleInject; 	pOpNtHeader = (IMAGE_OPTIONAL_HEADER*)((BYTE*)hModuleInject + pDosHeader->e_lfanew + 24); //这里加24因为可选头前面有个4字节的标志+IMAGE_FILE_HEADER 	pImportDesc = (IMAGE_IMPORT_DESCRIPTOR*)((BYTE*)hModuleInject + pOpNtHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);//找到导入表 	while (pImportDesc->FirstThunk) 	{ 		TCHAR* pszDllName = (TCHAR*)((BYTE*)hModuleInject + pImportDesc->Name);//得到DLL的名字 		//printf("模块名称:%sn", pszDllName);    		DWORD n = 0;  		IMAGE_THUNK_DATA* pThunk = (IMAGE_THUNK_DATA*)((BYTE*)hModuleInject + pImportDesc->OriginalFirstThunk);  		while (pThunk->u1.Function) 		{ 			//取得函数地址   			PDWORD lpAddr = (DWORD*)((BYTE*)hModuleInject + pImportDesc->FirstThunk) + n; //从第一个函数的地址    			LPDWORD lpd = (LPDWORD)pThunk;  			DWORD oldp; 			VirtualProtect((LPVOID)lpAddr, 8, PAGE_EXECUTE_READWRITE, &oldp); 			//if(strcmp(pszFuncName,"MessageBoxW")==0) 			if (*lpAddr == (unsigned long)MessageBoxW) 			{ 				MessageBox(NULL,L"已监控目标进程中 MessageBoxW 函数", pszDllName, MB_ICONINFORMATION); 				*(lpAddr) = (unsigned long)MyMsgBoxW; 			} 			if (*lpAddr == (unsigned long)PostQuitMessage) 			{ 				MessageBox(NULL,L"已监控目标进程中 PostQuitMessage 函数", pszDllName, MB_ICONINFORMATION); 				*(lpAddr) = (unsigned long)MyPostQuitMessage; 			} 			if (*lpAddr == (unsigned long)GetSubMenu) 			{ 				MessageBox(NULL,L"已监控目标进程中 GetSubMenu 函数", pszDllName, MB_ICONINFORMATION); 				*(lpAddr) = (unsigned long)MyPostQuitMessage; 			} 			VirtualProtect((LPVOID)lpAddr, 8, oldp, &oldp);  			n++; //每次增加一个DWORD   			pThunk++; 		} 		pImportDesc++; 	} 	return 0;}BOOL APIENTRY DllMain(HMODULE hSelfModule, 					  DWORD  ul_reason_for_call, 					  LPVOID lpReserved					  ){ 	g_hModuleHandle = (HMODULE)hSelfModule; 	switch (ul_reason_for_call) 	{ 	case DLL_PROCESS_ATTACH: 		DisableThreadLibraryCalls((HMODULE)hSelfModule); 		hInjectThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)injectThread, 0, 0, 0); 		CloseHandle(hInjectThread); 		break; 	case DLL_THREAD_ATTACH: 	case DLL_THREAD_DETACH: 	case DLL_PROCESS_DETACH:  		CloseHandle(hInfoFile);  		MessageBox(NULL, L"目标进程已经退出", L"Information", MB_ICONINFORMATION); 		break; 	} 	return TRUE;}


本文始发于微信公众号(飓风网络安全):C++实现IAT HOOK细节部分

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2018年5月29日15:59:14
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   C++实现IAT HOOK细节部分https://cn-sec.com/archives/358801.html

发表评论

匿名网友 填写信息