利用Windows頁防護機制進行函數(shù)掛鉤
摘要
Guard Pages是一種操作系統(tǒng)內存保護機制,旨在檢測和防止對內存的非法訪問。在Windows操作系統(tǒng)中,Guard Pages通常被用作內存頁的末尾,它們通常是未分配或不可訪問的內存頁。
當程序試圖訪問一個Guard Page時,操作系統(tǒng)會檢測到這種訪問并引發(fā)異常,通常是訪問沖突異常(如訪問違例異常)。這種異常的引發(fā)使得程序能夠及時檢測到內存訪問錯誤,從而可以采取適當?shù)拇胧缃K止程序或記錄錯誤信息,以防止?jié)撛诘陌踩┒幢焕谩?/p>
在Windows Hooking中,利用Guard Pages可以用于檢測和攔截對特定內存區(qū)域的訪問,從而實現(xiàn)對系統(tǒng)功能的修改或監(jiān)視。這種技術通常被用于軟件調試、安全研究和惡意軟件分析等領域。
實現(xiàn)過程
整體代碼如下:
#include <windows.h>
#include <stdio.h>
// Hook函數(shù)功能
HANDLE hook(LPSECURITY_ATTRIBUTES rcx, SIZE_T rdx, LPTHREAD_START_ROUTINE r8, LPVOID r9, DWORD stck1, LPDWORD stck2) {
MessageBoxA(0, "CreateThread() was called!", "YAY!", 0);
MessageBoxA(0, "Hooked CreateThread", "YAY!", 0);
// 這里調用原始CreateThread函數(shù)
//return CreateThread(rcx, rdx, r8, r9, stck1, stck2);
return NULL;
}
LONG WINAPI handler(EXCEPTION_POINTERS * ExceptionInfo) {
if (ExceptionInfo->ExceptionRecord->ExceptionCode == STATUS_GUARD_PAGE_VIOLATION) {
if (ExceptionInfo->ContextRecord->Rip == (DWORD64) &CreateThread) {
printf("[!] Exception (%#llx)!" , ExceptionInfo->ExceptionRecord->ExceptionAddress);
printf("\nClick a key to continue...\n");
getchar();
ExceptionInfo->ContextRecord->Rip = (DWORD64) &hook;
printf("Modified RIP Points to: %#llx\n", ExceptionInfo->ContextRecord->Rip);
printf("Hook Function = %#llx\n", (DWORD64) &hook);
}
return EXCEPTION_CONTINUE_EXECUTION;
}
return EXCEPTION_CONTINUE_SEARCH;
}
int main() {
DWORD old = 0;
DWORD param = 5000;
AddVectoredExceptionHandler(1, &handler);
VirtualProtect(&CreateThread, 1, PAGE_EXECUTE_READ | PAGE_GUARD, &old);
printf("CreateThread addr = %#p\n", &CreateThread);
HANDLE hThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE) &Sleep, ?m, 0, 0);
WaitForSingleObject(hThread, param);
printf("YEP!\n");
return 0;
}
頭文件部分:
代碼從包含必要的頭文件開始,包括 <windows.h> 和 <stdio.h>,它們分別提供了Windows API和標準I/O操作的函數(shù)和定義。
Hook函數(shù):
定義了鉤子函數(shù)hook。這個函數(shù)旨在充當CreateThread API函數(shù)的鉤子,該函數(shù)負責在Windows應用程序中創(chuàng)建線程。 在鉤子函數(shù)內部,顯示了兩個消息框,指示CreateThread函數(shù)已被調用,并且它已經(jīng)被這段代碼“hook”了。在這段代碼中,原始的CreateThread函數(shù)沒有被調用。
異常處理
定義了一個處理函數(shù), 并使用AddVectoredExceptionHandler將其設置為異常處理程序, 這個函數(shù)被設計用來處理異常,特別是STATUS_GUARD_PAGE_VIOLATION,這是一種在受保護的內存頁上嘗試執(zhí)行代碼時發(fā)生的異常。 如果異常代碼是STATUS_GUARD_PAGE_VIOLATION,并且指令指針(Rip)指向CreateThread函數(shù),它會顯示一條消息,并修改Rip指向鉤子函數(shù)。 任何嘗試調用執(zhí)行CreateThread函數(shù)的操作都將被重定向到執(zhí)行鉤子函數(shù)。
主函數(shù)
在主函數(shù)內部,聲明了一個變量old,但未被使用。 一個param變量被設置為5000,并調用AddVectoredExceptionHandler函數(shù)將處理程序函數(shù)注冊為異常處理程序。 使用VirtualProtect在CreateThread函數(shù)上設置了一個守衛(wèi)頁面。如果嘗試執(zhí)行它,這將觸發(fā)處理程序函數(shù)。 使用printf顯示了CreateThread函數(shù)的地址。 使用CreateThread創(chuàng)建了一個新線程,但似乎并沒有提供任何實際目的,因為該線程只是休眠了5000毫秒。 等待線程結束后,打印“YEP!”。
測試
將代碼編譯后執(zhí)行,效果如下:
圖片