日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 综合教程 >内容正文

综合教程

Hook技术简单介绍

發(fā)布時(shí)間:2023/12/15 综合教程 32 生活家
生活随笔 收集整理的這篇文章主要介紹了 Hook技术简单介绍 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Hook主要就是通過(guò)一定手段在程序執(zhí)行過(guò)程中進(jìn)行干預(yù)。

IAT Hook 篡改MessageBox

借用accills的例子

#include <windows.h>
#include <stdio.h>
#include <imagehlp.h>
#pragma comment(lib,"imagehlp.lib")


//以MessageBoxA的原型定義一個(gè)函數(shù)指針類(lèi)型
typedef int 
(WINAPI *PFN_MessageBoxA)(
	HWND hWnd,          // handle of owner window
	LPCTSTR lpText,     // address of text in message box
	LPCTSTR lpCaption,  // address of title of message box
	UINT uType          // style of message box
	);

//以MessageBoxA的原型定義一個(gè)函數(shù)來(lái)替代原始的MessageBoxA
int WINAPI My_MessageBoxA(
	HWND hWnd,          // handle of owner window
	LPCTSTR lpText,     // address of text in message box
	LPCTSTR lpCaption,  // address of title of message box
	UINT uType          // style of message box
	);

//存在以下關(guān)系
//*(*pThunkPointer) == *pOriginalFuncAddr ;
BOOL InstallModuleIATHook(
	HMODULE hModToHook,
	char *szModuleName, 
	char *szFuncName,
	PVOID ProxyFunc,
	PULONG_PTR *pThunkPointer,
	ULONG_PTR *pOriginalFuncAddr
	);

VOID ShowMsgBox(char *szMsg);
BOOL IAT_InstallHook();
VOID IAT_UnInstallHook();
BOOL IsWow64();
//保存原始MessageBoxA的地址
PFN_MessageBoxA OldMessageBox=NULL;
//指向IAT中pThunk的地址
PULONG_PTR g_PointerToIATThunk = NULL;

int main(int argc, char *argv[ ])
{
	BOOL bIsWow64 = IsWow64();
	printf("IsWow64 = %d\n",bIsWow64);
	ShowMsgBox("Before IAT Hook");
	IAT_InstallHook();
	ShowMsgBox("After  IAT Hook");
	IAT_UnInstallHook();
	ShowMsgBox("After  IAT Hook UnHooked");
	return 0;
}

//之所以把這個(gè)調(diào)用單獨(dú)放在一個(gè)函數(shù)中,是因?yàn)镽elease模式下對(duì)調(diào)用進(jìn)行了優(yōu)化,第二次調(diào)用時(shí)直接采用了寄存器尋址而不是導(dǎo)入表
//因此,單獨(dú)放在一個(gè)函數(shù)中可以避免這個(gè)情況。

VOID ShowMsgBox(char *szMsg)
{
	MessageBoxA(NULL,szMsg,"Test",MB_OK);
}


int WINAPI My_MessageBoxA(
	HWND hWnd,          // handle of owner window
	LPCTSTR lpText,     // address of text in message box
	LPCTSTR lpCaption,  // address of title of message box
	UINT uType          // style of message box
	)
{	
	//在這里,你可以對(duì)原始參數(shù)進(jìn)行任意操作
	int ret;
	char newText[1024]={0};
	char newCaption[256]="pediy.com";
	printf("有人調(diào)用MessageBox!\n");
	//在調(diào)用原函數(shù)之前,可以對(duì)IN(輸入類(lèi))參數(shù)進(jìn)行干涉
	lstrcpy(newText,lpText);//為防止原函數(shù)提供的緩沖區(qū)不夠,這里復(fù)制到我們自己的一個(gè)緩沖區(qū)中再進(jìn)行操作
	lstrcat(newText,"\n\tMessageBox Hacked by pediy.com!");//篡改消息框內(nèi)容
	uType|=MB_ICONERROR;//增加一個(gè)錯(cuò)誤圖標(biāo)
	ret = OldMessageBox(hWnd,newText,newCaption,uType);//調(diào)用原MessageBox,并保存返回值
	//調(diào)用原函數(shù)之后,可以繼續(xù)對(duì)OUT(輸出類(lèi))參數(shù)進(jìn)行干涉,比如網(wǎng)絡(luò)函數(shù)的recv,可以干涉返回的內(nèi)容
	return ret;//這里你還可以干涉原始函數(shù)的返回值
	
}

