測試系統:Windows7 x86 Ultimate
SSDT即系统服务描述符表,它的结构如下(参考《Undocument Windows 2000 Secretes》第二章):
typedef struct _SYSTEM_SERVICE_TABLE
{
PVOID ServiceTableBase; //这个指向系统服务函数地址表
PULONG ServiceCounterTableBase;
ULONG NumberOfService; //服务函数的个数,NumberOfService*4 就是整个地址表的大小
ULONG ParamTableBase;
}SYSTEM_SERVICE_TABLE,*PSYSTEM_SERVICE_TABLE;
//轉至http://bbs.pediy.com/showthread.php?t=40832
//0xD7为NtProtectVirtualMemory服务ID
Address = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0xD7 * 4;
服务ID 取得:
用CheatEngine 6.2 查看NtProtectVirtualMemory函數
ntdll.NtProtectVirtualMemory - B8 D7000000 - mov eax,000000D7 -> 這就是 服務ID
ntdll.ZwProtectVirtualMemory+5- BA 0003FE7F - mov edx,7FFE0300 : [ntdll.KiFastSystemCall]
ntdll.ZwProtectVirtualMemory+A- FF 12 - call dword ptr [edx]
ntdll.ZwProtectVirtualMemory+C- C2 1400 - ret 0014
ntdll.ZwProtectVirtualMemory+F- 90 - nop
在看ntdll.KiFastSystemCall:
ntdll.KiFastSystemCall - 8B D4 - mov edx,esp
ntdll.KiFastSystemCall+2- 0F34 - sysenter -> 由此進入內核 (Ring0層)
ntdll.KiFastSystemCallRet- C3 - ret
讓我們進入內核層看HS到底是怎樣Hook的
8425C539 -> NtProtectVirtualMemory原始地址
原始:
8425C539 6A 38 push 38
8425C53B 68 28 20 07 84 push 84072028
8425C540 E8 A3 BA E3 FF call 84097FE8 -> Org_Call
8425C545 FF 75 14 push dword ptr [ebp+14]
.....
HS 啟動後:
8425C539 6A 38 push 38
8425C53B 68 28 20 07 84 push 84072028
8425C540 E8 9B 73 95 02 call 86BB38E0 -> Fake_Call
8425C545 FF 75 14 push dword ptr [ebp+14]
.....
由此可知:
這函數是 Call Inline Hook 而非 Head Inilne Hook (Win7的 NtClose 是 Head Inilne Hook)
破解思路:
直接恢復函數原始Call位子記憶體雖然可以Pass過沒多久又會被HS改回去所以:
在8425C53B設立跳轉點,自己建立一段ASM讓他使用Org_Call而非Fake_Call ,在跳回8425C545.
但此版的HS客戶端主程式會調用原函數以確定是否"真的不能使用"
單純的跳轉過法已經過不了(會跳Callback 0x10301錯誤)必須把客戶端加入調用黑名單"只"讓他依舊無法使用
.
沒有留言:
張貼留言