输入表与HOOK

难过哎,刚开始确实难得看懂,不过耐心看下去就好了


首先很有必要知道几个结构 


IMAGE_DOS_HEADER *pidh;    //DOS头
MAGE_NT_HEADERS *pinh;   //NT头
IMAGE_DATA_DIRECTORY *pSymbolTable;  //数据目录
MAGE_IMPORT_DESCRIPTOR *piid;   //输入表

IMAGE_THUNK_DATA   //函数结构



IMAGE_DOS_HEADER 通过程序的模块句柄换转获得    (IMAGE_DOS_HEADER *)模块句柄;

 MAGE_NT_HEADERS  通过 基址 + DOS头结构中的 e_ifanew 标志   给出 .  机制就是将模块句柄强制转换 DWORD类型

IMAGE_DATA_DIRECTORY  通过 NT头的可选头 DataDirectory[1] 成员就是输入表数据目录

MAGE_IMPORT_DESCRIPTOR  通过 基址 + 输入表.VirtualAddress   给出输入表模块的第一个DLL

IMAGE_THUNK_DATA  基址 + 输入表.OriginalFirstThunk  等于 函数名 的 RVA

IMAGE_THUNK_DATA  基址 + 输入表.FirstThunk等于 IAT ,也就是函数呼叫地址




下面给出例子源码,c++程序


#include <windows.h>
#include <iostream>

typedef int (WINAPI *MsgBoxType)(HWND,LPCWSTR,LPCWSTR,UINT); 
MsgBoxType oldMsg;  /*API原入口地址*/
int WINAPI  MyMessage(HWND hWnd ,LPCWSTR M1,LPCWSTR M2, UINT M3);
DWORD APIAddress; /*存储API入口地址的地方的地址*/
int WINAPI WinMain( __in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in LPSTR lpCmdLine, __in int nShowCmd )
{
	/* 1 */HANDLE hCurrent = GetModuleHandle(NULL);
	/* 2 */IMAGE_DOS_HEADER *pidh;    //DOS头
	/* 3 */IMAGE_NT_HEADERS *pinh;   //NT头
	/* 4 */IMAGE_DATA_DIRECTORY *pSymbolTable;  //数据目录
	/* 5 */IMAGE_IMPORT_DESCRIPTOR *piid;   //输入表


	/* 6 */pidh = (IMAGE_DOS_HEADER *)hCurrent; 
	/* 7 */pinh = (IMAGE_NT_HEADERS *)((DWORD)hCurrent + pidh->e_lfanew);  
	/* 8 */pSymbolTable = &pinh->OptionalHeader.DataDirectory[1]; //输入表
	/* 9 */piid =(IMAGE_IMPORT_DESCRIPTOR *)((DWORD)hCurrent +  pSymbolTable->VirtualAddress); //输入表的相对虚拟地址RVA,
	//0x00cb0000+
	/*10 */do {
		/*11 */    IMAGE_THUNK_DATA *pitd,*pitd2;
		/*12 */    pitd = (IMAGE_THUNK_DATA *)((DWORD)hCurrent + piid->OriginalFirstThunk);  //pitd 等于函数名的RVA
		/*13 */    pitd2 = (IMAGE_THUNK_DATA *)((DWORD)hCurrent + piid->FirstThunk);     //pitd2 等于函数的RVA



		/*14 */    do {
			/*15 */ IMAGE_IMPORT_BY_NAME *piibn;
			/*16 */ piibn = (IMAGE_IMPORT_BY_NAME *)((DWORD)hCurrent +  *((DWORD *)pitd));
			/*17 */ PROC *ppfn = (PROC *)(pitd2->u1.Function);
			/*18 */ if (!strcmp("MessageBoxW",(char *)piibn->Name)) {
				/*19 */     oldMsg = (MsgBoxType)(ppfn);
				/*20 */     DWORD addr = (DWORD)MyMessage;
				/*21 */     DWORD written = 0;
				/* 改变内存读写状态 */
				/*22 */     DWORD oldAccess;
				/*23 */     VirtualProtect(&pitd2->u1.Function,sizeof(DWORD),PAGE_WRITECOPY,&oldAccess);
				/*24 */     APIAddress = (DWORD)&pitd2->u1.Function;
				/* 向内存映像写入数据 */
				/*25 */     WriteProcessMemory(GetCurrentProcess(),&pitd2->u1.Function, &addr,sizeof(DWORD), &written);
				/*26 */ }
			/*27 */ pitd++;pitd2++;
			/*28 */    } while (pitd->u1.Function);






		/*29 */    piid++;
		/*30 */} while (piid->FirstThunk + piid->Characteristics 
			+ piid->ForwarderChain + piid->Name + piid->TimeDateStamp);


		MessageBoxW(NULL,L"呵呵",NULL,NULL);

	return 0;
}