BOOL IAT_InstallHook()
{
	BOOL bResult = FALSE ;
	HMODULE hCurExe = GetModuleHandle(NULL);
	PULONG_PTR pt ;
	ULONG_PTR OrginalAddr;
	bResult = InstallModuleIATHook(hCurExe,"user32.dll","MessageBoxA",(PVOID)My_MessageBoxA,&pt,&OrginalAddr);
	if (bResult)
	{
		printf("[*]Hook安裝完畢! pThunk=0x%p  OriginalAddr = 0x%p\n",pt,OrginalAddr);
		g_PointerToIATThunk = pt ;
		OldMessageBox = (PFN_MessageBoxA)OrginalAddr ;
	}
	return bResult;
	
}

VOID IAT_UnInstallHook()
{
	
	DWORD dwOLD;
	MEMORY_BASIC_INFORMATION  mbi;
	if (g_PointerToIATThunk)
	{
		//查詢(xún)并修改內(nèi)存頁(yè)的屬性
		VirtualQuery((LPCVOID)g_PointerToIATThunk,&mbi,sizeof(mbi));
		VirtualProtect(mbi.BaseAddress,mbi.RegionSize,PAGE_EXECUTE_READWRITE,&dwOLD);
		//將原始的MessageBoxA地址填入IAT中
		*g_PointerToIATThunk = (ULONG)OldMessageBox;
		//恢復(fù)內(nèi)存頁(yè)的屬性
		VirtualProtect(mbi.BaseAddress,mbi.RegionSize,dwOLD,0);
	}

}

//************************************
// FullName:    InstallModuleIATHook
// Description: 為指定模塊安裝IAT Hook
// Access:      public 
// Returns:     BOOL
// Parameter:   HMODULE hModToHook , 待Hook的模塊基址
// Parameter:   char * szModuleName , 目標(biāo)函數(shù)所在模塊的名字
// Parameter:   char * szFuncName , 目標(biāo)函數(shù)的名字
// Parameter:   PVOID DetourFunc , Detour函數(shù)地址
// Parameter:   PULONG * pThunkPointer , 用以接收指向修改的位置的指針
// Parameter:   ULONG * pOriginalFuncAddr , 用以接收原始函數(shù)地址
//************************************
BOOL InstallModuleIATHook(
	HMODULE hModToHook,// IN
	char *szModuleName,// IN
	char *szFuncName,// IN
	PVOID DetourFunc,// IN
	PULONG_PTR *pThunkPointer,//OUT
	ULONG_PTR *pOriginalFuncAddr//OUT
	)
{
	PIMAGE_IMPORT_DESCRIPTOR  pImportDescriptor;
	PIMAGE_THUNK_DATA         pThunkData;
	ULONG ulSize;
	HMODULE hModule=0;
	ULONG_PTR TargetFunAddr;
	PULONG_PTR lpAddr;
	char *szModName;
	BOOL result = FALSE ;
	BOOL bRetn = FALSE;

	hModule = LoadLibrary(szModuleName);
	TargetFunAddr = (ULONG_PTR)GetProcAddress(hModule,szFuncName);
	printf("[*]Address of %s:0x%p\n",szFuncName,TargetFunAddr);
	printf("[*]Module To Hook at Base:0x%p\n",hModToHook);
	pImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryEntryToData(hModToHook, TRUE,IMAGE_DIRECTORY_ENTRY_IMPORT, &ulSize);;
	printf("[*]Find ImportTable,Address:0x%p\n",pImportDescriptor);
	while (pImportDescriptor->FirstThunk)
	{
		szModName = (char*)((PBYTE)hModToHook+pImportDescriptor->Name) ;
		printf("[*]Cur Module Name:%s\n",szModName);
		if (stricmp(szModName,szModuleName) != 0)
		{
			printf("[*]Module Name does not match, search next...\n");
			pImportDescriptor++;
			continue;
		}
		//程序的導(dǎo)入表處理完畢后OriginalFirstThunk可能是無(wú)效的,不能再根據(jù)名稱(chēng)來(lái)查找,而是遍歷FirstThunk直接根據(jù)地址判斷
		pThunkData = (PIMAGE_THUNK_DATA)((BYTE *)hModToHook + pImportDescriptor->FirstThunk);
		while(pThunkData->u1.Function)
		{
			lpAddr = (ULONG_PTR*)pThunkData;
			//找到了地址
			if((*lpAddr) == TargetFunAddr)
			{
				printf("[*]Find target address!\n");
				//通常情況下導(dǎo)入表所在內(nèi)存頁(yè)都是只讀的,因此需要先修改內(nèi)存頁(yè)的屬性為可寫(xiě)
				DWORD dwOldProtect;
				MEMORY_BASIC_INFORMATION  mbi;
				VirtualQuery(lpAddr,&mbi,sizeof(mbi));
				bRetn = VirtualProtect(mbi.BaseAddress,mbi.RegionSize,PAGE_EXECUTE_READWRITE,&dwOldProtect);
				if (bRetn)
				{
					//內(nèi)存頁(yè)屬性修改成功,繼續(xù)下一步操作,先保存原始數(shù)據(jù)
					if (pThunkPointer != NULL)
					{
						*pThunkPointer = lpAddr ;
					}
					if (pOriginalFuncAddr != NULL)
					{
						*pOriginalFuncAddr = *lpAddr ;
					}
					//修改地址
					*lpAddr = (ULONG_PTR)DetourFunc;
					result = TRUE ;
					//恢復(fù)內(nèi)存頁(yè)的屬性
					VirtualProtect(mbi.BaseAddress,mbi.RegionSize,dwOldProtect,0);
					printf("[*]Hook ok.\n");
				}
				
				break;	
			}
			//---------
			pThunkData++;
		}
		pImportDescriptor++;
	}
	
	FreeLibrary(hModule);
	return result;
}
typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);

LPFN_ISWOW64PROCESS fnIsWow64Process;

BOOL IsWow64()
{
	BOOL bIsWow64 = FALSE;

	fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(
		GetModuleHandle(TEXT("kernel32")),"IsWow64Process");

	if (NULL != fnIsWow64Process)
	{
		if (!fnIsWow64Process(GetCurrentProcess(),&bIsWow64))
		{
			// handle error
		}
	}
	return bIsWow64;
}

00DA8845  |.  C745 A4 01000>||mov [local.23],0x1
00DA884C  |.  8BF4          ||mov esi,esp
00DA884E  |.  6A 00         ||push 0x0                                       ; /pOldProtect = NULL
00DA8850  |.  8B45 8C       ||mov eax,[local.29]                             ; |
00DA8853  |.  50            ||push eax                                       ; |NewProtect = PAGE_READWRITE|PAGE_WRITECOPY
00DA8854  |.  8B8D 74FFFFFF ||mov ecx,[local.35]                             ; |
00DA885A  |.  51            ||push ecx                                       ; |Size = 501EBA15 (1344190997.)
00DA885B  |.  8B95 68FFFFFF ||mov edx,[local.38]                             ; |IATHookM._IMPORT_DESCRIPTOR_KERNEL32:NativeDll::ProcessAttach)'0,64)'4)'64)'
00DA8861  |.  52            ||push edx                                       ; |Address = IATHookM.00E04038
00DA8862  |.  FF15 8882E000 ||call dword ptr ds:[<&KERNEL32.VirtualProtect>] ; \VirtualProtect
00DA8868  |.  3BF4          ||cmp esi,esp
00DA886A  |.  E8 80E3FFFF   ||call IATHookM.00DA6BEF
00DA886F  |.  68 7C4DDF00   ||push IATHookM.00DF4D7C                         ;  [*]Hook ok.\n
00DA8874  |.  E8 F5E6FFFF   ||call IATHookM.00DA6F6E
00DA8879  |.  83C4 04       ||add esp,0x4
00DA887C  |>  EB 0E         ||jmp short IATHookM.00DA888C
00DA887E  |>  8B45 EC       ||mov eax,[local.5]                              ;  <&USER32.MessageBoxA>
00DA8881  |.  83C0 04       ||add eax,0x4
00DA8884  |.  8945 EC       ||mov [local.5],eax
00DA8887  |.^ E9 1EFFFFFF   |\jmp IATHookM.00DA87AA
00DA888C  |>  8B45 F8       |mov eax,[local.2]                               ;  IATHookM._IMPORT_DESCRIPTOR_USER32t Hierarchy Descriptor'r',-1,0,64)'4)'64)'
00DA888F  |.  83C0 14       |add eax,0x14
00DA8892  |.  8945 F8       |mov [local.2],eax
00DA8895  |.^ E9 AEFEFFFF   \jmp IATHookM.00DA8748

