提供对文件的读写功能是操作系统的一项重要任务。我们来看一下NT家族的操作系统都为我们提供了那些功能。
9.1 核心句柄表
在开始讨论本文的主题之前,我们先来讨论一个重要的问题,我们之前并未对其给予应有的注意。为了取得对象的句柄需要填充OBJECT_ATTRIBUTES结构体——我们已经做过很多遍了,其样子如下:
InitializeObjectAttributes(oa, @g_usName,OBJ_CASE_INSENSITIVE,0, nil);
unit FileWorks;
interface
uses
nt_status, ntoskrnl, ntifs, native, winioctl, fcall, macros;
function _DriverEntry(pDriverObject:PDRIVER_OBJECT;
pusRegistryPath:PUNICODE_STRING): NTSTATUS; stdcall;
implementation
var
g_usDirName: UNICODE_STRING;
g_usFileName: UNICODE_STRING;
procedure CreateDirectory;
var
oa: OBJECT_ATTRIBUTES;
iosb: IO_STATUS_BLOCK;
hDirectory: THANDLE;
RtnCode: NTSTATUS;
begin
{ 还记得吧, 传递给DbgPrint函数的用于格式化Unicode的代码(%C, %S, %lc, %ls, %wc, %ws, %wZ)只能在
IRQL = PASSIVE_LEVEL下调用! }
DbgPrint(#13#10'FileWorks: Creating %ws directory'#13#10, g_usDirName.Buffer);
InitializeObjectAttributes(oa, @g_usDirName,
OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE,
0, nil);
RtnCode := ZwCreateFile(@hDirectory, SYNCHRONIZE, @oa, @iosb, nil,
FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN_IF,
FILE_DIRECTORY_FILE + FILE_SYNCHRONOUS_IO_NONALERT,
nil, 0);
if RtnCode = STATUS_SUCCESS then
begin
if iosb.Information = FILE_CREATED then
begin
DbgPrint('FileWorks: Directory created'#13#10);
end else if iosb.Information = FILE_OPENED then
begin
DbgPrint('FileWorks: Directory exists and was opened'#13#10);
end;
ZwClose(hDirectory);
end else
begin
DbgPrint('FileWorks: Can''t create directory. Status: %08X'#13#10, RtnCode);
end;
end;
procedure CreateFile;
var
oa:OBJECT_ATTRIBUTES;
iosb:IO_STATUS_BLOCK;
hFile:THANDLE;
RtnCode: NTSTATUS;
begin
DbgPrint(#13#10'FileWorks: Creating %ws file'#13#10, g_usFileName.Buffer);
InitializeObjectAttributes(oa, @g_usFileName,
OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE,
0, nil);
RtnCode := ZwCreateFile(@hFile, SYNCHRONIZE, @oa, @iosb, nil,
FILE_ATTRIBUTE_NORMAL, 0,
FILE_CREATE,
FILE_SYNCHRONOUS_IO_NONALERT, nil, 0);
if RtnCode = STATUS_SUCCESS then
begin
DbgPrint('FileWorks: File created'#13#10);
ZwClose(hFile);
end else
begin
DbgPrint('FileWorks: Can''t create file. Status: %08X'#13#10, RtnCode);
end;
end;
procedure WriteFile;
var
oa:OBJECT_ATTRIBUTES;
iosb:IO_STATUS_BLOCK;
hFile:THANDLE;
RtnCode: NTSTATUS;
g_szData: PAnsiChar;
begin
DbgPrint(#13#10'FileWorks: Opening file for writing'#13#10);
InitializeObjectAttributes(oa, @g_usFileName,
OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE,
0, nil);
RtnCode := ZwCreateFile(@hFile, FILE_WRITE_DATA + SYNCHRONIZE,
@oa, @iosb, nil, 0, FILE_SHARE_READ,
FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT,
nil, 0);
if RtnCode = STATUS_SUCCESS then
begin
DbgPrint('FileWorks: File openeded'#13#10);
g_szData := 'Data can be written to an open file';
//RtlInitUnicodeString(g_szData, 'Data can be written to an open file');
RtnCode := ZwWriteFile(hFile, 0, nil, nil, @iosb, g_szData,
strlen(g_szData), nil, nil);
if RtnCode = STATUS_SUCCESS then
begin
DbgPrint('FileWorks: File was written'#13#10);
end else
begin
DbgPrint('FileWorks: Can''t write to the file. Status: %08X\n', RtnCode);
end;
ZwClose(hFile);
end else
begin
DbgPrint('FileWorks: Can''t open file. Status: %08X'#13#10, RtnCode);
end;
end;
procedure MarkAsReadOnly;
var
oa:OBJECT_ATTRIBUTES;
iosb:IO_STATUS_BLOCK;
hFile:THandle;
fbi:FILE_BASIC_INFORMATION;
RtnCode:NTSTATUS;
begin
DbgPrint(#13#10'FileWorks: Opening file for changing attributes'#13#10);
InitializeObjectAttributes(oa, @g_usFileName,
OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE,
0, nil);
RtnCode := ZwCreateFile(@hFile, FILE_READ_ATTRIBUTES + FILE_WRITE_ATTRIBUTES + SYNCHRONIZE,
@oa, @iosb, nil, 0, FILE_SHARE_READ,
FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT,
nil, 0);
if RtnCode = STATUS_SUCCESS then
begin
DbgPrint('FileWorks: File openeded'#13#10);
RtnCode := ZwQueryInformationFile(hFile, @iosb, @fbi,
sizeof(fbi),
FileBasicInformation);
if RtnCode = STATUS_SUCCESS then
begin
DbgPrint('FileWorks: File attributes were: %08X'#13#10, fbi.FileAttributes);
fbi.FileAttributes := fbi.FileAttributes or FILE_ATTRIBUTE_READONLY;
RtnCode := ZwSetInformationFile(hFile, @iosb, @fbi,
sizeof(fbi), FileBasicInformation);
if RtnCode = STATUS_SUCCESS then
begin
DbgPrint('FileWorks: Now file marked as read-only'#13#10);
end else
begin
DbgPrint('FileWorks: Can''t change file attributes. Status: %08X'#13#10, RtnCode);
end;
end else
begin
DbgPrint('FileWorks: Can''t query file attributes. Status: %08X'#13#10, RtnCode);
end;
ZwClose(hFile);
end else
begin
DbgPrint('FileWorks: Can''t open file. Status: %08X\n', RtnCode);
end;
end;
procedure ReadFile;
var
oa:OBJECT_ATTRIBUTES;
iosb:IO_STATUS_BLOCK;
hFile:THANDLE;
p:PVOID;
cb:DWORD;
fsi:FILE_STANDARD_INFORMATION;
RtnCode: NTSTATUS;
begin
DbgPrint(#13#10'FileWorks: Opening file for reading'#13#10);
InitializeObjectAttributes(oa, @g_usFileName,
OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE,
0, nil);
RtnCode := ZwOpenFile(@hFile, FILE_READ_DATA + SYNCHRONIZE,
@oa, @iosb, FILE_SHARE_READ + FILE_SHARE_WRITE + FILE_SHARE_DELETE,
FILE_SYNCHRONOUS_IO_NONALERT);
if RtnCode = STATUS_SUCCESS then
begin
DbgPrint('FileWorks: File openeded'#13#10);
RtnCode := ZwQueryInformationFile(hFile, @iosb, @fsi,
sizeof(fsi),
FileStandardInformation);
if RtnCode = STATUS_SUCCESS then
begin
cb := fsi.EndOfFile.LowPart + 1;
p := ExAllocatePool(PagedPool, cb);
if p <> nil then
begin
memset(p, 0, cb);
RtnCode := ZwReadFile(hFile, 0, nil, nil, @iosb, p, cb, nil, nil);
if RtnCode = STATUS_SUCCESS then
begin
DbgPrint('FileWorks: File content: \=%s\='#13#10, p);
end else
begin
DbgPrint('FileWorks: Can''t read from the file. Status: %08X'#13#10, RtnCode);
end;
ExFreePool(p);
end else
begin
DbgPrint('FileWorks: Can''t allocate memory. Status: %08X'#13#10, RtnCode);
end;
end else
begin
DbgPrint('FileWorks: Can''t query file size. Status: %08X'#13#10, RtnCode);
end;
ZwClose(hFile);
end else
begin
DbgPrint('FileWorks: Can''t open file. Status: %08X'#13#10, RtnCode);
end;
end;
procedure UnmarkAsReadOnly;
var
oa:OBJECT_ATTRIBUTES;
iosb:IO_STATUS_BLOCK;
hFile:THANDLE;
fbi:FILE_BASIC_INFORMATION;
RtnCode:NTSTATUS;
begin
DbgPrint(#13#10'FileWorks: Opening file for changing attributes'#13#10);
InitializeObjectAttributes(oa, @g_usFileName,
OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE,
0, nil);
RtnCode := ZwCreateFile(@hFile, FILE_READ_ATTRIBUTES + FILE_WRITE_ATTRIBUTES + SYNCHRONIZE,
@oa, @iosb, nil, 0, FILE_SHARE_READ,
FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT,
nil, 0);
if RtnCode = STATUS_SUCCESS then
begin
DbgPrint('FileWorks: File openeded'#13#10);
RtnCode := ZwQueryInformationFile(hFile, @iosb, @fbi,
sizeof(fbi), FileBasicInformation);
if RtnCode = STATUS_SUCCESS then
begin
DbgPrint('FileWorks: File attributes were: %08X'#13#10, fbi.FileAttributes);
fbi.FileAttributes := fbi.FileAttributes and (not FILE_ATTRIBUTE_READONLY);
RtnCode := ZwSetInformationFile(hFile, @iosb, @fbi, sizeof(fbi), FileBasicInformation);
if RtnCode = STATUS_SUCCESS then
begin
DbgPrint('FileWorks: Now file can be written or deleted'#13#10);
end else
begin
DbgPrint('FileWorks: Can''t change file attributes. Status: %08X'#13#10, RtnCode);
end;
end else
begin
DbgPrint('FileWorks: Can''t query file attributes. Status: %08X'#13#10, RtnCode);
end;
ZwClose(hFile);
end else
begin
DbgPrint('FileWorks: Can''t open file. Status: %08X'#13#10, RtnCode);
end;
end;
procedure AppendFile;
var
oa:OBJECT_ATTRIBUTES;
iosb:IO_STATUS_BLOCK;
hFile:THANDLE;
g_szDataToAppend:PAnsiChar;
RtnCode:NTSTATUS;
begin
DbgPrint(#13#10'FileWorks: Opening file to append data'#13#10);
InitializeObjectAttributes(oa, @g_usFileName,
OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE,
0, nil);
RtnCode := ZwOpenFile(@hFile, FILE_APPEND_DATA + SYNCHRONIZE,
@oa, @iosb, FILE_SHARE_READ,
FILE_SYNCHRONOUS_IO_NONALERT);
if RtnCode = STATUS_SUCCESS then
begin
DbgPrint('FileWorks: File openeded'#13#10);
g_szDataToAppend := ' using ZwWriteFile';
RtnCode := ZwWriteFile(hFile, 0, nil, nil, @iosb, g_szDataToAppend,
strlen(g_szDataToAppend), nil, nil);
if RtnCode = STATUS_SUCCESS then
begin
DbgPrint('FileWorks: Data appended to the file'#13#10);
end else
begin
DbgPrint('FileWorks: Can''t append data to file. Status: %08X'#13#10, RtnCode);
end;
ZwClose(hFile);
end else
begin
DbgPrint('FileWorks: Can''t open file. Status: %08X'#13#10, RtnCode);
end;
end;
procedure TruncateFile;
var
oa:OBJECT_ATTRIBUTES;
iosb:IO_STATUS_BLOCK;
hFile:THANDLE;
fsi:FILE_STANDARD_INFORMATION;
feofi:FILE_END_OF_FILE_INFORMATION;
RtnCode:NTSTATUS;
begin
DbgPrint(#13#10'FileWorks: Opening file to truncate'#13#10);
InitializeObjectAttributes(oa, @g_usFileName,
OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE,
0, nil);
RtnCode := ZwOpenFile(@hFile, FILE_WRITE_DATA + SYNCHRONIZE,
@oa, @iosb, FILE_SHARE_READ,
FILE_SYNCHRONOUS_IO_NONALERT);
if RtnCode = STATUS_SUCCESS then
begin
DbgPrint('FileWorks: File openeded'#13#10);
RtnCode := ZwQueryInformationFile(hFile, @iosb, @fsi,
sizeof(fsi),
FileStandardInformation);
if RtnCode = STATUS_SUCCESS then
begin
DbgPrint('FileWorks: EOF was: %08X'#13#10, fsi.EndOfFile.LowPart);
feofi.EndOfFile.HighPart := 0;
feofi.EndOfFile.LowPart := (fsi.EndOfFile.LowPart) shr 1;
RtnCode := ZwSetInformationFile(hFile, @iosb, @feofi,
sizeof(feofi),
FileEndOfFileInformation);
if RtnCode = STATUS_SUCCESS then
begin
DbgPrint('FileWorks: File truncated to its half size'#13#10);
end else
begin
DbgPrint('FileWorks: Can''t truncate file. Status: %08X'#13#10, RtnCode);
end;
end else
begin
DbgPrint('FileWorks: Can''t query file info. Status: %08X'#13#10, RtnCode);
end;
ZwClose(hFile);
end else
begin
DbgPrint('FileWorks: Can''t open file. Status: %08X'#13#10, RtnCode);
end;
end;
procedure DeleteFile;
var
oa:OBJECT_ATTRIBUTES;
iosb:IO_STATUS_BLOCK;
hFile:THANDLE;
fdi:FILE_DISPOSITION_INFORMATION;
RtnCode:NTSTATUS;
begin
DbgPrint(#13#10'FileWorks: Opening file for deletion'#13#10);
InitializeObjectAttributes(oa, @g_usFileName,
OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE,
0, nil);
RtnCode := ZwCreateFile(@hFile, _DELETE + SYNCHRONIZE,
@oa, @iosb, nil, 0, FILE_SHARE_DELETE,
FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT,
nil, 0);
if RtnCode = STATUS_SUCCESS then
begin
DbgPrint('FileWorks: File openeded'#13#10);
fdi.DeleteFile := True;
RtnCode := ZwSetInformationFile(hFile, @iosb, @fdi,
sizeof(fdi),
FileDispositionInformation);
if RtnCode = STATUS_SUCCESS then
begin
DbgPrint('FileWorks: File has been marked for deletion'#13#10);
DbgPrint('FileWorks: It should be deleted when the last open handle is closed'#13#10);
end else
begin
DbgPrint('FileWorks: Can''t mark file for deletion. Status: %08X'#13#10, RtnCode);
end;
ZwClose(hFile);
end else
begin
DbgPrint('FileWorks: Can''t open file. Status: %08X'#13#10, RtnCode);
end;
end;
procedure DeleteDirectory;
var
oa:OBJECT_ATTRIBUTES;
RtnCode:NTSTATUS;
begin
InitializeObjectAttributes(oa, @g_usDirName,
OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE,
0, nil);
RtnCode := ZwDeleteFile(@oa);
if RtnCode = STATUS_SUCCESS then
begin
DbgPrint(#13#10'FileWorks: Directory should be deleted'#13#10);
end else
begin
DbgPrint(#13#10'FileWorks: Can''t delete directory. Status: %08X'#13#10, RtnCode);
end;
end;
procedure EnumerateFiles;
var
oa:OBJECT_ATTRIBUTES;
hSystemRootDirectory:THANDLE;
hDriversDirectory:THANDLE;
_as:ANSI_STRING;
us:UNICODE_STRING;
iosb:IO_STATUS_BLOCK;
tf:TIME_FIELDS;
cb:DWORD;
pfdi:PFILE_DIRECTORY_INFORMATION;
RtnCode:NTSTATUS;
g_usTemp:UNICODE_STRING;
begin
DbgPrint(#13#10'FileWorks: Opening directory to enumerate files'#13#10);
RtlInitUnicodeString(g_usTemp, '\SystemRoot');
InitializeObjectAttributes(oa, @g_usTemp,
OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE,
0, nil);
RtnCode := ZwOpenFile(@hSystemRootDirectory, FILE_LIST_DIRECTORY + SYNCHRONIZE,
@oa, @iosb, FILE_SHARE_READ + FILE_SHARE_WRITE + FILE_SHARE_DELETE,
FILE_DIRECTORY_FILE + FILE_SYNCHRONOUS_IO_NONALERT);
if RtnCode = STATUS_SUCCESS then
begin
RtlInitUnicodeString(g_usTemp, 'system32\drivers');
InitializeObjectAttributes(oa, @g_usTemp,
OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE,
hSystemRootDirectory, nil);
RtnCode := ZwOpenFile(@hDriversDirectory, FILE_LIST_DIRECTORY + SYNCHRONIZE,
@oa, @iosb, FILE_SHARE_READ + FILE_SHARE_WRITE + FILE_SHARE_DELETE,
FILE_DIRECTORY_FILE + FILE_SYNCHRONOUS_IO_NONALERT);
if RtnCode = STATUS_SUCCESS then
begin
cb := sizeof(FILE_DIRECTORY_INFORMATION) + 256;
pfdi := ExAllocatePool(PagedPool, cb);
if pfdi <> nil then
begin
RtlInitUnicodeString(g_usTemp, 'c*');
DbgPrint(#13#10'FileWorks: ---------- Starting enumerate files ----------'#13#10);
RtnCode := ZwQueryDirectoryFile(hDriversDirectory, 0, nil, nil, @iosb,
pfdi, cb, FileDirectoryInformation,
true, @g_usTemp, true);
while RtnCode <> STATUS_NO_MORE_FILES do
begin
if RtnCode = STATUS_SUCCESS then
begin
us.Length := pfdi^.FileNameLength;
us.MaximumLength := pfdi^.FileNameLength;
us.Buffer := PWideChar(@pfdi^.FileName);
if RtlUnicodeStringToAnsiString(@_as, @us, true) = STATUS_SUCCESS then
begin
RtlTimeToTimeFields(@pfdi^.CreationTime, @tf);
DbgPrint(' %s size=%d created on %d.%02d.%04d'#13#10,
_as.Buffer, pfdi^.EndOfFile.LowPart,
BYTE(tf.Day), BYTE(tf.Month), WORD(tf.Year));
RtlFreeAnsiString(@_as);
end;
end;
RtnCode := ZwQueryDirectoryFile(hDriversDirectory, 0, nil, nil, @iosb,
pfdi, cb, FileDirectoryInformation,
true, nil, false);
end; {End While}
DbgPrint('FileWorks: ------------------------------------------------'#13#10);
ExFreePool(pfdi);
end;
ZwClose(hDriversDirectory);
end else
begin
DbgPrint('FileWorks: Can''t open drivers directory. Status: %08X', RtnCode);
end;
ZwClose(hSystemRootDirectory);
end else
begin
DbgPrint('FileWorks: Can''t open system root directory. Status: %08X'#13#10, RtnCode);
end;
end;
function _DriverEntry(pDriverObject:PDRIVER_OBJECT;
pusRegistryPath:PUNICODE_STRING): NTSTATUS; stdcall;
begin
DbgPrint(#13#10'FileWorks: Entering DriverEntry'#13#10);
RtlInitUnicodeString(g_usFileName, '\??\c:\FileWorks\test.txt');
RtlInitUnicodeString(g_usDirName, '\??\c:\FileWorks');
CreateDirectory;
CreateFile;
WriteFile;
MarkAsReadOnly;
ReadFile;
UnmarkAsReadOnly;
AppendFile;
ReadFile;
TruncateFile;
ReadFile;
DeleteFile;
DeleteDirectory;
EnumerateFiles;
DbgPrint(#13#10'FileWorks: Leaving DriverEntry'#13#10);
result := STATUS_DEVICE_CONFIGURATION_ERROR;
end;
end.
InitializeObjectAttributes(oa, @g_usDirName, OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE, 0, nil);
RtnCode := ZwCreateFile(@hDirectory, SYNCHRONIZE, @oa, @iosb, nil,FILE_ATTRIBUTE_NORMAL, 0,
FILE_OPEN_IF,FILE_DIRECTORY_FILE+FILE_SYNCHRONOUS_IO_NONALERT,
nil, 0); NTSTATUS
ZwCreateFile(
OUT PHANDLE FileHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PLARGE_INTEGER AllocationSize OPTIONAL,
IN ULONG FileAttributes,
IN ULONG ShareAccess,
IN ULONG CreateDisposition,
IN ULONG CreateOptions,
IN PVOID EaBuffer OPTIONAL,
IN ULONG EaLength
);
if RtnCode = STATUS_SUCCESS then
begin
if iosb.Information = FILE_CREATED then
begin
……
end else if iosb.Information = FILE_OPENED then
begin
……
end;
p_Irp^.IoStatus.Status := STATUS_SUCCESS;
p_Irp^.IoStatus.Information := 0;
IofCompleteRequest(p_Irp, IO_NO_INCREMENT);
RtnCode := ZwCreateFile(@hFile, SYNCHRONIZE, @oa, @iosb, nil,
FILE_ATTRIBUTE_NORMAL, 0,
FILE_CREATE,
FILE_SYNCHRONOUS_IO_NONALERT, nil, 0);
TFileObject=packed record
wType:Word;
Size:Word;
DeviceObject:PDeviceObject;
DoNotUser1:Pointer;
FsContext:Pointer;
FsContext2:Pointer;
SectionObjectPointer:Pointer;
PrivateCacheMap:Pointer;
FinalStatus:NTSTATUS;
RelatedFileObject:PFileObject;
LockOperation:Boolean;
DeletePending:Boolean;
ReadAccess:Boolean;
WriteAccess:Boolean;
DeleteAccess:Boolean;
SharedRead:Boolean;
SharedWrite:Boolean;
SharedDelete:Boolean;
Flags:Cardinal;
FileName:TUnicodeString;
CurrentByteOffset:TLargeInteger;
Waiters:Cardinal;
Busy:Cardinal;
LastLock:Pointer;
Lock:TKEvent;
Event:TKEvent;
CompletionContext:Pointer;
end;
var
pFileObject:PFILE_OBJECT;
. . .
begin
RtnCode := ObReferenceObjectByHandle(hFile, FILE_READ_DATA, nil, KernelMode, @pFileObject,nil);
if RtnCode = STATUS_SUCCESS then
begin
{pFileObject指向对应于hFile的FILE_OBJECT}
ObfDereferenceObject(pFileObject);
end;
end; RtnCode := ZwCreateFile(@hFile, FILE_WRITE_DATA + SYNCHRONIZE,
@oa, @iosb, nil, 0, FILE_SHARE_READ,
FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT,
nil, 0);
FILE_GENERIC_WRITE = (STANDARD_RIGHTS_WRITE or
FILE_WRITE_DATA or
FILE_WRITE_ATTRIBUTES or
FILE_WRITE_EA or
FILE_APPEND_DATA or
SYNCHRONIZE);
if RtnCode = STATUS_SUCCESS then
begin
DbgPrint('FileWorks: File openeded'#13#10);
g_szData := 'Data can be written to an open file';
RtnCode := ZwWriteFile(hFile, 0, nil, nil, @iosb, g_szData,
strlen(g_szData), nil, nil); NTSTATUS
ZwWriteFile(
IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset OPTIONAL,
IN PULONG Key OPTIONAL
);
RtnCode := ZwCreateFile(@hFile, FILE_READ_ATTRIBUTES + FILE_WRITE_ATTRIBUTES + SNCHRONIZE, @oa, @iosb, nil, 0, FILE_SHARE_READ,
FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT,
nil, 0);
if RtnCode = STATUS_SUCCESS then
begin
DbgPrint('FileWorks: File openeded'#13#10);
RtnCode := ZwQueryInformationFile(hFile, @iosb, @fbi,
sizeof(fbi),
FileBasicInformation);
if RtnCode = STATUS_SUCCESS then
begin fbi.FileAttributes := fbi.FileAttributes or FILE_ATTRIBUTE_READONLY;
RtnCode := ZwSetInformationFile(hFile, @iosb, @fbi,
sizeof(fbi), FileBasicInformation);
fbi.FileAttributes := fbi.FileAttributes and (not FILE_ATTRIBUTE_READONLY);
NTSTATUS
ZwOpenFile(
OUT PHANDLE FileHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN ULONG ShareAccess,
IN ULONG OpenOptions
);
RtnCode := ZwOpenFile(@hFile, FILE_READ_DATA + SYNCHRONIZE,
@oa, @iosb, FILE_SHARE_READ + FILE_SHARE_WRITE + FILE_SHARE_DELETE,
FILE_SYNCHRONOUS_IO_NONALERT);
FILE_READ_DATA——在这里我们只从文件中读取数据。标志FILE_SHARE_READ、FILE_SHARE_WRITE和FILE_SHARE_DELETE的组合允许对文件进行完全的访问。
if RtnCode = STATUS_SUCCESS then
begin
DbgPrint('FileWorks: File openeded'#13#10);
RtnCode := ZwQueryInformationFile(hFile, @iosb, @fsi,
sizeof(fsi),
FileStandardInformation);
if RtnCode = STATUS_SUCCESS then
begin
p := ExAllocatePool(PagedPool, cb);
if p <> nil then
begin
memset(p, 0, cb);
RtnCode := ZwReadFile(hFile, 0, nil, nil, @iosb, p, cb, nil, nil);
if RtnCode = STATUS_SUCCESS then
begin
DbgPrint('FileWorks: File content: \=%s\='#13#10, p);
End;
ExFreePool(p);
end;
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!