从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

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,您想了解如何从Filemapping中读取数据并使用CreateFile函数写入文件。首先,需要使用CreateFileMapping函数创建一个文件映射对象,将文件映射到进程的地址空间中。然后使用MapViewOfFile函数将文件映射到进程的地址空间中并返回指向该区域的指针。接下来,您可以使用指针访问文件映射中的数据。最后,使用CreateFile函数创建一个新文件或打开已存在的文件,并使用WriteFile函数将数据写入该文件。 以下是一个简单的示例代码,展示如何实现从Filemapping中读取数据并使用CreateFile函数写入文件: ``` HANDLE hFile = CreateFile("output.txt", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { printf("Error creating file. Error code: %d\n", GetLastError()); return; } HANDLE hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 1024, "MyFileMap"); if (hMapFile == NULL) { printf("Error creating file mapping. Error code: %d\n", GetLastError()); CloseHandle(hFile); return; } LPVOID lpMapAddress = MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 1024); if (lpMapAddress == NULL) { printf("Error mapping view of file. Error code: %d\n", GetLastError()); CloseHandle(hMapFile); CloseHandle(hFile); return; } DWORD dwBytesWritten; if (!WriteFile(hFile, lpMapAddress, 1024, &dwBytesWritten, NULL)) { printf("Error writing file. Error code: %d\n", GetLastError()); } UnmapViewOfFile(lpMapAddress); CloseHandle(hMapFile); CloseHandle(hFile); ``` 注意:此示例代码仅供参考,您需要根据自己的需求进行修改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值