跟蹤到這一步已經(jīng)實(shí)現(xiàn)了HOOK,在IAT——InstallHook函數(shù)執(zhí)行后

這個(gè)MessageBox的地址已經(jīng)被修改

之前的是

00DA832C  |.  F3:AB         rep stos dword ptr es:[edi]
00DA832E  |.  8BF4          mov esi,esp
00DA8330  |.  6A 00         push 0x0                                         ; /Style = MB_OK|MB_APPLMODAL
00DA8332  |.  68 C44CDF00   push IATHookM.00DF4CC4                           ; |Test
00DA8337  |.  8B45 08       mov eax,[arg.1]                                  ; |
00DA833A  |.  50            push eax                                         ; |Text = B0ADE667 ???
00DA833B  |.  6A 00         push 0x0                                         ; |hOwner = NULL
00DA833D  |.  FF15 4884E000 call dword ptr ds:[<&USER32.MessageBoxA>]        ; \MessageBoxA
00DA8343  |.  3BF4          cmp esi,esp
00DA8345  |.  E8 A5E8FFFF   call IATHookM.00DA6BEF

所以現(xiàn)在調(diào)用的是My——MessageBox函數(shù)

說(shuō)明第二次條用ShowMsgBox之前執(zhí)行的IAT_InstallHook函數(shù)。因?yàn)檫@個(gè)函數(shù)以修改IAT方式攔截了對(duì)API的調(diào)用。

第二個(gè)Inline Hook 篡改指定MessageBox消息

esi值向User32.MessageBoxA

而MessageBoxA 函數(shù)內(nèi)部被篡改了(在開(kāi)頭直接通過(guò)一個(gè)跳轉(zhuǎn)指令到了MY—— MessageBoxA函數(shù)里)

