⬆️ ⬇️

Undocumented features of Windows: breakpoints for registry keys

Sometimes in the process of reverse engineering of a program (including the driver), it may be necessary to interrupt its execution at the time of performing some action with a certain registry key, in such a situation, you can use the undocumented functionality of breakpoints for registry keys.



For the first time, breakpoints for registry keys appeared in Windows XP, where the kernel implemented the ability to execute int 3 instructions when opening a registry key with a mark (debugging flag) BREAK_ON_OPEN or when creating a subkey as part of such a key.





Fig. 1: CmpDoOpen function fragment



This functionality appeared in the kernel even before the release of any service packs, and there was no need to install a debugging (“checked”) version of the kernel. At the same time, there were no API functions for setting the BREAK_ON_OPEN flag, and therefore this flag could be set on the key only by editing the registry BREAK_ON_OPEN file in the HEX editor.

')

Starting from Windows Vista, the list of available debug flags has been expanded, it has become possible to set these flags through the NtSetInformationKey API function, but the functionality itself remains only in the debug kernel versions (which can be obtained from the Windows Driver Kit).



Tab. 1: Possible Debug Flag Values

FlagValueNote
BREAK_ON_OPEN0x01Opening the key
BREAK_ON_DELETE0x02Key removal
BREAK_ON_SECURITY_CHANGE0x04Security descriptor change
BREAK_ON_CREATE_SUBKEY0x08Creating a subkey
BREAK_ON_DELETE_SUBKEY0x10Removing a subkey
BREAK_ON_SET_VALUE0x20Setting value
BREAK_ON_DELETE_VALUE0x40Delete value
BREAK_ON_KEY_VIRTUALIZE0x80Key virtualization


To set the debug flag, you must call the NtSetInformationKey function, passing as its first argument the handle of the registry key for which you want to set the debug flag. The second argument is KeySetDebugInformation, and the last two arguments must describe a buffer containing a double word (DWORD) containing the value of the debugging flag (or a combination of two or more flags).



To activate the discussed breakpoints, you must set the CmpRegDebugBreakEnabled kernel variable to one.



Example



As an example, we will try to catch the moment when the value is written to the registry key “ HKEY_LOCAL_MACHINE\SYSTEM\MountedDevices ”, where the information about mounted volumes is stored, and to determine the Windows component that writes data there. To do this, mark the specified key with the BREAK_ON_SET_VALUE debug flag, BREAK_ON_SET_VALUE on the breakpoints, change the value of the CmpRegDebugBreakEnabled variable to one, and format the test disk, which we then mount.



As a result, the stop point is triggered, the following call stack is visible:



  # Child-SP RetAddr Call Site 00 ffffd000`79b851a0 fffff803`7ccf88fa nt!CmSetValueKey+0x158 01 ffffd000`79b852b0 fffff803`7c69eac3 nt!NtSetValueKey+0x73e 02 ffffd000`79b85470 fffff803`7c697e40 nt!KiSystemServiceCopyEnd+0x13 03 ffffd000`79b85678 fffff803`7d08f11e nt!KiServiceLinkage 04 ffffd000`79b85680 fffff801`46d6fcaa nt!RtlWriteRegistryValue+0x9e 05 ffffd000`79b856f0 fffff801`46d6b58c mountmgr+0xecaa 06 ffffd000`79b85820 fffff803`7cd9cd78 mountmgr+0xa58c 07 ffffd000`79b85850 fffff803`7cd9bdd5 nt!PnpNotifyDriverCallback+0x1b8 08 ffffd000`79b85900 fffff803`7cdd6755 nt!PnpNotifyDeviceClassChange+0x2f9 09 ffffd000`79b859d0 fffff803`7c66dcb7 nt!PnpDeviceEventWorker+0x4c1 0a ffffd000`79b85b50 fffff803`7c5e7071 nt!ExpWorkerThread+0x177 0b ffffd000`79b85be0 fffff803`7c699836 nt!PspSystemThreadStartup+0x23d 0c ffffd000`79b85c60 00000000`00000000 nt!KiStartSystemThread+0x16 


The call stack clearly shows that the record is initiated by the component “mountmgr”, in its code you can find the required call nt! RtlWriteRegistryValue:



 fffff801`46d6fca4 ff15fe44ffff call qword ptr [mountmgr+0x31a8 (fffff801`46d641a8)] //  nt!RtlWriteRegistryValue fffff801`46d6fcaa 488d55b7 lea rdx,[rbp-49h] 


findings



The described functionality can be used both for solving problems directly related to debugging the kernel and drivers, and for solving third-party tasks — for example, searching programs in the system image under study that use a given registry key.

Source: https://habr.com/ru/post/321288/



All Articles