Back to Home

Windows Undocumented Features: Breakpoints for Registry Keys / BI.ZONE Blog

bizone windows registry

Windows Undocumented Features: Breakpoints for Registry Keys

    Sometimes during the reverse development of a program (including a driver) it may be necessary to interrupt its execution at the moment of performing some action with a certain registry key; in this 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 realized the ability to execute int 3 instructions when opening a registry key with a mark (debug flag) BREAK_ON_OPENor when creating a subkey as part of such a key.


    Fig. 1: Fragment of the CmpDoOpen

    function This functionality appeared in the kernel even before the release of any service packs, and it was not required to install the debug ("checked") version of the kernel. However, the API functions for setting the flagBREAK_ON_OPENwas not, and therefore this flag could be set at the key only by editing the file with the registry hive in the HEX editor.

    Starting with Windows Vista, the list of available debugging flags was expanded, it became possible to set these flags through the NtSetInformationKey API function, however, the functionality itself remained only in debugging versions of the kernel (which can be taken from the Windows Driver Kit).

    Tab. 1: Possible values ​​of the debug flag
    FlagValueNote
    BREAK_ON_OPEN0x01Key opening
    BREAK_ON_DELETE0x02Key Removal
    BREAK_ON_SECURITY_CHANGE0x04Security Descriptor Change
    BREAK_ON_CREATE_SUBKEY0x08Create subkey
    BREAK_ON_DELETE_SUBKEY0x10Delete 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 it the handle of the registry key as the first argument 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), which contains the value of the debug flag (or a combination of two or more flags).

    To activate the discussed breakpoints, it is necessary to set the value of the CmpRegDebugBreakEnabled kernel variable to one.

    Example


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

    As a result, the breakpoint 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 initiates the mountmgr component, in its code you can find the required nt! RtlWriteRegistryValue call:

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

    conclusions


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

    Read Next