日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

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

生活随笔

當(dāng)前位置: 首頁(yè) >

(64)句柄表,遍历所有进程的句柄表实现反调试

發(fā)布時(shí)間:2025/3/21 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 (64)句柄表,遍历所有进程的句柄表实现反调试 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、內(nèi)核對(duì)象,句柄

這次課討論的內(nèi)核對(duì)象是指創(chuàng)建時(shí)需要指定 LPSECURITY_ATTRIBUTES 參數(shù)的對(duì)象,例如 Mutex, Thread。

調(diào)用 CreateThread 等函數(shù)會(huì)返回一個(gè) HANDLE 類(lèi)型值,這種就叫句柄,它對(duì)應(yīng)一個(gè)內(nèi)核對(duì)象;

調(diào)用 CloseHandle 函數(shù)對(duì)某個(gè)內(nèi)核對(duì)象計(jì)數(shù)減一,當(dāng)內(nèi)核對(duì)象計(jì)數(shù)為0,這個(gè)對(duì)象就被銷(xiāo)毀了。

內(nèi)核對(duì)象在內(nèi)核存儲(chǔ),直接把地址給3環(huán)用很不安全,所以微軟設(shè)計(jì)了句柄(HANDLE)給3環(huán)使用,句柄是一個(gè)整數(shù),它的值除以4是句柄表的下標(biāo),通過(guò)下標(biāo)能找到存儲(chǔ)在句柄表里的句柄表項(xiàng),每個(gè)占8字節(jié)。

二、句柄表,句柄表項(xiàng)

1.句柄表結(jié)構(gòu)

句柄表存儲(chǔ)在 EPROCESS.ObjectTable.TableCode 里:

kd> dt _HANDLE_TABLE ntdll!_HANDLE_TABLE+0x000 TableCode : Uint4B+0x004 QuotaProcess : Ptr32 _EPROCESS+0x008 UniqueProcessId : Ptr32 Void+0x00c HandleTableLock : [4] _EX_PUSH_LOCK+0x01c HandleTableList : _LIST_ENTRY+0x024 HandleContentionEvent : _EX_PUSH_LOCK+0x028 DebugInfo : Ptr32 _HANDLE_TRACE_DEBUG_INFO+0x02c ExtraInfoPages : Int4B+0x030 FirstFree : Uint4B+0x034 LastFree : Uint4B+0x038 NextHandleNeedingPool : Uint4B+0x03c HandleCount : Int4B+0x040 Flags : Uint4B+0x040 StrictFIFO : Pos 0, 1 Bit

句柄表項(xiàng)每個(gè)占8字節(jié),一個(gè)頁(yè)4KB,所以一個(gè)頁(yè)能存儲(chǔ)512個(gè)句柄表項(xiàng),當(dāng)進(jìn)程中的句柄數(shù)量超過(guò)512,句柄表就會(huì)以分級(jí)形式存儲(chǔ),最多三級(jí):

特別留意 TableCode 的第2位,它表明了句柄表的結(jié)構(gòu),如果第2位是01,表示現(xiàn)在句柄表有兩級(jí), TableCode 指向的表存儲(chǔ)了 4KB / 4 = 1024 個(gè)句柄表的地址,每個(gè)地址指向一個(gè)句柄表。

我們可以編程,構(gòu)造超過(guò)512個(gè)句柄,看看 TableCode 的低2位是否是01:

#include "stdafx.h" #include <windows.h>int _tmain(int argc, _TCHAR* argv[]) {DWORD PID;HANDLE hPro = NULL;HWND hwnd = FindWindowA(NULL, "計(jì)算器");GetWindowThreadProcessId(hwnd, &PID);for (int i = 0; i < 600; i++){//hPro = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, TRUE, PID);hPro = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, TRUE, PID);printf("句柄:%x\n", hPro);}SetHandleInformation(hPro, HANDLE_FLAG_PROTECT_FROM_CLOSE, HANDLE_FLAG_PROTECT_FROM_CLOSE);getchar();return 0; }

確實(shí)是這樣的,觀察 +0x000 TableCode : 0xe128f001

