亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

微軟Detours Hook庫(kù)編譯與使用教程

 更新時(shí)間:2024年08月16日 10:12:18   作者:微軟技術(shù)分享  
Detours 是一個(gè)兼容多個(gè)Windows系列操作系統(tǒng)版本(包括 Windows XP 到 Windows 11)的工具庫(kù),Detours 是微軟開(kāi)發(fā)的一個(gè)強(qiáng)大的Windows API鉤子庫(kù),用于監(jiān)視和攔截函數(shù)調(diào)用,這篇文章給大家介紹微軟Detours Hook庫(kù)編譯與使用,感興趣的朋友一起看看吧

Detours 是微軟開(kāi)發(fā)的一個(gè)強(qiáng)大的Windows API鉤子庫(kù),用于監(jiān)視和攔截函數(shù)調(diào)用。它廣泛應(yīng)用于微軟產(chǎn)品團(tuán)隊(duì)和眾多獨(dú)立軟件開(kāi)發(fā)中,旨在無(wú)需修改原始代碼的情況下實(shí)現(xiàn)函數(shù)攔截和修改。Detours 在調(diào)試、監(jiān)控、日志記錄和性能分析等方面表現(xiàn)出色,已成為開(kāi)發(fā)者的重要工具。本章將指導(dǎo)讀者編譯并使用Detours庫(kù),通過(guò)實(shí)現(xiàn)一個(gè)簡(jiǎn)單的彈窗替換功能,幫助讀者熟悉該庫(kù)的使用技巧。

Detours 是一個(gè)兼容多個(gè)Windows系列操作系統(tǒng)版本(包括 Windows XPWindows 11)的工具庫(kù)。它現(xiàn)在在 MIT 開(kāi)源許可證下發(fā)布,簡(jiǎn)化了開(kāi)發(fā)者的使用許可流程,并允許社區(qū)利用開(kāi)源工具和流程來(lái)支持其發(fā)展,目前該庫(kù)的穩(wěn)定版本為4.0.1讀者可通過(guò)如下官方鏈接自行下載到本地。

Detours 4.0.1:https://github.com/microsoft/Detours/releases

下載文件后打開(kāi)目錄,其中src目錄下存儲(chǔ)的是Detours庫(kù)的源代碼,而samples則是一些使用案例,當(dāng)準(zhǔn)備就緒后讀者需要打開(kāi)Visual Studio開(kāi)發(fā)者命令提示符,你可以從開(kāi)始菜單中找到Visual Studio Tools工具菜單,并在其中找到VS20XX x86 本機(jī)工具命令提示Developer Command Prompt for VS 20XX字樣,此處以x86為例,在命令提示符中跳轉(zhuǎn)到Detours源代碼目錄,運(yùn)行 nmake 命令執(zhí)行編譯。

如果一切順利,這將會(huì)編譯Detours庫(kù)并生成所需的二進(jìn)制文件,其中include保存有頭文件信息,而lib.X86則包含有detours.lib庫(kù)文件,如下圖中所示。

接著我們打開(kāi)Visual Studio工具,新建一個(gè)可執(zhí)行控制臺(tái)項(xiàng)目并配置包含引用目錄及庫(kù)目錄,如下圖所示;

接著我們來(lái)實(shí)現(xiàn)攔截并替換彈窗功能,在Windows中彈窗接口為MessageBoxW函數(shù),首先需要定義OriginalMessageBoxW的函數(shù)指針,該指針用于指向原始的MessageBoxW函數(shù)地址。接著定義CustomMessageBoxW函數(shù),在函數(shù)內(nèi)首先將彈窗提示替換為自定義內(nèi)容,并攜帶該參數(shù)調(diào)用OriginalMessageBoxW原函數(shù)地址,以此來(lái)實(shí)現(xiàn)替代彈窗功能。

#include <iostream>
#include <Windows.h>
#include "detours.h"
#pragma comment(lib, "detours.lib")
// 定義指向原始 MessageBoxW 函數(shù)的指針
static int (WINAPI *OriginalMessageBoxW)(
	_In_opt_ HWND hWnd,
	_In_opt_ LPCWSTR lpText,
	_In_opt_ LPCWSTR lpCaption,
	_In_ UINT uType) = MessageBoxW;
// 自定義的 MessageBoxW 函數(shù),用于替換原始函數(shù)
static int WINAPI CustomMessageBoxW(
	_In_opt_ HWND hWnd,
	_In_opt_ LPCWSTR lpText,
	_In_opt_ LPCWSTR lpCaption,
	_In_ UINT uType)
{
	// 調(diào)用原始的 MessageBoxW 函數(shù),但修改了顯示的文本
	return OriginalMessageBoxW(hWnd, L"hello lyshark", L"MsgBox", MB_OK);
}

