File and registry operations in kernel mode

Source: Internet
Author: User

Like applications, obtaining programs often deals with files and registries. However, the operations in Ring0 are different from those in Ring3. Here is a brief introduction of file and registry operations in kernel mode.

First, read and write files in the driver. First, open the file. Because a string cannot be directly accepted in the kernel, we must enter an OBJECT_ATTRIBUTES structure, which must be initialized by InitializeObjectAttributes first.

Then, the file operation functions in the kernel include: open the file: ZwCreateFile; read the file: ZwReadFile
; Write File: ZwWriteFile; get file attribute: ZwQueryInformationFile
; Modify file attributes: ZwSetInformationFile. The following code illustrates the problem:

BOOLEAN
MyCopyFile (
IN PUNICODE_STRING ustrDestFile,
IN PUNICODE_STRING ustrSrcFile
)
{
HANDLE hSrcFile, hDestFile;
PVOID buffer = NULL;
ULONG length = 0;
LARGE_INTEGER offset = {0 };
IO_STATUS_BLOCK Io_Status_Block = {0 };
OBJECT_ATTRIBUTES obj_attrib;
NTSTATUS status;
BOOLEAN bRet = FALSE;
FILE_BASIC_INFORMATION fpi;

Do
{
// Open the source file
InitializeObjectAttributes (& obj_attrib,
UstrSrcFile,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
NULL,
NULL );
Status = ZwCreateFile (& hSrcFile,
GENERIC_READ,
& Obj_attrib,
& Io_Status_Block,
NULL,
FILE_ATTRIBUTE_NORMAL,
File_pai_read,
FILE_OPEN,
FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0 );
If (! NT_SUCCESS (status ))
{
BRet = FALSE;
Goto END;
}

// Open the target file
InitializeObjectAttributes (& obj_attrib,
UstrDestFile,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
NULL,
NULL );
Status = ZwCreateFile (& hDestFile,
GENERIC_WRITE,
& Obj_attrib,
& Io_Status_Block,
NULL,
FILE_ATTRIBUTE_NORMAL,
File_pai_read,
FILE_OPEN_IF,
FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0 );
If (! NT_SUCCESS (status ))
{
BRet = FALSE;
Goto END;
}

// Allocate a 10 KB space for the buffer
Buffer = ExAllocatePool (NonPagedPool, 1024*10 );
If (buffer = NULL)
{
BRet = FALSE;
Goto END;
}

// Copy an object
While (1)
{
Length = 10*1024;
// Read the source file
Status = ZwReadFile (hSrcFile,
NULL,
NULL,
NULL,
& Io_Status_Block,
Buffer,
Length,
& Offset,
NULL );
If (! NT_SUCCESS (status ))
{
// If the status is STATUS_END_OF_FILE, it indicates that the file has been read to the end.
If (status = STATUS_END_OF_FILE)
{
BRet = TRUE;
Goto END;
}
}

// Obtain the actual read Length
Length = Io_Status_Block.Information;

// Write to the target file
Status = ZwWriteFile (hDestFile,
NULL,
NULL,
NULL,
& Io_Status_Block,
Buffer,
Length,
& Offset,
NULL );
If (! NT_SUCCESS (status ))
{
BRet = FALSE;
Goto END;
}

// Move the file pointer
Offset. QuadPart + = length;
}
// Read the object Length
Status = ZwQueryInformationFile (hDestFile,
& Io_Status_Block,
& Offset,
Sizeof (FILE_STANDARD_INFORMATION ),
FileStandardInformation );

Fpi. FileAttributes = FILE_ATTRIBUTE_HIDDEN; // sets the file attribute to hide, but the operation fails. I have not found a solution to the problem.
Status = ZwSetInformationFile (hDestFile,
& Io_Status_Block,
& Fpi,
Sizeof (FILE_BASIC_INFORMATION ),
FileBasicInformation );
If (NT_SUCCESS (status ))

{
KdPrint ("update the file successfully./n "));
Goto END;
}
} While (0 );
END:
If (hSrcFile)
{
ZwClose (hSrcFile );
}
If (hDestFile)
{
ZwClose (hDestFile );
}
If (buffer = NULL)
{
ExFreePool (buffer );
}

Return bRet;
}

The call code is as follows:

