2013年2月27日 星期三

[Note] - SSDT Hook 筆記 (一)

測試系統: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錯誤)
必須把客戶端加入調用黑名單"只"讓他依舊無法使用
.


沒有留言:

張貼留言