1. Use Files in the driver
In Windows, an object is represented by a file object, which is an object managed by the object manager. For example, a directory is also represented by a file object.
The kernel component uses an object name to reference a file.\ DosDevices. (In Windows 2000 and subsequent operating systems,\??Equivalent\ DosDevices). For exampleC: \ WINDOWS \ example.txtObject Name\ DosDevices \ C: \ WINDOWS \ example.txt. You need to use the object name to open the file to obtain the handle.
The object name is described below.
Steps for using the file:
- Open the file and return the file handle.
- Call appropriateZwXxxFileFunction to complete file operations.
- Call the ZwClose function to close the opened file handle.
When you open a file handle pointing to a file, the Windows execution body creates a file object to represent the file and returns a file handle representing the object. Therefore, for a single file, there will be multiple file objects. Similarly, because user-Mode Applications may copy file handles, there are also multiple file handles for the same file object. Only when all file handles pointing to a file object are closed will the Windows Executable body delete the file object.
Ii. Object Name
Objects in kernel mode can be named or unknown.Object NameIt is a unicode string and can be used to reference objects in both user mode and kernel mode. For example,\ KernelObjects \ LowMemoryConditionIs a standard event object name that indicates a low total available memory in the system.
Both user mode and kernel mode use the object name to open the handle pointing to the object. All subsequent operations must be completed with the opened handle.
If the object is unknown, the user mode component cannot open the handle pointing to the object. The kernel mode is different. It can reference unknown objects through pointers or handles.
The named object is organized into a layered structure. The name of each object is related to its parent object. The object name of each component starts with a backslash. For example,\ KernelObjectsThe object is\ KernelObjects \ LowMemoryConditionThe parent object of the object.
Only some types of objects have sub-objects. Some of them are listed below:
1. Directory object. The Object Manager uses directory objects to manage objects, for example,\ KernelObjectsIs a directory object used to maintain standard event objects. The directory object does not correspond to the actual disk directory. Here, the directory does not mean the folder directory.
2. disk drive device object. This corresponds to disk files (including regular Directories.
3. represents the file object in the directory. All files under the specified directory.
4. WDM driver device object. It has its own namespace and can be used in the driver definition method.
The object name is\ DosDevices. For exampleThe Object Name of C: \ Directory \ File is\ DosDevices \ C: \ Directory \ File.
The following table describes a set of typical object names.
Object Name |
Description |
\ DosDevices |
Object directory |
\ DosDevices \ C: |
Indicates the device object of drive C. |
\ DosDevices \ C :\Directory |
NameC: \ DirectorObject |
\ DosDevices \ C :\Directory\File |
NameC: \ Directo \ FilerObject |
The driver can create a named object in the specified object directory.
3. Open the handle pointing to the file
To open the file handle, follow these steps:
1. Define eachOBJECT_ATTRIBUTESStruct variable, and then callInitializeObjectAttributesThe function initializes the variable. The key is to set the change volume.ObjectNameThe field is the object name.
2. CallIoCreateFile,
ZwCreateFile, OrZwOpenFileTo pass the struct variable defined above. If it succeeds, the handle for executing the file will be returned.
Note: drivers are generally used.ZwCreateFileAndZwOpenFile,IoCreateFileRarely used
WhenZwCreateFile,ZwOpenFileOrIoCreateFileIn Windows, create a new file object that represents the file and return a handle pointing to the object. The file object always exists, knowing that you have disabled all file handles pointing to it.
4. Use a file handle to operate a file
The following table lists the common functions used by the driver to operate files using file handles.
Operation |
Function |
Read files |
ZwReadFile |
Write files |
Zwwritefile |
Familiar with reading files |
Zwqueryinformationfile |
Set file familiarity |
Zwsetinformationfile |
5. sample file code used in the driver
/** @ File
* Copyright (C): Information Technology Co Ltd., All rights reserved.
* @ N
* @ N file: MyKFile. h
* @ N function: process operations on kernel files
* @ N Author: aurain (zhangqiushui@gmail.com)
*/
# Ifndef _ MYKFILE_H __
# Define _ MYKFILE_H __
# Include "debug. h"
/**
* Create or open a file
* @ Param lpFileHandle returns the opened file handle pointer
* @ Param usFileName: the path of the file to be opened. Use the object path, for example \\?? \ C: \ test.txt
* @ Param dwDesiredAccess: You can use | (OR) to combine the following operations.
Write File Content-FILE_WRITE_DATA, set file familiarity-FILE_WRITE_ATTRIBUTES, General write-GENERIC_WRITE
Read File Content-FILE_READ_DATA, set file familiarity-FILE_READE_ATTRIBUTES, General write-GENERIC_READ
DELETE file-DELETE
All permissions-GENERIC_ALL
SYNCHRONIZE
* @ Param dww.access sharing method (that is, when this code is used to open this file, other codes are allowed to open this file at the same time.
You can use | (OR) to combine the following operations:
Shared read-file_assist_read
Shared write-file_pai_write
Shared deletion-file_assist_delete
* @ Param dwCreateDisposition: Object creation or opening
Create File-FILE_CREATE
Open File-FILE_OPEN
Open or create-FILE_OPEN_IF
Overwrite-FILE_OVERWRITE
New or overwrite-FILE_OVERWRITE_IF
Create or replace-FILE_SUPERSEDE
* @ Param dwCreateOptions option settings when opening a file
FILE_NOT_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT
* @ Return: read successful: STATUS_SUCCESS; read failed: NTSTATUS error code
*/
_ Inline
NTSTATUS MyCreateFile (out phandle lpFileHandle,
IN PUNICODE_STRING usFileName,
In ulong dwDesiredAccess,
In ulong dww.access,
In ulong dwCreateDisposition,
In ulong dwcreateoptions)
{
Ntstatus = status_unsuccessful;
Object_attributes oaname;
Io_status_block iosblock;
If (lpfilehandle! = NULL & usfilename! = NULL & usfilename-> buffer! = NULL)
{
If (passive_level! = Kegetcurrentirql ())
{
Return ntstatus;
}
InitializeObjectAttributes (& oaName,
UsFileName,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
NULL,
NULL );
NtStatus = ZwCreateFile (lpFileHandle,
DwDesiredAccess,
& OaName,
& IosBlock,
NULL,
FILE_ATTRIBUTE_NORMAL,
Dww.access,
DwCreateDisposition,
DwCreateOptions,
NULL,
0 );
If (! NT_SUCCESS (ntStatus ))
{
DEBUG_ERROR ("[MyCreateFile] ZwCreateFile (% ws) failed with error: % 08x \ r \ n", usFileName-> Buffer, ntStatus ));
Return ntStatus;
}
}
Return ntStatus;
}
/**
* Close the opened file handle.
* @ Param hFile file handle
* @ Return: read successful: STATUS_SUCCESS; read failed: NTSTATUS error code
*/
_ Inline
NTSTATUS MyCloseFile (in handle hFile)
{
Return ZwClose (hFile );
}
/**
* Reading file content
* @ Param hFile file handle
* @ Param pBuffer
* @ Param ulBufferSize buffer size
* @ Param pulBytesRead actual read size
* @ Return: read successful: STATUS_SUCCESS; read failed: NTSTATUS error code
*/
_ Inline
NTSTATUS MyReadFile (in handle hFile,
In pvoid pBuffer,
In ulong ulBufferSize,
Out pulong pulBytesRead)
{
IO_STATUS_BLOCK iosBlock;
NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;
If (hFile = NULL | pBuffer = NULL)
{
Return ntStatus;
}
If (PASSIVE_LEVEL <KeGetCurrentIrql ())
{
DEBUG_ERROR ("All kernel file operating functions must running on PASSIVE_LEVEL \ r \ n "));
Return ntStatus;
}
* PulBytesRead = 0;
NtStatus = ZwReadFile (hFile,
NULL,
NULL,
NULL,
& IosBlock,
PBuffer,
UlBufferSize,
NULL,
NULL );
If (NT_SUCCESS (ntStatus ))
{
// Obtain the actual read size
* PulBytesRead = (ULONG) iosBlock. Information;
}
Else
{
DEBUG_ERROR ("[MyReadFile] ZwReadFile failed with: % 08x \ r \ n", ntStatus ));
}
Return ntStatus;
}
/**
* Write content to a file
* @ Param hFile file handle
* @ Param pBuffer
* @ Param ulBufferSize buffer size
* @ Param pulBytesWrite actual write size
* @ Return: read successful: STATUS_SUCCESS; read failed: NTSTATUS error code
*/
_ Inline
NTSTATUS MyWriteFile (in handle hFile,
In pvoid pBuffer,
In ulong ulBufferSize,
Out pulong pulBytesWrite)
{
IO_STATUS_BLOCK iosBlock;
NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;
If (hFile = NULL | pBuffer = NULL)
{
Return ntstatus;
}
// All Kernel File operating functions must running on passive_level
If (passive_level! = Kegetcurrentirql ())
{
Return ntstatus;
}
* Pulbyteswrite = 0;
Ntstatus = zwwritefile (hfile,
Null,
Null,
Null,
& IosBlock,
PBuffer,
UlBufferSize,
NULL,
NULL );
If (NT_SUCCESS (ntStatus ))
{
* PulBytesWrite = (ULONG) iosBlock. Information;
}
Else
{
DEBUG_ERROR ("[MyWriteFile] ZwWriteFile failed with: % 08x \ r \ n", ntStatus ));
}
Return ntStatus;
}
# Endif