接著就是對(duì)掛鉤與摘鉤的函數(shù)封裝,分別定義這兩個(gè)函數(shù),其中InstallHook 函數(shù)通過(guò)Detours事務(wù)的方式,將原始的 MessageBoxW 函數(shù)指針替換為自定義的 CustomMessageBoxW 函數(shù)指針,從而攔截并修改該函數(shù)的行為。相反,RemoveHook 函數(shù)則通過(guò)類(lèi)似的事務(wù)機(jī)制,將自定義的 CustomMessageBoxW 函數(shù)指針替換回原始的 MessageBoxW 函數(shù)指針,以恢復(fù)函數(shù)的原始行為。

// 安裝鉤子
void InstallHook()
{
	// 開(kāi)始一個(gè) Detours 事務(wù)
	if (DetourTransactionBegin() == NO_ERROR)
	{
		// 更新當(dāng)前線(xiàn)程以準(zhǔn)備進(jìn)行鉤子操作
		if (DetourUpdateThread(GetCurrentThread()) == NO_ERROR)
		{
			// 將原始函數(shù)指針替換為自定義的函數(shù)指針
			if (DetourAttach(&(PVOID&)OriginalMessageBoxW, CustomMessageBoxW) == NO_ERROR)
			{
				// 提交事務(wù),完成鉤子安裝
				if (DetourTransactionCommit() == NO_ERROR)
				{
					printf("鉤子已成功安裝。\n");
					return;
				}
			}
		}
		// 如果任何步驟失敗,則中止事務(wù)
		DetourTransactionAbort();
	}
	printf("安裝鉤子失敗。\n");
}
// 移除鉤子
void RemoveHook()
{
	// 開(kāi)始一個(gè) Detours 事務(wù)
	if (DetourTransactionBegin() == NO_ERROR)
	{
		// 更新當(dāng)前線(xiàn)程以準(zhǔn)備進(jìn)行鉤子操作
		if (DetourUpdateThread(GetCurrentThread()) == NO_ERROR)
		{
			// 將自定義的函數(shù)指針替換回原始函數(shù)指針
			if (DetourDetach(&(PVOID&)OriginalMessageBoxW, CustomMessageBoxW) == NO_ERROR)
			{
				// 提交事務(wù),完成鉤子移除
				if (DetourTransactionCommit() == NO_ERROR)
				{
					printf("鉤子已成功移除。\n");
					return;
				}
			}
		}
		// 如果任何步驟失敗,則中止事務(wù)
		DetourTransactionAbort();
	}
	printf("移除鉤子失敗。\n");
}

在程序入口處,我們分三次調(diào)用MessageBoxW函數(shù),其中第一次調(diào)用及最后依次調(diào)用均在未掛鉤狀態(tài)下進(jìn)行,第二次調(diào)用之前通過(guò)InstallHook()安裝鉤子,之后再調(diào)用MessageBoxW函數(shù),并在調(diào)用結(jié)束后通過(guò)RemoveHook()移除鉤子,編譯這段代碼。

int main(int argc, char *argv[])
{
	// 顯示原始的消息框
	MessageBoxW(NULL, L"hello world", L"MsgBox", MB_OK);
	// 安裝鉤子并顯示修改后的消息框
	InstallHook();
	MessageBoxW(NULL, L"hello world", L"MsgBox", MB_OK);
	// 移除鉤子并恢復(fù)為原始的消息框
	RemoveHook();
	MessageBoxW(NULL, L"hello world", L"MsgBox", MB_OK);
	system("pause");
	return 0;
}

使用x64dbg調(diào)試器加載運(yùn)行代碼,并尋找到程序的入口處,由于此處的入口處僅僅是一個(gè)main(int argc, char *argv[])所以,在匯編中我們可以直接尋找三個(gè)參數(shù)的關(guān)鍵變量位置,找到后即可定位到入口處,此時(shí)直接跟進(jìn)去就可以看到主函數(shù)代碼;

如下圖中所示,當(dāng)0x00321314處被執(zhí)行后則鉤子生效,當(dāng)鉤子生效后則底部0x00321347處的地址將被替換為自定義鉤子地址,此時(shí)在其之上的入棧操作數(shù)將會(huì)失效;

繼續(xù)跟進(jìn)0x00321347這個(gè)地址,如下圖所示該地址中的入口處已被替換為我們自定義的彈窗位置,此處是一個(gè)jmp無(wú)條件跳轉(zhuǎn),預(yù)示著將要轉(zhuǎn)向。

我們繼續(xù)跟進(jìn)這個(gè)轉(zhuǎn)向地址,則可看到如下圖所示的反匯編指令集,這里的代碼重新入棧了新的字符串變量,并在入棧后調(diào)用了原始MessageBoxW函數(shù),并依次來(lái)實(shí)現(xiàn)替換函數(shù)彈窗中的內(nèi)容。

