对CreateFileW函数进行从ring3到ring0的跟踪,用到WinDBG工具,也算是对该工具如何使用做一个展示。
步骤:
通过VirtualKD建立双机调试
在虚拟机中打开一个记事本
在WinDBGM中输入:
0: kd> !process 0 0 notepad.exe
PROCESS 87e883a8 SessionId: 1 Cid: 0ab0 Peb: 7ffdb000 ParentCid: 062c
DirBase: 3f07e420 ObjectTable: 8e45a618 HandleCount: 284.
Image: notepad.exe
0: kd> .process /i /p 0x87e883a8
//切换调试进程(默认是在system进程)You need to continue execution (press 'g' <enter>) for the context
to be switched. When the debugger breaks in again, you will be in
the new process context.
按一下g
0: kd> g
Break instruction exception - code 80000003 (first chance)
nt!RtlpBreakWithStatusInstruction:
83ec07b8 cc int 3
0: kd> .reload /f /user
//加载内核的调试符号
0: kd> bp /p 0x87e883a8 kernel32!CreateFileW
//在kernel32!CreateFileW处下断
0: kd> g
在记事本中 点【文件】->【打开】
Breakpoint 0 hit
//断在了kernel32!CreateFileW 处
kernel32!CreateFileW:
001b:76a7e9a8 ff25e019a376 jmp dword ptr [kernel32!_imp__CreateFileW (76a319e0)]
F10单步一下
KERNELBASE!CreateFileW:
001b:75faa808 8bff mov edi,edi
0: kd> u KERNELBASE!CreateFileW lA0
//显示A0条汇编指令
找到如下指令:
... ...
75faa9ab 8b35a810fa75 mov
esi,dword ptr [KERNELBASE!_imp__NtCreateFile (75fa10a8)]
75faa9b1 ff75fc
push dword ptr [ebp-4]
75faa9b4 81e1a77f0000 and
ecx,7FA7h
75faa9ba ff7510
push dword ptr [ebp+10h]
75faa9bd 894d1c mov
dword ptr [ebp+1Ch],ecx
75faa9c0 51
push ecx
75faa9c1 53
push ebx
75faa9c2 8d4de0 lea
ecx,[ebp-20h]
75faa9c5 51
push ecx
75faa9c6 0d80001000 or
eax,100080h
75faa9cb 8d4d9c lea
ecx,[ebp-64h]
75faa9ce 51
push ecx
75faa9cf 50
push eax
75faa9d0 89450c
mov dword ptr [ebp+0Ch],eax
75faa9d3 8d45f8 lea
eax,[ebp-8]
75faa9d6 50
push eax
75faa9d7 ffd6
call esi
... ...
在75faa9d7处下断
0: kd> bp 75faa9d7
0: kd> g
Breakpoint 1 hit
KERNELBASE!CreateFileW+0x35c:
001b:75faa9d7 ffd6 call esi
按F11跟进去
ntdll!ZwCreateFile:
77da5608 b842000000 mov eax,42h
77da560d ba0003fe7f mov edx,offset SharedUserData!SystemCallStub (7ffe0300)
77da5612 ff12 call
dword ptr [edx]
77da5614 c22c00 ret
2Ch
77da5617 90 nop
0: kd> u
看得出 mov eax,42h就是中的0x42就是CreateFileW的标号
F10 F10 F11
进入call dword ptr [edx]
0: kd> u
ntdll!KiFastSystemCall:
77da70f0 8bd4 mov edx,esp
77da70f2 0f34 sysenter
再执行两步就要进入ring0了
然后要做的就是在nt!KiFastCallEntry函数处下断点
0: kd> rdmsr 176
//获取nt!KiFastCallEntry函数地址
msr[176] = 00000000`83e83790
在0x83e83790处下条件断点
0: kd> bp 83e83790 ".if (@eax &0x0ffffffff)=0x42{} .else {gc}"
0: kd> g
nt!KiFastCallEntry:
83e83790 b923000000 mov ecx,23h //断在了nt!KiFastCallEntry
0: kd> u nt!KiFastCallEntry l50
... ...
83e83871 8b1487 mov edx,dword ptr [edi+eax*4]
... ...
其中 [edi+eax*4]的edi就是SSDT表的首地址
0: kd> bp 83e83871
0: kd> g
Breakpoint 3 hit
nt!KiSystemServiceAccessTeb+0x25:
83e83871 8b1487 mov edx,dword ptr [edi+eax*4]
0: kd> dd edi
83ec443c 840bffcf 83f07855 8404fd4b 83e6b897
83ec444c 840c18a5 83f44112 841320eb 84132134
83ec445c 84044567 8414b9e8 8414cc41 8403ad3f
83ec446c 840cbee3 84124daf 84077cd7 840478af
83ec447c 83fdd9e2 84116c90 8402e290 84070ccc
83ec448c 840bd1a1 8401e304 840bc5ae 8403bdb6
83ec449c 840cd96a 8403e439 840cd74a 840c5ea2
83ec44ac 840502d3 84111a2d 840c326f 840cdb9c
以上就是SSDT的内容,是一堆函数指针
0: kd> u 83e83871 l20
nt!KiSystemServiceAccessTeb+0x25:
83e83871 8b1487
mov edx,dword ptr [edi+eax*4]
83e83874 2be1
sub esp,ecx
83e83876 c1e902
shr ecx,2
83e83879 8bfc
mov edi,esp
83e8387b f6457202
test byte ptr [ebp+72h],2
83e8387f 7506
jne nt!KiSystemServiceAccessTeb+0x3b (83e83887)
83e83881 f6456c01
test byte ptr [ebp+6Ch],1
83e83885 740c
je nt!KiSystemServiceCopyArguments (83e83893)
83e83887 3b3550f8fa83
cmp esi,dword ptr [nt!MmUserProbeAddress (83faf850)]
83e8388d 0f832e020000
jae nt!KiSystemCallExit2+0xa5 (83e83ac1)
nt!KiSystemServiceCopyArguments:
83e83893 f3a5
rep movs dword ptr es:[edi],dword ptr [esi]
83e83895 f6456c01
test byte ptr [ebp+6Ch],1
83e83899 7416
je nt!KiSystemServiceCopyArguments+0x1e (83e838b1)
83e8389b 648b0d24010000
mov ecx,dword ptr fs:[124h]
83e838a2 8b3c24
mov edi,dword ptr [esp]
83e838a5 89993c010000
mov dword ptr [ecx+13Ch],ebx
83e838ab 89b92c010000
mov dword ptr [ecx+12Ch],edi
83e838b1 8bda
mov ebx,edx
83e838b3 f60588c6f78340
test byte ptr [nt!PerfGlobalGroupMask+0x8 (83f7c688)],40h
83e838ba 0f954512
setne byte ptr [ebp+12h]
83e838be 0f8580030000
jne nt!KiServiceExit2+0x179 (83e83c44)
83e838c4 ffd3
call ebx
... ...
1: kd> bp 83e838c4
1: kd> g
Breakpoint 4 hit
nt!KiSystemServiceCopyArguments+0x31:
83e838c4 ffd3 call ebx
按F11
nt!NtCreateFile:
84096480 8bff mov edi,edi
0: kd> u 84096480 l20
nt!NtCreateFile:
84096480 8bff
mov edi,edi
84096482 55
push ebp
84096483 8bec
mov ebp,esp
84096485 51
push ecx
84096486 33c0
xor eax,eax
84096488 50
push eax
84096489 6a20
push 20h
8409648b 50
push eax
8409648c 50
push eax
8409648d 50
push eax
8409648e ff7530
push dword ptr [ebp+30h]
84096491 ff752c
push dword ptr [ebp+2Ch]
84096494 ff7528
push dword ptr [ebp+28h]
84096497 ff7524
push dword ptr [ebp+24h]
8409649a ff7520
push dword ptr [ebp+20h]
8409649d ff751c
push dword ptr [ebp+1Ch]
840964a0 ff7518
push dword ptr [ebp+18h]
840964a3 ff7514
push dword ptr [ebp+14h]
840964a6 ff7510
push dword ptr [ebp+10h]
840964a9 ff750c
push dword ptr [ebp+0Ch]
840964ac ff7508
push dword ptr [ebp+8]
840964af e80bc1fdff
call nt!IopCreateFile (840725bf)
840964b4 59
pop ecx
840964b5 5d
pop ebp
840964b6 c22c00
ret 2Ch
840964b9 90
nop
至此就找到了ring0调用CreateFileW最终是调用的nt!IopCreateFile。