int WINAPI  MyMessage(HWND hWnd ,LPCWSTR M1,LPCWSTR M2, UINT M3) {
	/* 这是用来替换的函数 */




	return oldMsg(hWnd,L"被修改啦",M2,MB_OK);
}

大致过程就是获得指定函数的详细信息, 比较函数名,如果等于你想要HOOK的,就改写内存地址的属性,然后修改 函数的IAT为你自己的,


接下来就是 跨进程 API HOOK ,先给出源码


DLL源码

#include <windows.h>
#include <iostream>

/*DLL 入口函数*/


HHOOK hook;
HINSTANCE hIns;
HWND wind;
DWORD Treeid;
LRESULT CALLBACK GetMsgProc(int,WPARAM, LPARAM);
//void UnHookAPIHook();
typedef int (WINAPI *MsgBoxType)(HWND,LPCWSTR,LPCWSTR,UINT); 
MsgBoxType oldMsg;  /*API原入口地址*/
int WINAPI  MyMessage(HWND hWnd ,LPCWSTR M1,LPCWSTR M2, UINT M3);
DWORD APIAddress; /*存储API入口地址的地方的地址*/
int HookApi() ;
BOOL WINAPI DllMain(HINSTANCE hInst, DWORD reason,LPVOID lpvReserved)
{
	switch (reason)
	{

	case DLL_PROCESS_ATTACH:
	//MessageBoxW(NULL,L"加载DLL",NULL,NULL);
	hIns = hInst;
		break;
	case DLL_PROCESS_DETACH:
		//MessageBoxW(NULL,L"装卸DLL",NULL,NULL);
		break;
	}
	return true;
}



extern "C" __declspec(dllexport) BOOL SetAPIHook(HWND target) 
{
	wind = FindWindowW(NULL,L"Dialog");
	Treeid =  GetWindowThreadProcessId(wind,NULL);
	hook = SetWindowsHookEx(WH_GETMESSAGE,GetMsgProc,hIns,Treeid);    

	
	 

		//PostThreadMessage(pg_data->idTarget,WM_ENABLEAPIHOOK,0,0);

	return TRUE;
}


LRESULT CALLBACK GetMsgProc(int nCode,WPARAM wParam, LPARAM lParam) {
	
	
	
	
	if (nCode == HC_ACTION) 
	{
		MSG *msg = (MSG *)lParam;
	//	MessageBoxW(wind,L"失去焦点",NULL,NULL);
		if (msg->message == WM_KEYDOWN)
		{
			HookApi();
		MessageBoxW(wind,L"失去焦点",NULL,NULL);
		

		}

	}
	return CallNextHookEx(hook,nCode,wParam,lParam);
}


