hook 原理

以 hook ssdk 中的 createfile 为例(windbg 调试)

1
2
dd  keservicedescriptortable  -> dd 80502030 + 0x25*4 -> u 8056e14c   -> jmp  mycreatefile->   if(...){return ...} return 
获取 ssdt 基址 -> 根据索引获取对应函数 -> 汇编当前地址 ->劫持到能控的地址 -> 过滤对应值 返回windows

windbg 调试(windows xp)

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
lkd> dd keservicedescriptortable
80553180 80502030 00000000 0000011c 805024a4
80553190 00000000 00000000 00000000 00000000
805531a0 00000000 00000000 00000000 00000000
805531b0 00000000 00000000 00000000 00000000
805531c0 00002710 bf80da45 00000000 00000000
805531d0 bad8da80 ba4879e0 897e00f0 806e0f40
805531e0 00000000 00000000 8e798ba8 00000140
805531f0 79bdab68 01ced627 00000000 00000000
lkd> dd 80502030
80502030 8059949a 805e6666 805e9ec4 805e6698
80502040 805e9efe 805e66ce 805e9f42 805e9f86
80502050 8060b5da 8060c84e 805e1a08 805e1660
80502060 805ca684 805ca634 8060bc00 805ab088
80502070 8060b218 8059d910 805a54da 805cc162
80502080 804ffd04 805bde0e 8056bbe6 805351dc
80502090 806048ea 805b1714 805ea3fe 806197a2
805020a0 805ee8f0 80599b88 806199f6 8059943a
lkd> u 8059949a
nt!NtConnectPort+0x60:
8059949a 689c000000 push 9Ch
8059949f 6818a14d80 push offset nt!FsRtlLegalAnsiCharacterArray+0x1678 (804da118)
805994a4 e837ecf9ff call nt!wctomb+0x45 (805380e0)
805994a9 64a124010000 mov eax,dword ptr fs:[00000124h]
805994af 8a8040010000 mov al,byte ptr [eax+140h]
805994b5 884590 mov byte ptr [ebp-70h],al
805994b8 84c0 test al,al
805994ba 0f84b9010000 je nt!NtConnectPort+0x23f (80599679)
lkd> dd 80502030 + 0x25*4
805020c4 8056e14c 8056c9de 805cb126 805cae5e
805020d4 80619bd2 8056e25a 8060cf8c 8056e186
805020e4 805a08fa 80599f56 805c6ce8 805c6c32
805020f4 8060d3ac 805a023e 8060a936 805ba410
80502104 805c6ad0 8060c85c 805eec98 80599f7a
80502114 80638ac4 80638c14 8060c26e 8060ba90
80502124 805bde0e 8056bd2c 8061a062 805ea50a
80502134 8061a232 8056e312 806088aa 805b31f0
lkd> 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]

代码实现

获取函数地址

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
ULONG GetSsdtAddr(ULONG uIndex){

ULONG uAddr =(ULONG) (*KeServiceDescriptorTable).ServiceCounterTableBase + uIndex*sizeof(ULONG);
return uAddr;

}
DriverEntry

KdBreakPoint(); //断点
ULONG uAddr = GetSsdtAddr(0x25);
if(uAddr){

KdPrint(("[+] NtCreateFile 0x%08x\n",uAddr));

}

调试

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
28
BOOLEAN 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
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
if(uAddr){

g_oNtCreateFile=(ONtCreateFile)uAddr;
HookSSDT(0x25,(ULONG)ProxyNtCreateFile,&g_uOladCreateFileAddr);
KdPrint(("[+] NtCreateFile 0x%08x\n",uAddr));

}

//代理函数 ProxyNtCreateFile

NTSTATUS ProxyNtCreateFile(......)
{

if(ObjectAttributes && ObjectAttributes->ObjectName)
{

if(wcsstr(ObjectAttributes->ObjectName->Buffer,L"ya.txt") != 0){

KdPrint(("[+]Hook File: %wZ Succeed \n",ObjectAttributes->ObjectName));
return STATUS_UNSUCCESSFUL;

}

}

return g_oNtCreateFile(......);

}

//驱动卸载处 卸载hook

KdPrint(("[+] -------------------- Driver Unload -----------------\n"));
UnHookSSDT(0x25,g_uOladCreateFileAddr);

加载驱动调试

1
2
3
4
5
6
7
8
9
10
11
12
13
[+] -------------------- DriverEntry -----------------
Break instruction exception - code 80000003 (first chance)
HelloDrive!DriverEntry+0xac:
bac5123c cc int 3
kd> g
[+] NtCreateFile 0x8056e14c
simid:30
simid:30
[+]Hook File: \??\C:\Pentest\debuger\ya.txt Succeed
[+]Hook File: \??\C:\Pentest\debuger\ya.txt Succeed
[+]Hook File: \??\C:\Documents and Settings\Administrator\Recent\ya.txt.lnk Succeed
[+]Hook File: \??\C:\Pentest\debuger\ya.txt Succeed
[+] -------------------- Driver Unload -----------------


此时文件已经被保护了

恢复hook

kd 查看

参考

修改CR0 SSDT保护 http://www.cnblogs.com/hongfei/p/3142162.html
SSDT Hook的妙用-对抗ring0 inline hook http://bbs.pediy.com/showthread.php?t=40832