kd> dt 0xe1be0f00 _HANDLE_TABLE ntdll!_HANDLE_TABLE+0x000 TableCode : 0xe128f001+0x004 QuotaProcess : 0x81df0da0 _EPROCESS+0x008 UniqueProcessId : 0x00000614 Void+0x00c HandleTableLock : [4] _EX_PUSH_LOCK+0x01c HandleTableList : _LIST_ENTRY [ 0x8055c448 - 0xe2307b04 ]+0x024 HandleContentionEvent : _EX_PUSH_LOCK+0x028 DebugInfo : (null) +0x02c ExtraInfoPages : 0n0+0x030 FirstFree : 0x99c+0x034 LastFree : 0+0x038 NextHandleNeedingPool : 0x1000+0x03c HandleCount : 0n613+0x040 Flags : 0+0x040 StrictFIFO : 0y0

2.通過(guò)句柄表項(xiàng)找到內(nèi)核對(duì)象(句柄數(shù)量少于512)

下面我們編寫(xiě)一個(gè)程序,打開(kāi)計(jì)算器的進(jìn)程句柄,然后在windbg里通過(guò)句柄表找到計(jì)算器的EPROCESS:

#include "stdafx.h" #include <windows.h>int _tmain(int argc, _TCHAR* argv[]) {DWORD PID;HANDLE hPro = NULL;HWND hwnd = FindWindowA(NULL, "計(jì)算器");GetWindowThreadProcessId(hwnd, &PID);for (int i = 0; i < 100; i++){//hPro = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, TRUE, PID);hPro = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, TRUE, PID);printf("句柄:%x\n", hPro);}SetHandleInformation(hPro, HANDLE_FLAG_PROTECT_FROM_CLOSE, HANDLE_FLAG_PROTECT_FROM_CLOSE);getchar();return 0; }

以 1c0 為例,除以4得到 70.找到程序的句柄表:

kd> dt 0xe14be1e0 _HANDLE_TABLE ntdll!_HANDLE_TABLE+0x000 TableCode : 0xe11a4000+0x004 QuotaProcess : 0x81e6b020 _EPROCESS+0x008 UniqueProcessId : 0x00000544 Void+0x00c HandleTableLock : [4] _EX_PUSH_LOCK+0x01c HandleTableList : _LIST_ENTRY [ 0x8055c448 - 0xe2307b04 ]+0x024 HandleContentionEvent : _EX_PUSH_LOCK+0x028 DebugInfo : (null) +0x02c ExtraInfoPages : 0n0+0x030 FirstFree : 0x1c8+0x034 LastFree : 0+0x038 NextHandleNeedingPool : 0x800+0x03c HandleCount : 0n113+0x040 Flags : 0+0x040 StrictFIFO : 0y0

0xe11a4000 低2位是0,表示當(dāng)前進(jìn)程的句柄表只有一級(jí),然后我們找一下下標(biāo)為70的項(xiàng):

kd> dq 0xe11a4000+70*8 e11a4380 0000003a`81dd800b 0200003a`81dd800b e11a4390 000001cc`00000000 000001d0`00000000 e11a43a0 000001d4`00000000 000001d8`00000000 e11a43b0 000001dc`00000000 000001e0`00000000 e11a43c0 000001e4`00000000 000001e8`00000000 e11a43d0 000001ec`00000000 000001f0`00000000 e11a43e0 000001f4`00000000 000001f8`00000000 e11a43f0 000001fc`00000000 00000200`00000000

我們這里打印了下標(biāo)70的項(xiàng),同時(shí),+8就是下標(biāo)71的項(xiàng),就是我們調(diào)用 SetHandleInformation 修改了句柄屬性的最后一個(gè)項(xiàng),觀察它們的區(qū)別,最高字節(jié)不相同。

關(guān)于句柄表項(xiàng)這64位,網(wǎng)上是沒(méi)有文檔的,只能自己分析。這里先介紹低32位,低32位的低3位清零后就是內(nèi)核對(duì)象頭(此處是EPROCESS)的虛擬地址,注意,指向內(nèi)核對(duì)象頭 OBJECT_HEADER,這個(gè)結(jié)構(gòu)大小是 0x18,所以要加上 0x18 才能找到 EPROCESS.

