内核 hook 初探
hook 原理
以 hook ssdk 中的 createfile 为例(windbg 调试)1
2dd keservicedescriptortable -> dd 80502030 + 0x25*4 -> u 8056e14c -> jmp mycreatefile-> if(...){return ...} return
获取 ssdt 基址 -> 根据索引获取对应函数 -> 汇编当前地址 ->劫持到能控的地址 -> 过滤对应值 返回windows
windbg 调试(windows xp)
1 | lkd> dd keservicedescriptortable |
代码实现
获取函数地址
1 | ULONG GetSsdtAddr(ULONG uIndex){ |
调试1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68[+] DriverEntry
Break instruction exception - code 80000003 (first chance)
HelloDrive!DriverEntry+0xa9:
bac51229 cc int 3
kd> t
HelloDrive!DriverEntry+0xaa:
bac5122a 6a25 push 25h
kd> t
HelloDrive!GetSsdtAddr:
bac51260 8bff mov edi,edi
kd> t
HelloDrive!GetSsdtAddr+0x6:
bac51266 a11c20c5ba mov eax,dword ptr [HelloDrive!KeServiceDescriptorTable (bac5201c)]
kd> t
HelloDrive!GetSsdtAddr+0x16:
bac51276 8b45fc mov eax,dword ptr [ebp-4]
kd> t
HelloDrive!GetSsdtAddr+0x19:
bac51279 8be5 mov esp,ebp
kd> t
HelloDrive!DriverEntry+0xb1:
bac51231 8945f8 mov dword ptr [ebp-8],eax
kd> t
HelloDrive!DriverEntry+0xb4:
bac51234 837df800 cmp dword ptr [ebp-8],0
kd> u uAddr
bacfbc74 4c dec esp
bacfbc75 e156 loope bacfbccd
bacfbc77 8090ac7a894cbd adc byte ptr [eax+4C897AACh],0BDh
bacfbc7e cf iretd
bacfbc7f ba50655780 mov edx,offset nt!NtWriteFile+0x449a (80576550)
bacfbc84 a849 test al,49h
bacfbc86 50 push eax
bacfbc87 8900 mov dword ptr [eax],eax
kd> dd uAddr
bacfbc74 8056e14c 897aac90 bacfbd4c 80576550
bacfbc84 895049a8 89893000 00000000 b15f5c44
bacfbc94 00000000 00000018 00000000 bacfbcc0
bacfbca4 00000010 00000000 00000000 895049a8
bacfbcb4 bacfbd70 8944be38 89893000 00240024
bacfbcc4 89728228 806d12e2 895049a8 89800b38
bacfbcd4 00000024 000004c4 bac50000 000004c0
bacfbce4 00160014 e1bd3d10 0000007e 004c004a
kd> u 8056e14c
nt!NtCreateFile:
8056e14c 8bff mov edi,edi
8056e14e 55 push ebp
8056e14f 8bec mov ebp,esp
8056e151 33c0 xor eax,eax
8056e153 50 push eax
8056e154 50 push eax
8056e155 50 push eax
8056e156 ff7530 push dword ptr [ebp+30h]
kd> t
HelloDrive!DriverEntry+0xba:
bac5123a 8b4df8 mov ecx,dword ptr [ebp-8]
kd> t
nt!DbgPrint:
8052802e 8bff mov edi,edi
kd> p
nt!DbgPrint+0x8:
80528036 50 push eax
kd> gu
[+] NtCreateFile 0x8056e14c
HelloDrive!DriverEntry+0xc8:
bac51248 83c408 add esp,8
kd> g
[+] Driver Unload
Hook CrateFile 保护文件
hook 函数1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28BOOLEAN HookSSDT(ULONG uIndex,ULONG uNewAddr,PULONG puOldAddr){
if(uNewAddr ==0 || puOldAddr == NULL) {
return FALSE;
}
ULONG uAddr = ((ULONG) (*KeServiceDescriptorTable).ServiceTableBase + uIndex*sizeof(ULONG)); //获取函数原始地址
*puOldAddr = *(PULONG)uAddr ;
DisableWP();
*(PULONG)uAddr=uNewAddr; //写入新地址
EnableWP(); //关闭写保护
return TRUE;
}
BOOLEAN UnHookSSDT(ULONG uIndex,ULONG uOldAddr){
if(uOldAddr == 0){
return FALSE;
}
ULONG uAddr = ((ULONG) (*KeServiceDescriptorTable).ServiceTableBase + uIndex*sizeof(ULONG));
DisableWP();
*(PULONG)uAddr = uOldAddr;
EnableWP();
return TRUE;
}
关于绕过内存保护机制见参考资料
驱动入口函数
1 | if(uAddr){ |
加载驱动调试
1 | [+] -------------------- DriverEntry ----------------- |
恢复hook
参考
修改CR0 SSDT保护 http://www.cnblogs.com/hongfei/p/3142162.html
SSDT Hook的妙用-对抗ring0 inline hook http://bbs.pediy.com/showthread.php?t=40832