00401050 > .  81EC 00050000 sub esp,0x500                                    ;  ?My_MessageBoxA@@YGHPAUHWND__@@PBD1I@Z
00401056   .  57            push edi                                         ;  InlineHo.<ModuleEntryPoint>
00401057   .  B9 FF000000   mov ecx,0xFF
0040105C   .  33C0          xor eax,eax
0040105E   .  8DBC24 050100>lea edi,dword ptr ss:[esp+0x105]
00401065   .  C68424 040100>mov byte ptr ss:[esp+0x104],0x0
0040106D   .  66:8B15 C0804>mov dx,word ptr ds:[0x4080C0]                    ;  m
00401074   .  F3:AB         rep stos dword ptr es:[edi]
00401076   .  8B0D BC804000 mov ecx,dword ptr ds:[0x4080BC]                  ;  y.com
0040107C   .  66:895424 0C  mov word ptr ss:[esp+0xC],dx
00401081   .  66:AB         stos word ptr es:[edi]
00401083   .  AA            stos byte ptr es:[edi]
00401084   .  A1 B8804000   mov eax,dword ptr ds:[<??_C@_09HIDC@pediy?4com?$>;  pediy.com
00401089   .  894C24 08     mov dword ptr ss:[esp+0x8],ecx
0040108D   .  894424 04     mov dword ptr ss:[esp+0x4],eax
00401091   .  B9 3D000000   mov ecx,0x3D
00401096   .  33C0          xor eax,eax
00401098   .  8D7C24 0E     lea edi,dword ptr ss:[esp+0xE]
0040109C   .  F3:AB         rep stos dword ptr es:[edi]
0040109E   .  68 A0804000   push offset <InlineHo.??_C@_0BF@ODOO@?S?P?H?K?$L>;  有人調(diào)用MessageBox!\n
004010A3   .  66:AB         stos word ptr es:[edi]
004010A5   .  E8 4C030000   call InlineHo.printfsbh_decommit_pagesem_page
004010AA   .  8B8424 100500>mov eax,dword ptr ss:[esp+0x510]
004010B1   .  83C4 04       add esp,0x4
004010B4   .  8D8C24 040100>lea ecx,dword ptr ss:[esp+0x104]
004010BB   .  50            push eax                                         ; /String2 = 00000001 ???
004010BC   .  51            push ecx                                         ; |String1 = 00000005
004010BD   .  FF15 04704000 call dword ptr ds:[<&KERNEL32.lstrcpyA>]         ; \lstrcpyA
004010C3   .  8D9424 040100>lea edx,dword ptr ss:[esp+0x104]
004010CA   .  68 7C804000   push offset <InlineHo.??_C@_0CC@ELLF@?6?7Message>; /\n\tMessageBox Hacked by pediy.com!
004010CF   .  52            push edx                                         ; |ConcatString = ""
004010D0   .  FF15 00704000 call dword ptr ds:[<&KERNEL32.lstrcatA>]         ; \lstrcatA
004010D6   .  8D4C24 04     lea ecx,dword ptr ss:[esp+0x4]

總結(jié):通過(guò)在執(zhí)行真正的目標(biāo)函數(shù)之前執(zhí)行事先插入的代碼,獲得了程序執(zhí)行過(guò)程的決定權(quán)(Hook終極奧義)。

AddressHook 是指通過(guò)修改數(shù)據(jù)(指一些函數(shù)的地址也可能是偏移量)進(jìn)行Hook方法。

Hook的典型過(guò)程

不管是哪種Hook都需要自定義的函數(shù)來(lái)代替被Hook的函數(shù)。稱(chēng)之為Detour函數(shù)。其原型、調(diào)用約定、返回值都與原函數(shù)一模一樣。

對(duì)函數(shù)調(diào)用的約定為_(kāi)cdecl,WindowAPI通常是stdcall調(diào)用。

AddressHook 是指通過(guò)修改數(shù)據(jù)(指一些函數(shù)的地址也可能是偏移量)進(jìn)行Hook方法。

以messageBox原型定義一個(gè)函數(shù)指針類(lèi)型

實(shí)現(xiàn)IATHook的函數(shù)見(jiàn)上

虛函數(shù)Hook

(1)確定TargetFun在TargetClass虛函數(shù)表中的位置及函數(shù)原型

(2)定義DetourClass和TrampolineClass

(3)修改虛函數(shù)表,實(shí)現(xiàn)Hook

InlineHook的實(shí)施過(guò)程中要明確的3個(gè)概念

TargetFun : 要被Hook的目標(biāo)函數(shù);

DetourFun:用于代替TargetFun的自定義函數(shù);

TargetpolineFun:該函數(shù)不是一個(gè)完成的函數(shù),而是調(diào)用用原函數(shù)的入口。在該函數(shù)中要執(zhí)行TargetFun中被替換的前幾條指令,也就是說(shuō),TrampolinentFun和TargetFun中被Hook位置之后的部分構(gòu)成了一個(gè)完成的函數(shù)。

實(shí)現(xiàn)Inline Hook 時(shí)需要解決兩個(gè)問(wèn)題:一是確定要采用的Hook方式。這樣才能確定要寫(xiě)入何種機(jī)器碼來(lái)完成執(zhí)行的轉(zhuǎn)移。

1、確定Hook方式及需要Trampoline中執(zhí)行的指令

2、準(zhǔn)備TrampolineFun函數(shù)

3、準(zhǔn)備JMP指令并寫(xiě)入

4、call Hook

總結(jié)

以上是生活随笔為你收集整理的Hook技术简单介绍的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。