Skip to content

Registry Operations

Ido Veltzman edited this page Jan 14, 2024 · 4 revisions

Registry Item Protecting - From Deletion

Protecting a registry key or value from deleting using a CmRegistryCallback. This feature is not enabled when the driver is loaded reflectively.

Function Signature

NTSTATUS RegistryUtils::RegNtPreDeleteKeyHandler(REG_DELETE_KEY_INFORMATION* info)

info [REG_DELETE_KEY_INFORMATION*] -- Contains important information such as key path, key object, etc.
NTSTATUS RegistryUtils::RegNtPreDeleteValueKeyHandler(REG_DELETE_VALUE_KEY_INFORMATION* info)

info [REG_DELETE_VALUE_KEY_INFORMATION*] -- Contains important information such as key path, value name, key object, etc.

Usage Example

# Protecting a registry key
NidhoggClient.exe reg add <PATH>

# Unprotecting registry key
NidhoggClient.exe reg remove <PATH>
# Protecting a registry value
NidhoggClient.exe reg add <PATH> <VALUE NAME>

# Unprotecting registry value
NidhoggClient.exe reg remove <PATH> <VALUE NAME>

How It Works

Registry Key

The function begins by checking if the Object in the info structure is valid kernel-mode memory. If it is not, it returns STATUS_SUCCESS.

Next, it gets the key object ID and the registry path of the key object. If this operation fails, it returns STATUS_SUCCESS.

The function then checks if the Buffer in the regPath structure is NULL, if the Length of the regPath is zero, or if the Buffer is not valid kernel-mode memory. If any of these conditions are true, it returns STATUS_SUCCESS.

The function then copies the Buffer from the regPath to a RegItem structure, and sets the type of the RegItem to RegProtectedKey.

It checks if the RegItem is in the list of protected registry items. If it is, it sets the status to STATUS_ACCESS_DENIED.

Finally, it releases the key object ID and returns the status of the operation. If the operation was successful, it means that the registry key was not protected and was allowed to be deleted. If the status is STATUS_ACCESS_DENIED, it means that the registry key was protected and the deletion was blocked.

Registry Value

The function begins by checking if the Object in the info structure is valid kernel-mode memory. If it isn't, it returns STATUS_SUCCESS.

Next, it gets the key object ID and the registry path of the key object. If this operation fails, it returns STATUS_SUCCESS.

The function then checks if the Buffer in the regPath structure is NULL, if the Length of the regPath is zero, or if the Buffer is not valid kernel-mode memory. If any of these conditions are true, it returns STATUS_SUCCESS.

The function then copies the Buffer from the regPath and the ValueName from the info structure to a RegItem structure, and sets the Type of the RegItem to RegProtectedValue.

It checks if the RegItem is in the list of protected registry items. If it is, it sets the status to STATUS_ACCESS_DENIED.

Finally, it releases the key object ID and returns the status of the operation. If the operation was successful, it means that the registry value was not protected and was allowed to be deleted. If the status is STATUS_ACCESS_DENIED, it means that the registry value was protected and the deletion was blocked.


Registry Value Protecting - From overwrite

Protecting a registry value from overwriting using a CmRegistryCallback. This feature is not enabled when the driver is loaded reflectively.

Function Signature

NTSTATUS RegistryUtils::RegNtPreSetValueKeyHandler(REG_SET_VALUE_KEY_INFORMATION* info)

info [REG_SET_VALUE_KEY_INFORMATION*] -- Contains important information such as key path, value name, key object, etc.

Usage Example

# Protecting a registry value
NidhoggClient.exe reg add <PATH> <VALUE NAME>

# Unprotecting registry value
NidhoggClient.exe reg remove <PATH> <VALUE NAME>

How It Works

The function begins by checking if the Object in the info structure is valid kernel-mode memory. If it is not, it returns STATUS_SUCCESS.

Next, it gets the key object ID and the registry path of the key object. If this operation fails, it returns STATUS_SUCCESS.

The function then checks if the Buffer in the regPath structure is NULL, if the Length of the regPath is zero, or if the Buffer is not valid kernel-mode memory. If any of these conditions are true, it returns STATUS_SUCCESS.

