NTSTATUS Regedit()
{
NTSTATUS status;
HANDLE hKey;
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING usKeyPath;
RtlInitUnicodeString(&usKeyPath, L"\\Registry\\Machine\\SOFTWARE");
InitializeObjectAttributes(&ObjectAttributes, &usKeyPath, OBJ_CASE_INSENSITIVE, NULL, NULL);
status = ZwOpenKey(&hKey, KEY_QUERY_VALUE, &ObjectAttributes);
if (!NT_SUCCESS(status))
{
KdPrint(("Fail to call ZwOpenKey, error code = 0x%08X", status));
return status;
}
PKEY_FULL_INFORMATION pKeyInformation;
ULONG ulResultLength = 0;
status = ZwQueryKey(hKey, KeyFullInformation, NULL, 0, &ulResultLength);
pKeyInformation = (PKEY_FULL_INFORMATION)ExAllocatePool(PagedPool, ulResultLength);
//
status = ZwQueryKey(hKey, KeyFullInformation, pKeyInformation, ulResultLength, &ulResultLength);
if (!NT_SUCCESS(status))
{
KdPrint(("Fail to call ZwOpenKey.."));
return status;
}
KdPrint(("Subkeys = %ld", pKeyInformation->SubKeys));
for (ULONG i = 0; i < pKeyInformation->SubKeys; i++)
{
UNICODE_STRING usKeyName;
PKEY_BASIC_INFORMATION pKeyBasicInformation;
ULONG ulResultLength = 0;
status = ZwEnumerateKey(hKey, i, KeyBasicInformation, NULL, 0, &ulResultLength);
KdPrint(("ZwEnumerateKey result ulResultlength = %d, i = %d", ulResultLength, i));
pKeyBasicInformation = (PKEY_BASIC_INFORMATION)ExAllocatePool(PagedPool, ulResultLength);
status = ZwEnumerateKey(hKey, i, KeyBasicInformation, pKeyBasicInformation, ulResultLength, &ulResultLength);
if (!NT_SUCCESS(status))
{
KdPrint(("Fail to call ZwEnumerateKey, error code = 0x%08X", status));
return status;
}
usKeyName.Length = (USHORT)pKeyBasicInformation->NameLength;
usKeyName.Buffer = pKeyBasicInformation->Name;
KdPrint(("key name = %wZ", &usKeyName));
ExFreePool(pKeyBasicInformation);
}
ExFreePool(pKeyInformation);
ZwClose(hKey);
return STATUS_SUCCESS;
}
Initializes a counted Unicode string.
Syntax
VOID WINAPI RtlInitUnicodeString( _Inout_ PUNICODE_STRING DestinationString, _In_opt_ PCWSTR SourceString );
Parameters
-
DestinationString [in, out]
-
The buffer for a counted Unicode string to be initialized. The length is initialized to zero if the SourceString is not specified.
SourceString [in, optional]
-
Optional pointer to a null-terminated Unicode string with which to initialize the counted string.
Syntax
Remarks
InitializeObjectAttributes initializes an OBJECT_ATTRIBUTES structure that specifies the properties of an object handle to be opened. The caller can then pass a pointer to this structure to a routine that actually opens the handle.
_Out_ PHANDLE KeyHandle,
_In_ ACCESS_MASK DesiredAccess,
_In_ POBJECT_ATTRIBUTES ObjectAttributes
);
Parameters
KeyHandle
Pointer to the HANDLE variable that receives the handle to the key.
DesiredAccess
Specifies an ACCESS_MASK value that determines the requested access to the object. For more information, see the DesiredAccess parameter of ZwCreateKey.
ObjectAttributes
//The ExAllocatePool routine is obsolete, and is exported only for existing binaries. Use ExAllocatePoolWithTag instead.
_In_ POOL_TYPE PoolType,
_In_ SIZE_T NumberOfBytes
);
_In_ HANDLE KeyHandle,
_In_ ULONG Index,
_In_ KEY_INFORMATION_CLASS KeyInformationClass,
_Out_opt_ PVOID KeyInformation,
_In_ ULONG Length,
_Out_ PULONG ResultLength
);
Parameters
KeyHandle
Handle to the registry key that contains the subkeys to be enumerated. The handle is created by a successful call to ZwCreateKey or ZwOpenKey.
Index
The index of the subkey that you want information for. If the key has n subkeys, the subkeys are numbered from 0 to n-1.
KeyInformationClass
Specifies a KEY_INFORMATION_CLASS enumeration value that determines the type of information to be received by the KeyInformation buffer. Set KeyInformationClass to one of the following values:
- KeyBasicInformation
- KeyFullInformation
- KeyNodeInformation
KeyInformation
Pointer to a caller-allocated buffer that receives the requested information. The KeyInformationClass parameter determines the type of information provided.
Length
Specifies the size, in bytes, of the KeyInformation buffer.
ResultLength
Pointer to a variable that receives the size, in bytes, of the registry-key information. If ZwEnumerateKey returns STATUS_SUCCESS, you can use the value of this variable to determine the amount of data returned. If the routine returns STATUS_BUFFER_OVERFLOW or STATUS_BUFFER_TOO_SMALL, you can use the value of this variable to determine the size of buffer required to hold the key information.
Return Value
ZwEnumerateKey returns STATUS_SUCCESS on success, or the appropriate NTSTATUS error code on failure. Possible error code values include: