从CreateFile(APP)到NtCreateFile(Kernel Mode)

1. Nt*与Zw*的区别

"一组与执行体的系统服务(executive's system services)平行的入口点.从内核模式的代码()中调用一个Zwxxx入口点将获得相应的系统服务,只是在使用Zw*()函数时,不会检查调用者的访问权限和参数的有效性,而且调用不会将先前模式(previous mode)切换到用户模式"
"尽管任意一组函数都可以从内核模式调用,但如果用Zw*()函数来代替Nt*()函数,则可将先前模式(这里的先前模式指的是发出请求的模式)切换到内核模式"

某些Zw*和Nt*函数既在ntdll.dll中导出又在ntoskrnl.exe中导出,同时存在NtCreateFile和ZwCreateFile, 在ntdll.dll中是这样定义的:

USRSTUBS_ENTRY1 macro ServiceNumber, Name, NumArgs
cPublicProc _Zw&Name, NumArgs
PUBLICP _Nt&Name, NumArgs
LABELP _Nt&Name, NumArgs
.FPO ( 0, NumArgs, 0, 0, 0, 0 )
mov eax, ServiceNumber ; (eax) = service number
mov edx, MM_SHARED_USER_DATA_VA+UsSystemCall
call [edx]
stdRET _Zw&Name
stdENDP _Zw&Name


即在ntdll.dll中Nt*函数和Zw*函数功能是相同的, Nt*函数是Zw*函数的别名.
通过IDA反汇编ntdll.dll得到:

.text:7C92D682 ; Exported entry 123. NtCreateFile
.text:7C92D682 ; Exported entry 933. ZwCreateFile
.text:7C92D682
.text:7C92D682 ; S U B R O U T I N E
.text:7C92D682
.text:7C92D682
.text:7C92D682 public ZwCreateFile
.text:7C92D682 ZwCreateFile proc near ; CODE XREF:
.text:7C92D682 ;
.text:7C92D682 mov eax, 25h ; NtCreateFile
.text:7C92D687 mov edx, 7FFE0300h
.text:7C92D68C call dword ptr [edx]
.text:7C92D68E retn 2Ch
.text:7C92D68E ZwCreateFile endp


对ntoskrnl.exe反汇编得到
NtCreateFile:

PAGE:004A63C4 ; Exported entry 747. NtCreateFile
PAGE:004A63C4
PAGE:004A63C4 ; S U B R O U T I N E
PAGE:004A63C4
PAGE:004A63C4 ; Attributes: bp-based frame
PAGE:004A63C4
PAGE:004A63C4 public NtCreateFile
PAGE:004A63C4 NtCreateFile proc near ; CODE XREF: RtlCreateSystemVolumeInformationFolder+139 p
PAGE:004A63C4 ; RtlCreateSystemVolumeInformationFolder+165 p ...
PAGE:004A63C4
PAGE:004A63C4 FileHandle = dword ptr 8
PAGE:004A63C4 DesiredAccess = dword ptr 0Ch
PAGE:004A63C4 ObjectAttributes= dword ptr 10h
PAGE:004A63C4 IoStatusBlock = dword ptr 14h
PAGE:004A63C4 AllocationSize = dword ptr 18h
PAGE:004A63C4 FileAttributes = dword ptr 1Ch
PAGE:004A63C4 ShareAccess = dword ptr 20h
PAGE:004A63C4 Disposition = dword ptr 24h
PAGE:004A63C4 CreateOptions = dword ptr 28h
PAGE:004A63C4 EaBuffer = dword ptr 2Ch
PAGE:004A63C4 EaLength = dword ptr 30h
PAGE:004A63C4
PAGE:004A63C4 mov edi, edi
PAGE:004A63C6 push ebp
PAGE:004A63C7 mov ebp, esp
PAGE:004A63C9 xor eax, eax
PAGE:004A63CB push eax ; Options
PAGE:004A63CC push eax ; ExtraCreateParameters
PAGE:004A63CD push eax ; CreateFileType
PAGE:004A63CE push [ebp+EaLength] ; EaLength
PAGE:004A63D1 push [ebp+EaBuffer] ; EaBuffer
PAGE:004A63D4 push [ebp+CreateOptions] ; CreateOptions
PAGE:004A63D7 push [ebp+Disposition] ; Disposition
PAGE:004A63DA push [ebp+ShareAccess] ; ShareAccess
PAGE:004A63DD push [ebp+FileAttributes] ; FileAttributes
PAGE:004A63E0 push [ebp+AllocationSize] ; AllocationSize
PAGE:004A63E3 push [ebp+IoStatusBlock] ; IoStatusBlock
PAGE:004A63E6 push [ebp+ObjectAttributes] ; ObjectAttributes
PAGE:004A63E9 push [ebp+DesiredAccess] ; DesiredAccess
PAGE:004A63EC push [ebp+FileHandle] ; FileHandle
PAGE:004A63EF call IoCreateFile
PAGE:004A63F4 pop ebp
PAGE:004A63F5 retn 2Ch
PAGE:004A63F5 NtCreateFile endp



ZwCreateFile:

cPublicProc _Zw&Name,NumArgs
.FPO ( 0, NumArgs, 0, 0, 0, 0 )
extrn _KiSystemService:PROC
mov eax, ServiceNumber ; (eax) = service number
lea edx, [esp]+4 ; (edx) -> arguments
pushfd ; EFLAGS to trap frame
push KGDT_R0_CODE ; CS to trap frame
call _KiSystemService ; EIP to trap frame and enter handler
stdRET _Zw&Name
stdENDP _Zw&Name



.text:0040C566 ; Exported entry 1295. ZwCreateFile
.text:0040C566
.text:0040C566 ; S U B R O U T I N E
.text:0040C566
.text:0040C566
.text:0040C566 ; NTSTATUS __stdcall ZwCreateFile(PHANDLE FileHandle,ACCESS_MASK DesiredAccess,POBJECT_ATTRIBUTES ObjectAttributes,PIO_STATUS_BLOCK IoStatusBlock,PLARGE_INTEGER AllocationSize,ULONG FileAttributes,ULONG ShareAccess,ULONG CreateDisposition,ULONG CreateOptions,PVOID EaBuffer,ULONG EaLength)
.text:0040C566 public ZwCreateFile
.text:0040C566 ZwCreateFile proc near ; CODE XREF: sub_4D53A6+66 p
.text:0040C566 ; sub_4D686F+50 p ...
.text:0040C566
.text:0040C566 FileHandle = dword ptr 4
.text:0040C566 DesiredAccess = dword ptr 8
.text:0040C566 ObjectAttributes= dword ptr 0Ch
.text:0040C566 IoStatusBlock = dword ptr 10h
.text:0040C566 AllocationSize = dword ptr 14h
.text:0040C566 FileAttributes = dword ptr 18h
.text:0040C566 ShareAccess = dword ptr 1Ch
.text:0040C566 CreateDisposition= dword ptr 20h
.text:0040C566 CreateOptions = dword ptr 24h
.text:0040C566 EaBuffer = dword ptr 28h
.text:0040C566 EaLength = dword ptr 2Ch
.text:0040C566
.text:0040C566 mov eax, 25h
.text:0040C56B lea edx, [esp+FileHandle]
.text:0040C56F pushf
.text:0040C570 push 8
.text:0040C572 call sub_4067D1
.text:0040C577 retn 2Ch
.text:0040C577 ZwCreateFile endp ; sp = -8


通过Windbg得到ZwCreateFile:
nt!ZwCreateFile:
804e4566 b825000000 mov eax,25h
804e456b 8d542404 lea edx,[esp+4]
804e456f 9c pushfd
804e4570 6a08 push 8
804e4572 e85aa2ffff call nt!KiSystemService (804de7d1)
804e4577 c22c00 ret 2Ch


在ntoskrnl.exe中ZwCreateFile会最终调用到NtCreateFile, 只是ZwCreateFile做了些参数检查和保存状态, 在内核态才能调用.

2. 从CreateFile(APP)到NtCreateFile(Kernel Mode)调用流程如下:

CreateFile(APP)   --> CreateFileA(kernel32.dll)   --> CreateFileW(kernel32.dll)   --> NtCreateFile(ntdll.dll)   --> NtCreateFile(ntoskrnl.exe)

在ntdll.dll中NtCreateFile定义如下:
NtCreateFile proc near ; CODE XREF:
;
mov eax, 25h ; NtCreateFile
mov edx, 7FFE0300h
call dword ptr [edx]
retn 2Ch
NtCreateFile endp

MM_SHARED_USER_DATA_VA equ 07FFE0000H
UsSystemCall equ 00300H


通过反汇编7FFE0300H得到:
MOV EDX, ESP

SYSENTER


通过执行下面的代码从ntdll.dll进入到了内核态KiFastCallEntry
MOV EDX, ESP
SYSENTER

你可能感兴趣的:(windows)