此時(shí),當(dāng)繼續(xù)調(diào)用原始函數(shù)時(shí),雖函數(shù)中的提示信息為hello world但由于掛鉤生效了則提示信息會(huì)被變更為hello lyshark,以此來(lái)實(shí)現(xiàn)對(duì)函數(shù)功能的替換與更正。

在實(shí)際應(yīng)用中,我們通常通過(guò) DLL 注入的方式使用 Detours 庫(kù),以便更好地實(shí)現(xiàn)對(duì)第三方程序的功能替換或修改,例如改變彈窗提示。這種方法能夠更高效地應(yīng)用 Hook 技術(shù),實(shí)現(xiàn)對(duì)目標(biāo)程序行為的控制和定制。

例如如下所示的這段代碼,當(dāng)使用注入器將其注入到第三方進(jìn)程中時(shí),首先DLL_PROCESS_ATTACH將被執(zhí)行也就是開(kāi)始掛鉤,在掛鉤函數(shù)中通過(guò)DetourFindFunction尋找到MessageBoxW函數(shù)的入口地址,并將其存儲(chǔ)到OriginalMessageBoxW指針中,并通過(guò)DetourAttach對(duì)其進(jìn)行掛鉤。

#include <windows.h>
#include "detours.h"
#include "detver.h"
#pragma comment(lib, "detours.lib")
// 定義 MessageBoxW 函數(shù)指針類(lèi)型
static int (WINAPI *OriginalMessageBoxW)(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType) = NULL;
// 自定義的 MessageBoxW 函數(shù)
int WINAPI MyMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType)
{
	// 可以在這里添加自定義邏輯
	return OriginalMessageBoxW(hWnd, L"hello lyshark", lpCaption, uType);
}
// 安裝鉤子
void InstallHooks()
{
	DetourRestoreAfterWith();
	// 開(kāi)始事務(wù)
	DetourTransactionBegin();
	// 更新當(dāng)前線(xiàn)程
	DetourUpdateThread(GetCurrentThread());
	// 查找并攔截 MessageBoxW 函數(shù)
	OriginalMessageBoxW = (int (WINAPI *)(HWND, LPCWSTR, LPCWSTR, UINT))DetourFindFunction("User32.dll", "MessageBoxW");
	if (OriginalMessageBoxW != NULL)
	{
		// 開(kāi)始掛鉤
		DetourAttach(&(PVOID&)OriginalMessageBoxW, MyMessageBoxW);
	}
	// 提交事務(wù)
	DetourTransactionCommit();
}
// 卸載鉤子
void UninstallHooks()
{
	// 開(kāi)始事務(wù)
	DetourTransactionBegin();
	// 更新當(dāng)前線(xiàn)程
	DetourUpdateThread(GetCurrentThread());
	// 撤銷(xiāo)攔截 MessageBoxW 函數(shù)
	if (OriginalMessageBoxW != NULL)
	{
		// 摘除鉤子
		DetourDetach(&(PVOID&)OriginalMessageBoxW, MyMessageBoxW);
	}
	// 提交事務(wù)
	DetourTransactionCommit();
}
// DLL 入口點(diǎn)
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
		// 禁用線(xiàn)程庫(kù)調(diào)用
		DisableThreadLibraryCalls(hModule);
		// 安裝鉤子
		InstallHooks();
		break;
	case DLL_THREAD_ATTACH:
		break;
	case DLL_THREAD_DETACH:
		break;
	case DLL_PROCESS_DETACH:
		// 卸載鉤子
		UninstallHooks();
		break;
	}
	return TRUE;
}

當(dāng)掛鉤成功后則進(jìn)程中任何調(diào)用彈窗的提示信息都將被替換成hello lyshark提示,而標(biāo)題欄因未被替換則依然會(huì)保持原始狀態(tài),如下圖是注入之前與注入之后的提示變化;

至此本章內(nèi)容結(jié)束,其實(shí)Hook在安全領(lǐng)域的應(yīng)用相當(dāng)廣泛,例如可以監(jiān)控和攔截指定的API調(diào)用,檢測(cè)分析程序的行為,攔截網(wǎng)絡(luò)通信函數(shù),監(jiān)控?cái)?shù)據(jù)傳輸,攔截文件操作和注冊(cè)表訪(fǎng)問(wèn)等等,本文也只是拋磚引玉讓讀者能認(rèn)識(shí)Detours庫(kù)。更多有用的案例可自行參考samples目錄下的內(nèi)容學(xué)習(xí)。

到此這篇關(guān)于微軟Detours Hook庫(kù)編譯與使用的文章就介紹到這了,更多相關(guān)微軟Detours Hook庫(kù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論