The function then copies the Buffer from the regPath and the ValueName from the info structure to a RegItem structure, and sets the type of the RegItem to RegProtectedValue.

It checks if the RegItem is in the list of protected registry items. If it is, it sets the status to STATUS_ACCESS_DENIED.

Finally, it releases the key object ID and returns the status of the operation. If the operation was successful, it means that the registry value was not protected and was allowed to be modified. If the status is STATUS_ACCESS_DENIED, it means that the registry value was protected and the modification was blocked.


Registry Item Hiding

Hiding a registry key or value from querying using a CmRegistryCallback. This feature is not enabled when the driver is loaded reflectively. The documentation below is for RegNtPostEnumerateKey and RegNtPostEnumerateValueKey only because RegNtPreQueryKey and RegNtPreQueryValueKey works the same as the functions mentioned above.

Function Signature

NTSTATUS RegistryUtils::RegNtPostEnumerateKeyHandler(REG_POST_OPERATION_INFORMATION* info)

info [REG_POST_OPERATION_INFORMATION*] -- Contains important information such as keys list, keys objects, etc.
NTSTATUS RegistryUtils::RegNtPostEnumerateValueKeyHandler(REG_POST_OPERATION_INFORMATION* info)

info [REG_POST_OPERATION_INFORMATION*] -- Contains important information such as keys list, keys objects, etc.

Usage Example

# Protecting a registry key
NidhoggClient.exe reg hide <PATH>

# Unprotecting registry key
NidhoggClient.exe reg unhide <PATH>
# Protecting a registry value
NidhoggClient.exe reg hide <PATH> <VALUE NAME>

# Unprotecting registry value
NidhoggClient.exe reg unhide <PATH> <VALUE NAME>

How It Works

Registry Key

The function begins by checking if the operation status in the info structure is successful. If it is not, it returns the status.

Next, it gets the key object ID and the registry path of the key object. If this operation fails, it returns STATUS_SUCCESS.

The function then checks if the registry key contains any protected registry value. If it does not, it releases the key object ID and returns STATUS_SUCCESS.

The function then gets the name from the value enumeration pre-information. If this operation fails, it releases the key object ID and returns STATUS_SUCCESS.

The function then opens the object by pointer with tag. If this operation fails, it releases the key object ID and returns STATUS_SUCCESS.

The function then allocates memory for tempValueInformation.

If tempValueInformation is not NULL, it sets the type of the item to RegHiddenValue and copies the Buffer from the regPath to the KeyPath of the item.

The function then enters a loop where it enumerates the value key and checks if the item is in the list of protected registry items. If it is not, it copies the tempValueInformation to the KeyValueInformation in the preInfo structure and breaks the loop. If it is, it increments the counter and continues the loop.

Finally, it sets the ReturnStatus in the info structure to the status of the operation, closes the key, releases the key object ID, and returns STATUS_SUCCESS.

Registry Value

The function begins by checking if the operation status in the info structure is successful. If it is not, it returns the status.

Next, it gets the key object ID and the registry path of the key object. If this operation fails, it returns STATUS_SUCCESS.

The function then checks if the registry key contains any protected registry value. If it does not, it releases the key object ID and returns STATUS_SUCCESS.

The function then gets the name from the value enumeration pre-information. If this operation fails, it releases the key object ID and returns STATUS_SUCCESS.

The function then opens the object by pointer with tag. If this operation fails, it releases the key object ID and returns STATUS_SUCCESS.

The function then allocates memory for tempValueInformation.

If tempValueInformation is not NULL, it sets the Type of the item to RegHiddenValue and copies the Buffer from the regPath to the KeyPath of the item.

The function then enters a loop where it enumerates the value key and checks if the item is in the list of protected registry items. If it is not, it copies the tempValueInformation to the KeyValueInformation in the preInfo structure and breaks the loop. If it is, it increments the counter and continues the loop.

Finally, it sets the ReturnStatus in the info structure to the status of the operation, closes the key, releases the key object ID, and returns STATUS_SUCCESS.