win 64 SSDT HOOK
阿新 • • 發佈:2017-10-01
分享 ima img 應該 ror i++ 直接 nproc mage
以下內容參考黑客防線2012合訂本第294頁
其實沒什麽好說的,直接上代碼:
ssdt的結構,和win32差不多,但是要註意這裏的指針類型不能用ULONG替代,如果要非要替代應該用ULONGLONG,原因就不說了.
//SSDT的結構 typedef struct _SystemServiceDescriptorTable { PVOID ServiceTableBase; PVOID ServiceCounterTableBase; ULONGLONG NumberOfService; PVOID ParamTableBase; }SystemServiceTable,*PSystemServiceTable; PSystemServiceTable KeServiceDescriptorTable;
獲取上面的結構的地址的代碼;
ULONGLONG GetKeSeviceDescriptorTable64() { /* 思路是讀取0xC0000082 這個寄存器的值是KiSystemCall64函數地址,然後通過特征碼搜索即可 ssdt特征碼是 0x4c8d15 接著就是ssdt的地址值的偏移了,然後通過公式: 真實地址 = 當前地址+當前指令長度+偏移 得到ssdt地址 找shadow ssdt地址類似*/ PUCHAR startSearchAddress = (PUCHAR)__readmsr(0xC0000082); PUCHAR endSearchAddress = startSearchAddress + 0x500; PUCHAR i = 0; UCHAR b1 = 0, b2 = 0, b3 = 0; ULONG temp = 0; ULONGLONG addr = 0; for ( i = startSearchAddress; i < endSearchAddress; i++) { if (MmIsAddressValid(i) && MmIsAddressValid(i + 1) && MmIsAddressValid(i + 2)) { b1 = *i; b2 = *(i + 1); b3 = *(i + 2); if (b1 == 0x4c && b2 == 0x8d && b3 == 0x15) { memcpy(&temp, i + 3, 4); addr = (ULONGLONG)temp + (ULONGLONG)i + 7;//加上指令長度 KdPrint(("find ssdt is %p\n", addr)); return addr; } } } KdPrint(("find ssdt error\n")); return 0; }
遍歷所有Native API 地址:
void througnAllServiceFuncAddr() { ULONG dwTemp = 0; PULONG ServiceTableBase = 0; ULONG i = 0; for ( i = 0; i < KeServiceDescriptorTable->NumberOfService; i++) { if (MmIsAddressValid(KeServiceDescriptorTable->ServiceTableBase)) { ServiceTableBase = (PULONG)KeServiceDescriptorTable->ServiceTableBase; dwTemp = ServiceTableBase[i]; dwTemp = dwTemp >> 4; DbgPrint("the %dth func addr is %p!\n", i, ((ULONGLONG)dwTemp + (ULONGLONG)ServiceTableBase) & 0xffffffff0fffffff); } else { DbgPrint("ServiceTableBase is fault!\n"); return 0; } } }
測試結果:
windbg查看的結果:
以ZwOpenProcess為例:
ida中發現他的id是0x23 也就是 35 對應 測試結果是 fffff8000419b038
windbg結果:
測試無誤.
最後如果想hook它那就很簡單了.
win 64 SSDT HOOK