所以計(jì)算器的 EPROCESS 是在 81dd8008+18, dt 驗(yàn)證一下:

kd> dt 81dd8008+18 _EPROCESS ntdll!_EPROCESS+0x000 Pcb : _KPROCESS+0x06c ProcessLock : _EX_PUSH_LOCK ...+0x174 ImageFileName : [16] "calc.exe" ...

如果句柄數(shù)量超過(guò)了512,意味著句柄表的結(jié)構(gòu)就是二級(jí)或者三級(jí)的,這種情況比較復(fù)雜,限于篇幅,我打算另寫(xiě)一篇博客單獨(dú)介紹。


3. 句柄表項(xiàng)其他位

句柄表項(xiàng)一個(gè)8字節(jié),它的64個(gè)位的用途是沒(méi)有文檔說(shuō)明的,只能自己分析,以下內(nèi)容屬于拓展,不保證內(nèi)容完整且正確,需要得到更準(zhǔn)確的情報(bào),請(qǐng)逆向或閱讀源碼。

63-56 給 SetHandleInformation 函數(shù)用,如果參數(shù)是HANDLE_FLAG_PROTECT_FROM_CLOSE(0x02),那么這個(gè)字節(jié)會(huì)設(shè)置成0x0200,剛才的實(shí)驗(yàn)已經(jīng)驗(yàn)證過(guò)了。