RtlInitUnicodeString (& ustrSrcFile, L "//?? // C: // windows // system32 // cmd.exe

");
RtlInitUnicodeString (& ustrDestFile, L "//?? // C: // cmd1.exe

");

Next is the registry operation. Similar to file operations, you must first open the registry, obtain a handle, and then use this handle to perform various operations. Enable registry function
ZwOpenKey, used to create or open ZwCreatKey. ZwOpenKey
Function is a simplified version of open registry operation. Modify the Registry to ZwSetValueKey. The query key value is ZwQueryValueKey.

The subkeys of the enumeration registry are completed with ZwQueryKey and ZwEnumerateKey, And the enumerated subkeys are completed with ZwQueryKey and ZwEnumerateValueKey.

It is worth noting that the paths of the subkeys in the Registry are different from those in ring3,

The HEKY_LOCAL_MACHINE method is/Registery/Machine.

HEKY_USERS corresponds to/Registry/User in the internal programming.

HEKY_CLASSES_ROOT and HEKY_CURRENT_USER do not have corresponding paths in kernel programming, but they can be obtained through other methods.

Below is a simple code to implement registry enumeration:

NTSTATUS
RegEnumTest () // enumerate registry subkeys
{
UNICODE_STRING ustrRegString;
UNICODE_STRING ustrKeyName;
HANDLE hRegister;
ULONG ulSize, I = 0;
OBJECT_ATTRIBUTES obj_attrib;
NTSTATUS status;
PKEY_FULL_INFORMATION pfi;
PKEY_BASIC_INFORMATION pbi;

// Initialization
RtlInitUnicodeString (& ustrRegString, L "// Registry // Machine // SOFTWARE // 360 Safe

");
InitializeObjectAttributes (& obj_attrib,
& UstrRegString,
OBJ_CASE_INSENSITIVE,
NULL,
NULL );
// Open the Registry
Status = ZwOpenKey (& hRegister, KEY_ALL_ACCESS, & obj_attrib );
If (NT_SUCCESS (status ))
{
KdPrint ("[Test] ZwOpenKey % wZ Success !", UstrRegString ));
}

// The first call is to obtain the required length.
ZwQueryKey (hRegister, KeyFullInformation, NULL, 0, & ulSize );
Pfi = (PKEY_FULL_INFORMATION) ExAllocatePool (PagedPool, ulSize );

// The second call is to obtain data.
ZwQueryKey (hRegister, KeyFullInformation, pfi, ulSize, & ulSize );
For (I = 0; I <pfi-> SubKeys; I ++)
{
// Obtain the length of the subitem I
ZwEnumerateKey (hRegister, I, KeyBasicInformation, NULL, 0, & ulSize );
Pbi = (PKEY_BASIC_INFORMATION) ExAllocatePool (PagedPool, ulSize );

// Obtain the data of subitem I
ZwEnumerateKey (hRegister, I, KeyBasicInformation, pbi, ulSize, & ulSize );
UstrKeyName. Length = (USHORT) pbi-> NameLength;
UstrKeyName. Buffer = pbi-> Name;

KdPrint ("[Test] The % d SubItem Name: % wZ./n", I, & ustrKeyName ));

// Release the memory
ExFreePool (pbi );
}

ExFreePool (pfi );
ZwClose (hRegister );

Return STATUS_SUCCESS;
}

------------------------------------
NTSTATUS
RegEnumSubValueTest () // enumerated registry subkey Function
{
UNICODE_STRING RegUnicodeString;
HANDLE hRegister;
ULONG ulSize;
NTSTATUS ntStatus;
UNICODE_STRING uniKeyName;
PKEY_VALUE_BASIC_INFORMATION pvbi;
PKEY_FULL_INFORMATION pfi;
ULONG I;
OBJECT_ATTRIBUTES objectAttributes;
// Initialize the UNICODE_STRING string
RtlInitUnicodeString (& RegUnicodeString,
L "// Registry // Machine // SOFTWARE // 360 Safe

");

// Initialize objectAttributes
InitializeObjectAttributes (& objectAttributes,
& RegUnicodeString,
OBJ_CASE_INSENSITIVE, // case sensitive
NULL,
NULL );
// Open the Registry
NtStatus = ZwOpenKey (& hRegister,
KEY_ALL_ACCESS,
& ObjectAttributes );

If (NT_SUCCESS (ntStatus ))
{
KdPrint ("Open register successfully/n "));
}
ZwQueryKey (hRegister,
KeyFullInformation,
NULL,
0,
& UlSize );

Pfi = (PKEY_FULL_INFORMATION)
ExAllocatePool (PagedPool, ulSize );

ZwQueryKey (hRegister,
KeyFullInformation,
Pfi,
UlSize,
& UlSize );

For (I = 0; I <pfi-> Values; I ++)
{
ZwEnumerateValueKey (hRegister,
I,
KeyValueBasicInformation,
NULL,
0,
& UlSize );

Pvbi = (PKEY_VALUE_BASIC_INFORMATION)
ExAllocatePool (PagedPool, ulSize );

ZwEnumerateValueKey (hRegister,
I,
KeyValueBasicInformation,
Pvbi,
UlSize,
& UlSize );
UniKeyName. Length =
UniKeyName. MaximumLength =
(USHORT) pvbi-> NameLength;

UniKeyName. Buffer = pvbi-> Name;

KdPrint ("The % d sub value name: % wZ/n", I, & uniKeyName ));

If (pvbi-> Type = REG_SZ)
{
KdPrint ("The sub value type: REG_SZ/n "));
} Else if (pvbi-> Type = REG_MULTI_SZ)
{
KdPrint ("The sub value type: REG_MULTI_SZ/n "));

} Else if (pvbi-> Type = REG_DWORD)
{
KdPrint ("The sub value type: REG_DWORD/n "));
} Else if (pvbi-> Type = REG_BINARY)
{
KdPrint ("The sub value type: REG_BINARY/n "));
}

ExFreePool (pvbi );
}

ExFreePool (pfi );
ZwClose (hRegister );
Return STATUS_SUCCESS;
}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.