int HookApi() {

	/* 1 */HANDLE hCurrent = GetModuleHandle(NULL);
	/* 2 */IMAGE_DOS_HEADER *pidh;    //DOS头
	/* 3 */IMAGE_NT_HEADERS *pinh;   //NT头
	/* 4 */IMAGE_DATA_DIRECTORY *pSymbolTable;  //数据目录
	/* 5 */IMAGE_IMPORT_DESCRIPTOR *piid;   //输入表


	/* 6 */pidh = (IMAGE_DOS_HEADER *)hCurrent; 
	/* 7 */pinh = (IMAGE_NT_HEADERS *)((DWORD)hCurrent + pidh->e_lfanew);  
	/* 8 */pSymbolTable = &pinh->OptionalHeader.DataDirectory[1]; //输入表
	/* 9 */piid =(IMAGE_IMPORT_DESCRIPTOR *)((DWORD)hCurrent +  pSymbolTable->VirtualAddress); //输入表的相对虚拟地址RVA,
	//0x00cb0000+
	/*10 */do {
		/*11 */    IMAGE_THUNK_DATA *pitd,*pitd2;
		/*12 */    pitd = (IMAGE_THUNK_DATA *)((DWORD)hCurrent + piid->OriginalFirstThunk);  //pitd 等于函数名的RVA
		/*13 */    pitd2 = (IMAGE_THUNK_DATA *)((DWORD)hCurrent + piid->FirstThunk);     //pitd2 等于函数的RVA



		/*14 */    do {
			/*15 */ IMAGE_IMPORT_BY_NAME *piibn;
			/*16 */ piibn = (IMAGE_IMPORT_BY_NAME *)((DWORD)hCurrent +  *((DWORD *)pitd));
			/*17 */ PROC *ppfn = (PROC *)(pitd2->u1.Function);
			/*18 */ if (!strcmp("MessageBoxW",(char *)piibn->Name)) {
				/*19 */     oldMsg = (MsgBoxType)(ppfn);
				/*20 */     DWORD addr = (DWORD)MyMessage;
				/*21 */     DWORD written = 0;
				/* 改变内存读写状态 */
				/*22 */     DWORD oldAccess;
				/*23 */     VirtualProtect(&pitd2->u1.Function,sizeof(DWORD),PAGE_WRITECOPY,&oldAccess);
				/*24 */     APIAddress = (DWORD)&pitd2->u1.Function;
				/* 向内存映像写入数据 */
				/*25 */     WriteProcessMemory(GetCurrentProcess(),&pitd2->u1.Function, &addr,sizeof(DWORD), &written);
					return 0;
				/*26 */ }
			/*27 */ pitd++;pitd2++;
			/*28 */    } while (pitd->u1.Function);






		/*29 */    piid++;
		/*30 */} while (piid->FirstThunk + piid->Characteristics 
			+ piid->ForwarderChain + piid->Name + piid->TimeDateStamp);

}


int WINAPI  MyMessage(HWND hWnd ,LPCWSTR M1,LPCWSTR M2, UINT M3) {
	/* 这是用来替换的函数 */

	MessageBoxW(hWnd,L"呵呵",NULL,NULL);


	return oldMsg(hWnd,L"被修改啦",M2,MB_OK);
}


extern "C" __declspec(dllexport) void UnHookAPIHook()
{


	UnhookWindowsHookEx(hook);
}


程序源码


#include <windows.h>
#include <iostream>
#include "resource.h"


typedef BOOL (*PSetAPIHook)(HWND);
typedef void (*PUnHookAPIHook)();
BOOL CALLBACK DialogProc(HWND hwndDIG , UINT UMsg , WPARAM wParam, LPARAM lParam);
HMODULE hDll = NULL;
PSetAPIHook SetAPIHook;
PUnHookAPIHook UnHookAPIHook;


int WINAPI WinMain( __in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in LPSTR lpCmdLine, __in int nShowCmd )
{

	DialogBoxW(hInstance,(wchar_t*)IDD_DIALOG1 ,NULL,DialogProc);
	


	return 0;
}


BOOL CALLBACK DialogProc(HWND hwndDIG , UINT UMsg , WPARAM wParam, LPARAM lParam)
{
	switch (UMsg)

	{

	case   WM_INITDIALOG :

		return TRUE ;



	case   WM_COMMAND :

		switch (LOWORD (wParam))

		{

		case   IDC_BUTTON1 :
			hDll = LoadLibraryW(L"例子.dll");
			SetAPIHook = (PSetAPIHook)GetProcAddress(hDll,"SetAPIHook");
			SetAPIHook(NULL);

			//MessageBoxW(hwndDIG,L"这是按钮1",NULL,NULL);
			return TRUE ;

		case   IDC_BUTTON2 :
			//hDll = LoadLibraryW(L"例子.dll");
			UnHookAPIHook = (PUnHookAPIHook)GetProcAddress(hDll,"UnHookAPIHook");
			UnHookAPIHook();
			//MessageBoxW(hwndDIG,L"这是按钮2",NULL,NULL);

			//IDOK
			return TRUE ;

		case   IDOK :

			EndDialog (hwndDIG, 0) ;
			return TRUE ;
		case   IDCANCEL :

			EndDialog (hwndDIG, 0) ;
			return TRUE ;


		}

		break ;

	}



	return FALSE ;


}


稍后给出详解...


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值