驅動開發:內核枚舉PspCidTable句柄表( 二 )


我們對 0xffffdc88-7d09b001 抹去低二位,輸入dp 0xffffdc887d09b000 輸出的結果就是一張二級表 , 里面存儲的就是一級表指針 。

驅動開發:內核枚舉PspCidTable句柄表

文章插圖
繼續查看第一張一級表,輸入dp 0xffffdc887962a000命令,我們知道一級句柄表是根據進程或線程ID來索引的,且以4累加,所以第一行對應id = 0 , 第二行對應id = 4 。根據嘗試,PID = 4的進程是System 。
驅動開發:內核枚舉PspCidTable句柄表

文章插圖
所以此處的第二行0xb281de28-3300ffa7就是加密后的System進程的EPROCESS結構,對于Win10系統來說解密算法(value >> 0x10) & 0xfffffffffffffff0是這樣的,我們通過代碼計算出來 。
#include <Windows.h>#include <iostream>int _tmain(int argc, _TCHAR* argv[]){ std::cout << "hello lyshark.com" << std::endl; ULONG64 ul_recode = 0xb281de283300ffa7; ULONG64 ul_decode = (LONG64)ul_recode >> 0x10; ul_decode &= 0xfffffffffffffff0; std::cout << "解密后地址: " << std::hex << ul_decode << std::endl; getchar(); return 0;}運行程序得到如下輸出,即可知道System系統進程解密后的EPROCESS結構地址是0xffffb281de283300
驅動開發:內核枚舉PspCidTable句柄表

文章插圖
回到WinDBG調試器,輸入命令dt _EPROCESS 0xffffb281de283300解析以下這個結構,輸出結果是System進程 。
驅動開發:內核枚舉PspCidTable句柄表

文章插圖
理論知識總結已經結束了,接下來就是如何實現枚舉進程線程了 , 枚舉流程如下:
  • 1.首先找到PspCidTable的地址 。
  • 2.然后找到HANDLE_TBALE的地址 。
  • 3.根據TableCode來判斷層次結構 。
  • 4.遍歷層次結構來獲取對象地址 。
  • 5.判斷對象類型是否為進程對象 。
  • 6.判斷進程是否有效 。
這里先來實現獲取PspCidTable函數的動態地址,代碼如下 。
#include <ntifs.h>#include <windef.h>// 獲取 PspCidTable// By: LyShark.comBOOLEAN get_PspCidTable(ULONG64* tableAddr){ // 獲取 PsLookupProcessByProcessId 地址 UNICODE_STRING uc_funcName; RtlInitUnicodeString(&uc_funcName, L"PsLookupProcessByProcessId"); ULONG64 ul_funcAddr = MmGetSystemRoutineAddress(&uc_funcName); if (ul_funcAddr == NULL) {return FALSE; } DbgPrint("PsLookupProcessByProcessId addr = %p \n", ul_funcAddr); // 前 40 字節有 call(PspReferenceCidTableEntry) /* 0: kd> uf PsLookupProcessByProcessIdnt!PsLookupProcessByProcessId:fffff802`0841cfe0 48895c2418      mov     qword ptr [rsp+18h],rbxfffff802`0841cfe5 56              push    rsifffff802`0841cfe6 4883ec20        sub     rsp,20hfffff802`0841cfea 48897c2438      mov     qword ptr [rsp+38h],rdifffff802`0841cfef 488bf2          mov     rsi,rdxfffff802`0841cff2 65488b3c2588010000 mov   rdi,qword ptr gs:[188h]fffff802`0841cffb 66ff8fe6010000  dec     word ptr [rdi+1E6h]fffff802`0841d002 b203            mov     dl,3fffff802`0841d004 e887000000      call    nt!PspReferenceCidTableEntry (fffff802`0841d090)fffff802`0841d009 488bd8          mov     rbx,raxfffff802`0841d00c 4885c0          test    rax,raxfffff802`0841d00f 7435            je      nt!PsLookupProcessByProcessId+0x66 (fffff802`0841d046)  Branch */ ULONG64 ul_entry = 0; for (INT i = 0; i < 100; i++) {// fffff802`0841d004 e8 87 00 00 00      call    nt!PspReferenceCidTableEntry (fffff802`0841d090)if (*(PUCHAR)(ul_funcAddr + i) == 0xe8){ul_entry = ul_funcAddr + i;break;} } if (ul_entry != 0) {// 解析 call 地址INT i_callCode = *(INT*)(ul_entry + 1);DbgPrint("i_callCode = %p \n", i_callCode);ULONG64 ul_callJmp = ul_entry + i_callCode + 5;DbgPrint("ul_callJmp = %p \n", ul_callJmp);// 來到 call(PspReferenceCidTableEntry) 內找 PspCidTable/*0: kd> uf PspReferenceCidTableEntrynt!PspReferenceCidTableEntry+0x115:fffff802`0841d1a5 488b0d8473f5ff  mov     rcx,qword ptr [nt!PspCidTable (fffff802`08374530)]fffff802`0841d1ac b801000000      mov     eax,1fffff802`0841d1b1 f0480fc107      lock xadd qword ptr [rdi],raxfffff802`0841d1b6 4883c130        add     rcx,30hfffff802`0841d1ba f0830c2400      lock or dword ptr [rsp],0fffff802`0841d1bf 48833900        cmp     qword ptr [rcx],0fffff802`0841d1c3 0f843fffffff    je      nt!PspReferenceCidTableEntry+0x78 (fffff802`0841d108)  Branch*/for (INT i = 0; i < 0x120; i++){// fffff802`0841d1a5 48 8b 0d 84 73 f5 ff  mov     rcx,qword ptr [nt!PspCidTable (fffff802`08374530)]if (*(PUCHAR)(ul_callJmp + i) == 0x48 && *(PUCHAR)(ul_callJmp + i + 1) == 0x8b && *(PUCHAR)(ul_callJmp + i + 2) == 0x0d){// 解析 mov 地址INT i_movCode = *(INT*)(ul_callJmp + i + 3);DbgPrint("i_movCode = %p \n", i_movCode);ULONG64 ul_movJmp = ul_callJmp + i + i_movCode + 7;DbgPrint("ul_movJmp = %p \n", ul_movJmp);// 得到 PspCidTable*tableAddr = ul_movJmp;return TRUE;}} } return FALSE;}VOID UnDriver(PDRIVER_OBJECT driver){ DbgPrint(("Uninstall Driver Is OK \n"));}NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath){ DbgPrint(("hello lyshark \n")); ULONG64 tableAddr = 0; get_PspCidTable(&tableAddr); DbgPrint("PspCidTable Address = %p \n", tableAddr); Driver->DriverUnload = UnDriver; return STATUS_SUCCESS;}

推薦閱讀