55-48 這個(gè)字節(jié)恒為0 存疑!140說(shuō) OpenProcess(PROCESS_ALL_ACCESS 就不是0

47-32 位存儲(chǔ)的是訪(fǎng)問(wèn)掩碼,OpenProcess 的第一個(gè)參數(shù)會(huì)影響這里的值。

31-3位加上第三位清零存儲(chǔ)的是內(nèi)核對(duì)象的地址.

低3位是屬性,2位默認(rèn)是0;1位表示該句柄是否可繼承;0位默認(rèn)為1.

三、實(shí)現(xiàn)用句柄表反調(diào)試:當(dāng)調(diào)試器attach時(shí)報(bào)錯(cuò)

思路:遍歷所有其他進(jìn)程句柄表,看哪個(gè)進(jìn)程的句柄表中保護(hù)自己的進(jìn)程,如果有,說(shuō)明正在被調(diào)試。

用一個(gè)驅(qū)動(dòng)不停地遍歷進(jìn)程鏈表,然后遍歷進(jìn)程的句柄表,如果發(fā)現(xiàn)句柄表項(xiàng)和游戲EPROCESS相等,就意味著被 OpenProcess 了,就認(rèn)為是被調(diào)試了。

運(yùn)行結(jié)果:沒(méi)被調(diào)試

運(yùn)行結(jié)果:被調(diào)試

3環(huán)代碼

// Game.cpp : 定義控制臺(tái)應(yīng)用程序的入口點(diǎn)。 //#include "stdafx.h" #include <windows.h>//----------------------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------------------typedef LONG (__stdcall *HBGCOMMUNICATION) (IN ULONG OpCode, IN OUT PVOID p1, IN OUT PVOID p2, IN OUT PVOID p3);//----------------------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------------------BOOL LoadDriver(PCWSTR lpszDriverName, PCWSTR lpszDriverPath); void UnLoadDriver(PCWSTR lpszDriverName);//----------------------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------------------#define DRIVER_NAME L"HbgProtect" #define DRIVER_PATH L"HbgProtect.sys"#define OP_CHECK_DEBUG 50HBGCOMMUNICATION HbgCommunication = NULL;//----------------------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------------------int _tmain(int argc, _TCHAR* argv[]) {HbgCommunication = (HBGCOMMUNICATION)GetProcAddress(LoadLibraryA("ntdll.dll"),"ZwQuerySystemInformation");if (HbgCommunication == NULL) {printf("獲取函數(shù)地址失敗. %d\n",GetLastError());getchar();return 1;}// 加載游戲保護(hù)驅(qū)動(dòng)LoadDriver(DRIVER_NAME,DRIVER_PATH);while (!GetAsyncKeyState('Q')){Sleep(1000);BOOL IsDebugged = FALSE;HbgCommunication(OP_CHECK_DEBUG,&IsDebugged,NULL,NULL);if (IsDebugged){printf("-----------------正在被調(diào)試!\n");}else{printf("沒(méi)有被調(diào)試.\n");}}UnLoadDriver(DRIVER_NAME);getchar();return 0; }BOOL LoadDriver(PCWSTR lpszDriverName, PCWSTR lpszDriverPath) {// 獲取驅(qū)動(dòng)完整路徑WCHAR szDriverFullPath[MAX_PATH] = { 0 };GetFullPathNameW(lpszDriverPath,MAX_PATH,szDriverFullPath,NULL);//printf("%s\n", szDriverFullPath);// 打開(kāi)服務(wù)控制管理器SC_HANDLE hServiceMgr = NULL; // SCM管理器句柄 hServiceMgr = OpenSCManagerW(NULL,NULL,SC_MANAGER_ALL_ACCESS);if (NULL == hServiceMgr){printf("OpenSCManagerW 失敗, %d\n", GetLastError());return FALSE;}printf("打開(kāi)服務(wù)控制管理器成功.\n");// 創(chuàng)建驅(qū)動(dòng)服務(wù)SC_HANDLE hServiceDDK = NULL; // NT驅(qū)動(dòng)程序服務(wù)句柄hServiceDDK = CreateServiceW(hServiceMgr,lpszDriverName,lpszDriverName,SERVICE_ALL_ACCESS,SERVICE_KERNEL_DRIVER,SERVICE_DEMAND_START,SERVICE_ERROR_IGNORE,szDriverFullPath,NULL,NULL,NULL,NULL,NULL);if (NULL == hServiceDDK){DWORD dwErr = GetLastError();if (dwErr != ERROR_IO_PENDING && dwErr != ERROR_SERVICE_EXISTS){printf("創(chuàng)建驅(qū)動(dòng)服務(wù)失敗, %d\n", dwErr);return FALSE;}}printf("創(chuàng)建驅(qū)動(dòng)服務(wù)成功.\n");// 驅(qū)動(dòng)服務(wù)已經(jīng)創(chuàng)建,打開(kāi)服務(wù)hServiceDDK = OpenServiceW(hServiceMgr,lpszDriverName,SERVICE_ALL_ACCESS);if (!StartService(hServiceDDK, NULL, NULL)){DWORD dwErr = GetLastError();if (dwErr != ERROR_SERVICE_ALREADY_RUNNING){printf("運(yùn)行驅(qū)動(dòng)服務(wù)失敗, %d\n", dwErr);return FALSE;}}printf("運(yùn)行驅(qū)動(dòng)服務(wù)成功.\n");if (hServiceDDK){CloseServiceHandle(hServiceDDK);}if (hServiceMgr){CloseServiceHandle(hServiceMgr);}return TRUE; }void UnLoadDriver(PCWSTR lpszDriverName) {SC_HANDLE hServiceMgr = OpenSCManagerW(0,0,SC_MANAGER_ALL_ACCESS);SC_HANDLE hServiceDDK = OpenServiceW(hServiceMgr,lpszDriverName,SERVICE_ALL_ACCESS);SERVICE_STATUS SvrStatus;ControlService(hServiceDDK,SERVICE_CONTROL_STOP,&SvrStatus);DeleteService(hServiceDDK);if (hServiceDDK){CloseServiceHandle(hServiceDDK);}if (hServiceMgr){CloseServiceHandle(hServiceMgr);} }

驅(qū)動(dòng)代碼

#include <ntddk.h>//----------------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------------typedef NTSTATUS (__stdcall *NTQUERYSYSTEMINFORMATION) (IN ULONG SystemInformationClass, OUT PVOID SystemInformation, IN ULONG SystemInformationLength, OUT PULONG ReturnLength);typedef struct _LDR_DATA_TABLE_ENTRY {LIST_ENTRY InLoadOrderLinks;LIST_ENTRY InMemoryOrderLinks;LIST_ENTRY InInitializationOrderLinks;PVOID DllBase;PVOID EntryPoint;ULONG SizeOfImage;UNICODE_STRING FullDllName;UNICODE_STRING BaseDllName;ULONG Flags;UINT16 LoadCount;UINT16 TlsIndex;LIST_ENTRY HashLinks;PVOID SectionPointer;ULONG CheckSum;ULONG TimeDateStamp;PVOID LoadedImports;PVOID EntryPointActivationContext;PVOID PatchInformation; } LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;//----------------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------------NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path); VOID DriverUnload(PDRIVER_OBJECT driver); ULONG GetProcessEprocessAddr(char *processname); BOOLEAN CheckProcessDebugged(ULONG EprocessAddress); VOID PageProtectOff(); VOID PageProtectOn(); VOID GetKernelBase(PDRIVER_OBJECT driver, PVOID *pKrnlBase, PULONG uKrnlImageSize); PVOID MemorySearch(PVOID bytecode, ULONG bytecodeLen, PVOID pBeginAddress, PVOID pEndAddress); void InlineHookNtQuerySystemInformation(); void UnsetInlineHookNtQuerySystemInformation(); void HbgNtQuerySystemInformation(IN ULONG OpCode, IN OUT PVOID p1, IN OUT PVOID p2, IN OUT PVOID p3);//----------------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------------#define OP_CHECK_DEBUG 50#define GAMEIMAGENAME "Game.exe" ULONG g_EprocessAddress;PDRIVER_OBJECT g_Driver; NTQUERYSYSTEMINFORMATION NtQuerySystemInformation; ULONG g_HookRetAddressNtQuerySystemInformation;BOOLEAN g_IsDebug;//----------------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------------NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path) {g_Driver = driver;driver->DriverUnload = DriverUnload;g_EprocessAddress = GetProcessEprocessAddr(GAMEIMAGENAME);//CheckProcessDebugged(g_EprocessAddress);// 通過(guò) hook api 的方式實(shí)現(xiàn)簡(jiǎn)易的0-3環(huán)通信// 在鉤子函數(shù)里處理3環(huán)的通信請(qǐng)求,3環(huán)會(huì)不停地命令驅(qū)動(dòng)檢查進(jìn)程是否被調(diào)試InlineHookNtQuerySystemInformation();return STATUS_SUCCESS; }VOID DriverUnload(PDRIVER_OBJECT driver) {UnsetInlineHookNtQuerySystemInformation();DbgPrint("HbgProtect Unload Successfully.\n"); }// 遍歷進(jìn)程列表,獲取游戲EPROCESS地址,不考慮多開(kāi) ULONG GetProcessEprocessAddr(char *ProcessName) {PEPROCESS pEprocess, pCurProcess;PCHAR ImageFileName;ULONG GameEprocessAddr; // 游戲EPROCESS地址,用來(lái)和句柄表的值比對(duì),如果比對(duì)相等說(shuō)明正在被調(diào)試// 獲取 EPROCESS__asm{mov eax, fs:[0x124];mov eax, [eax + 0x220];mov pEprocess, eax;}pCurProcess = pEprocess;// 遍歷 ActiveProcessLinksdo{ ImageFileName = (PCHAR)pCurProcess + 0x174;if (strcmp(ImageFileName, ProcessName) == 0){GameEprocessAddr = (ULONG)pCurProcess; // 記錄游戲EPROCESS地址return (ULONG)pCurProcess;} pCurProcess = (PEPROCESS)(*(PULONG)((ULONG)pCurProcess + 0x88) - 0x88);} while (pEprocess != pCurProcess);return 0; }BOOLEAN CheckProcessDebugged(ULONG EprocessAddress) {BOOLEAN IsDebugged = FALSE;PEPROCESS pEprocess, pCurProcess;PCHAR ImageFileName;ULONG TableCode;ULONG ObjectTable; // 獲取 EPROCESS__asm{mov eax, fs:[0x124];mov eax, [eax + 0x220];mov pEprocess, eax;}pCurProcess = pEprocess;// 遍歷 ActiveProcessLinksdo{ ImageFileName = (PCHAR)pCurProcess + 0x174;ObjectTable = *(PULONG)((ULONG)pCurProcess + 0xC4);if (ObjectTable != 0){TableCode = *(PULONG)ObjectTable;//DbgPrint("%x %s\n", TableCode, ImageFileName);switch(TableCode & 0x00000003){ case 0:{// 一級(jí)句柄表int i;ULONG HandleAddr;TableCode &= 0xFFFFFFFC; // 低2位清零//DbgPrint("正在檢查 [%s] 的句柄表...\n", ImageFileName);for (i = 0; i < 512; i+=2){HandleAddr = (((PULONG)TableCode)[i] & 0xFFFFFFF8) + 0x18; // 低3位清零 + 0x18(跳過(guò) OBJECT_HEADER ) 就是句柄的地址if (HandleAddr == EprocessAddress){DbgPrint("游戲正在被 [%s] 調(diào)試!\n", ImageFileName);IsDebugged = TRUE;}}break;}case 1:{// 二級(jí)句柄表int i,j;ULONG HandleAddr;ULONG TableCode2;TableCode &= 0xFFFFFFFC; // 低2位清零//DbgPrint("正在檢查 [%s] 的句柄表...\n", ImageFileName);for (i = 0; i < 1024; i++){TableCode2 = ((PULONG)TableCode)[i];if (!MmIsAddressValid((PVOID)TableCode2)) continue; // 跳過(guò)無(wú)效線(xiàn)性地址for (j = 0; j < 512; j+=2){HandleAddr = (((PULONG)TableCode2)[j] & 0xFFFFFFF8) + 0x18; // 低3位清零 + 0x18(跳過(guò) OBJECT_HEADER ) 就是句柄的地址if (HandleAddr == EprocessAddress){DbgPrint("%s 正在調(diào)試游戲!\n", ImageFileName);IsDebugged = TRUE;}}}break;}case 2:{// 三級(jí)句柄表int i,j,k;ULONG HandleAddr;ULONG TableCode2,TableCode3;TableCode &= 0xFFFFFFFC; // 低2位清零//DbgPrint("正在檢查 [%s] 的句柄表...\n", ImageFileName);for (i = 0; i < 1024; i++){TableCode2 = ((PULONG)TableCode)[i];if (!MmIsAddressValid((PVOID)TableCode2)) continue; // 跳過(guò)無(wú)效線(xiàn)性地址for (j = 0; j < 1024; j++){TableCode3 = ((PULONG)TableCode2)[j];if (!MmIsAddressValid((PVOID)TableCode3)) continue; // 跳過(guò)無(wú)效線(xiàn)性地址for (k = 0; k < 512; k+=2){HandleAddr = (((PULONG)TableCode3)[k] & 0xFFFFFFF8) + 0x18; // 低3位清零 + 0x18(跳過(guò) OBJECT_HEADER ) 就是句柄的地址if (HandleAddr == EprocessAddress){DbgPrint("%s 正在調(diào)試游戲!\n", ImageFileName);IsDebugged = TRUE;}}}}break;}}} pCurProcess = (PEPROCESS)(*(PULONG)((ULONG)pCurProcess + 0x88) - 0x88);} while (pEprocess != pCurProcess);if (!IsDebugged) DbgPrint("游戲沒(méi)有被調(diào)試.\n");return IsDebugged; }// 關(guān)閉頁(yè)保護(hù) VOID PageProtectOff() {__asm{cli; // 關(guān)閉中斷mov eax, cr0;and eax, not 0x10000; // WP位置0mov cr0, eax;} }// 開(kāi)啟頁(yè)保護(hù) VOID PageProtectOn() {__asm{mov eax, cr0;or eax, 0x10000; // WP位置1mov cr0, eax;sti; // 恢復(fù)中斷} }// 獲取內(nèi)核基址,大小 VOID GetKernelBase(PDRIVER_OBJECT driver, PVOID *pKrnlBase, PULONG uKrnlImageSize) {PLDR_DATA_TABLE_ENTRY pLdteHead; // 內(nèi)核模塊鏈表頭PLDR_DATA_TABLE_ENTRY pLdteCur; // 遍歷指針UNICODE_STRING usKrnlBaseDllName; // 內(nèi)核模塊名RtlInitUnicodeString(&usKrnlBaseDllName,L"ntoskrnl.exe");pLdteHead = (PLDR_DATA_TABLE_ENTRY)driver->DriverSection;pLdteCur = pLdteHead;do {PLDR_DATA_TABLE_ENTRY pLdte = CONTAINING_RECORD(pLdteCur, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);//DbgPrint("DllBase: %p, SizeOfImage: %08X %wZ\n", pLdteCur->DllBase, pLdteCur->SizeOfImage, &(pLdteCur->FullDllName));if (RtlCompareUnicodeString(&pLdteCur->BaseDllName, &usKrnlBaseDllName, TRUE) == 0){*pKrnlBase = pLdteCur->DllBase;*uKrnlImageSize = pLdteCur->SizeOfImage;return;}pLdteCur = (PLDR_DATA_TABLE_ENTRY)pLdteCur->InLoadOrderLinks.Flink;} while (pLdteHead != pLdteCur);return; }// 特征碼搜索 PVOID MemorySearch(PVOID bytecode, ULONG bytecodeLen, PVOID pBeginAddress, PVOID pEndAddress) {PVOID pCur = pBeginAddress;while (pCur != pEndAddress){if (RtlCompareMemory(bytecode,pCur,bytecodeLen) == bytecodeLen){return pCur;}((ULONG)pCur)++;}return 0; }// InlineHook NtQuerySystemInformation void InlineHookNtQuerySystemInformation() { // NtQuerySystemInformation 特征碼ULONG bytecode[] = {0x4589c033, 0xdc4589e4, 0x64fc4589 ,0x000124a1,0xe8858900, 0x8afffffd, 0x00014080 ,0x90458800};UCHAR ReplaceByte[5];PVOID KrnlBase;ULONG KrnlImageSize;// 通過(guò)特征碼獲取NtQuerySystemInformation函數(shù)地址GetKernelBase(g_Driver, &KrnlBase, &KrnlImageSize); NtQuerySystemInformation = (NTQUERYSYSTEMINFORMATION)((ULONG)MemorySearch( \bytecode,sizeof(bytecode),KrnlBase,(PVOID)((ULONG)KrnlBase+KrnlImageSize)) - 15); //DbgPrint("%x\n", ((PULONG)NtQuerySystemInformation)[0]);// 設(shè)置裸函數(shù)返回地址g_HookRetAddressNtQuerySystemInformation = (ULONG)NtQuerySystemInformation + 5;// 計(jì)算替換指令ReplaceByte[0] = 0xE9;*(PULONG)(ReplaceByte + 1) = (ULONG)HbgNtQuerySystemInformation - g_HookRetAddressNtQuerySystemInformation;PageProtectOff();memcpy(NtQuerySystemInformation, ReplaceByte, 5);PageProtectOn(); }// 卸載鉤子 void UnsetInlineHookNtQuerySystemInformation() {UCHAR ReplaceByte[5] = {0x68, 0x10, 0x02, 0x00, 0x00};PageProtectOff();memcpy(NtQuerySystemInformation, ReplaceByte, 5);PageProtectOn(); }// Hook NtQuerySystemInformation __declspec(naked) void HbgNtQuerySystemInformation(IN ULONG OpCode, IN OUT PVOID p1, IN OUT PVOID p2, IN OUT PVOID p3) {__asm{push ebp;mov ebp, esp;sub esp, 0x50;}switch (OpCode){case OP_CHECK_DEBUG:{g_IsDebug = CheckProcessDebugged(g_EprocessAddress);if (g_IsDebug){memset(p1,1,1);}goto ExitNtQuerySystemInformation;break;}}// 正常調(diào)用 NtQuerySystemInformation__asm{add esp, 0x50;pop ebp;push 0x210;jmp g_HookRetAddressNtQuerySystemInformation;} ExitNtQuerySystemInformation:__asm{add esp, 0x50;pop ebp;retn 0x10;} }

總結(jié)

以上是生活随笔為你收集整理的(64)句柄表,遍历所有进程的句柄表实现反调试的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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