What we know as the registry is in kernel-speak the configuration manager. The Hungarian prefix for the configuration manager is CM, the code is found under ntos/config.
The configuration manager has an involved data structure arranged around (in-core) hives and cells in the hives. The CM defines it's own NT-Object type, Object-Key, which interfaces the hive to the operating system. Outside of the kernel, the registry looks like a network of Key's. However, Key's are only pointers into the hive. A symptom of this is that a key opened twice will yield two distinct Key-Objects.
The root of the registry is represented by the \REGISTRY Key-Object. It points to the Master Hive, the original hive created by cmsysini.c. The Master Hive never exists outside of core, it has no backing store. Hives have a choice of of backing-store disciplines. For instance the System Hive is backed by the %SYSTEMROOT%\Config\System file, also known as a hive.
The whole hive deal is a very sophisticated, object oriented system, where hive operations are supported by function pointers in the hive header. The hive structure is hidden behind accessor functions pointed to by header slots. The allocate function for the hive enforces a quota so that allocated hive memory does not exceed a system-defined value. This value is manipulated through Control Panel->System->Virtual Memory.
First, find the pointer to the root directory object. This is at ObpRootDirectoryObject+0x60:
kd> dd ObpRootDirectoryObject 80156c70 00000096 00087f51 0000008c 00000000 80156c80 6943624f 00000030 80109ba4 8010a43a 80156c90 80156c30 80154120 00087ec2 00000096 80156ca0 00000000 00000000 00000000 00000000 80156cb0 806e8970 806e8850 00000000 00000000 <--- 80156cc0 806e7360 80156d00 00000000 00000000 80156cd0 00000000 00000000 00000000 00000000 80156ce0 00000000 00000000 00000000 00000000 kd> !object 806e8970 Object: 806e8970 Type: (8070dd60) Directory ObjectHeader: 806e8958 HandleCount: 0 PointerCount: 39 Directory Object: 00000000 Name: \ 59 symbolic links snapped through this directory HashBucket[ 00 ]: 806e64b0 Directory 'ArcName' 806bfd30 Device 'Ntfs' HashBucket[ 01 ]: e1273f60 Port 'SeLsaCommandPort' HashBucket[ 03 ]: e1004d30 Key '\REGISTRY' HashBucket[ 06 ]: e12ba620 Port 'XactSrvLpcPort' HashBucket[ 07 ]: e1217280 Port 'DbgUiApiPort' HashBucket[ 09 ]: 80654400 Directory 'NLS' HashBucket[ 10 ]: 806e8710 SymbolicLink 'DosDevices' HashBucket[ 12 ]: 806828b0 Directory 'WinStations' HashBucket[ 13 ]: 80641f50 Event 'SC_AutoStartComplete' e1220d20 Port 'SeRmCommandPort' HashBucket[ 14 ]: 805f5d10 Device 'Dfs' e12763c0 Port 'LsaAuthenticationPort' 805f8490 Event 'LanmanServerAnnounceEvent' HashBucket[ 16 ]: e12f3360 Port 'CtxMsgSvcQualifier' 806dad50 Directory 'Driver' HashBucket[ 17 ]: e11d65a0 Port 'DbgSsApiPort' HashBucket[ 19 ]: 806e63d0 Directory 'Device' HashBucket[ 20 ]: 80661030 Directory 'Windows' HashBucket[ 21 ]: 8063a970 Event 'SAM_SERVICE_STARTED' HashBucket[ 22 ]: 80661f50 Directory 'RPC Control' e1223dc0 Port 'SmApiPort' 806367b0 Device 'Fat' HashBucket[ 23 ]: 806557d0 Directory 'BaseNamedObjects' HashBucket[ 24 ]: 806e8770 Directory '??' 806dac70 Directory 'FileSystem' HashBucket[ 26 ]: e12ed040 Port 'SmSsWinStationApiPort' 80656350 Process 'WindowsSS' 806e8850 Directory 'ObjectTypes' HashBucket[ 27 ]: 806e8070 Directory 'Security' 805f29f0 Event 'NETLOGON_SERVICE_STARTED' e1278d80 Port 'ErrorLogPort' HashBucket[ 29 ]: e12df680 Port 'NtLmSecuritySupportProviderPort' HashBucket[ 31 ]: 80663f50 SymbolicLink 'SystemRoot' 8064f2f0 Device 'Cdfs' HashBucket[ 33 ]: 806693d0 Event 'SeLsaInitEvent' HashBucket[ 35 ]: 80661e70 Directory 'KnownDlls'
typedef struct _CM_KEY_BODY { ULONG Type; PCM_KEY_CONTROL_BLOCK KeyControlBlock; PCM_NOTIFY_BLOCK NotifyBlock; } CM_KEY_BODY, *PCM_KEY_BODY; kd> !object e1004d30 Object: e1004d30 Type: (806e5500) Key ObjectHeader: e1004d18 HandleCount: 1 PointerCount: 3 Directory Object: 00000000 Name: \REGISTRY kd> dd e1004d18 e1004d18 00000003 00000001 806e5500 00000010 e1004d28 00000001 00000000 6b793032 e1005ca8 <--- e1004d38 00000000 00000000 01021102 6944624f e1004d48 00000000 806e5500 00000000 00000000 e1004d58 00000000 00000000 08021101 74536d4d e1004d68 00000000 00000024 00024000 00000000 e1004d78 00000024 00000000 806e5608 00000000 e1004d88 00000000 00000000 00000000 00000000chasing the CONTROL_BLOCK pointer, we confirm our location by db'ing the NameBuffer.
typedef struct _CM_KEY_CONTROL_BLOCK { BOOLEAN Delete; SHORT RefCount; PHHIVE KeyHive; // Hive containing CM_KEY_NODE HCELL_INDEX KeyCell; // Cell containing CM_KEY_NODE struct _CM_KEY_NODE *KeyNode; // pointer to CM_KEY_NODE struct _CM_KEY_CONTROL_BLOCK *Parent; // parent in binary tree struct _CM_KEY_CONTROL_BLOCK *Left; // left child struct _CM_KEY_CONTROL_BLOCK *Right; // right child UNICODE_STRING FullName; // p->canonical name of key WCHAR NameBuffer[1]; // Variable length array, holds // body of actual name. MUST BE LAST } CM_KEY_CONTROL_BLOCK, *PCM_KEY_CONTROL_BLOCK; kd> dd e1005ca8 e1005ca8 00010000 e1005ce8 00000020 e1008024 e1005cb8 00000000 e1004628 e120ca48 00120012 e1005cc8 e1005ccc 0052005c 00470045 00530049 e1005cd8 00520054 00000059 0d022202 20204d43 e1005ce8 bee0bee0 801b7802 801b8c04 801b8c82 e1005cf8 801b6dca 801b8d6c 801b8cda 801b8e06 e1005d08 e1006000 00000000 00000000 00000000 e1005d18 00000000 00000001 00000000 00000001 kd> db e1005cc8 e1005cc8 cc 5c 00 e1 5c 00 52 00-45 00 47 00 49 00 53 00 .\..\.R.E.G.I.S. e1005cd8 54 00 52 00 59 00 00 00-02 22 02 0d 43 4d 20 20 T.R.Y...."..CM e1005ce8 e0 be e0 be 02 78 1b 80-04 8c 1b 80 82 8c 1b 80 .....x.......... e1005cf8 ca 6d 1b 80 6c 8d 1b 80-da 8c 1b 80 06 8e 1b 80 .m..l........... e1005d08 00 60 00 e1 00 00 00 00-00 00 00 00 00 00 00 00 .`.............. kd> du e1005ccc e1005ccc "\REGISTRY" kd>So we can investigate the parent and children pointers. Left child:
kd> dd e1004628 e1004628 00010000 e1005a28 800001f0 e114f1f4 e1004638 e1005ca8 e1005548 00000000 00800080 e1004648 e100464c 0052005c 00470045 00530049 e1004658 00520054 005c0059 0061004d 00680063 e1004668 006e0069 005c0065 00790053 00740073 e1004678 006d0065 0043005c 006e006f 00720074 e1004688 006c006f 00650053 00300074 00310030 e1004698 0048005c 00720061 00770064 00720061 kd> du e100464c e100464c "\REGISTRY\Machine\System\Control" e100468c "Set001\Hardware Profiles\Current" e10046cc " "Right Child:
kd> dd e120ca48 e120ca48 00010000 e122a428 00043f80 e1443f84 e120ca58 e1005ca8 e1124fa8 e12e18c8 008c008c e120ca68 e120ca6c 0052005c 00470045 00530049 e120ca78 00520054 005c0059 0041004d 00480043 e120ca88 004e0049 005c0045 004f0053 00540046 e120ca98 00410057 00450052 004d005c 00430049 e120caa8 004f0052 004f0053 00540046 0057005c e120cab8 004e0049 004f0044 00530057 004e0020 kd> du e120ca6c e120ca6c "\REGISTRY\MACHINE\SOFTWARE\MICRO" e120caac "SOFT\WINDOWS NT\CURRENTVERSION\P" e120caec "ERFLIB" kd>
typedef struct _HHIVE { ULONG Signature; PGET_CELL_ROUTINE GetCellRoutine; PALLOCATE_ROUTINE Allocate; PFREE_ROUTINE Free; PFILE_SET_SIZE_ROUTINE FileSetSize; PFILE_WRITE_ROUTINE FileWrite; PFILE_READ_ROUTINE FileRead; PFILE_FLUSH_ROUTINE FileFlush; struct _HBASE_BLOCK *BaseBlock; RTL_BITMAP DirtyVector; // only for Stable bins ULONG DirtyCount; ULONG DirtyAlloc; // allocated bytges for dirty vect ULONG Cluster; // Usually 1 512 byte sector. // Set up force writes to be // done in larger units on // machines with larger sectors. // Is number of logical 512 sectors. BOOLEAN Flat; // TRUE if FLAT BOOLEAN ReadOnly; // TRUE if READONLY BOOLEAN Log; BOOLEAN Alternate; ULONG HiveFlags; ULONG LogSize; ULONG RefreshCount; // debugging aid ULONG StorageTypeCount; // 1 > Number of largest valid // type. (1 for Stable only, // 2 for stable & volatile) ULONG Version; // hive version, to allow supporting multiple // formats simultaneously. struct _DUAL { ULONG Length; PHMAP_DIRECTORY Map; PHMAP_TABLE SmallDir; ULONG Guard; // Always == -1 HCELL_INDEX FreeDisplay[HHIVE_FREE_DISPLAY_SIZE]; ULONG FreeSummary; LIST_ENTRY FreeBins; // list of freed HBINs (FREE_HBIN) } Storage[ HTYPE_COUNT ]; // // Caller defined data goes here // } HHIVE, *PHHIVE; kd> dd e1005ce8 e1005ce8 bee0bee0 801b7802 801b8c04 801b8c82 e1005cf8 801b6dca 801b8d6c 801b8cda 801b8e06 e1005d08 e1006000 00000000 00000000 00000000 e1005d18 00000000 00000001 00000000 00000001 e1005d28 00000000 00000000 00000002 00000003 e1005d38 00001000 e1005d40 e1009000 ffffffff e1005d48 ffffffff 000001f0 ffffffff ffffffff e1005d58 ffffffff ffffffff ffffffff ffffffff kd> dd e1005d68 ffffffff ffffffff ffffffff ffffffff e1005d78 ffffffff 000002c8 ffffffff ffffffff e1005d88 ffffffff ffffffff ffffffff ffffffff e1005d98 ffffffff ffffffff ffffffff 000005d8 e1005da8 00802002 e1005dac e1005dac 00000000 e1005db8 00000000 00000000 ffffffff ffffffff e1005dc8 ffffffff ffffffff ffffffff ffffffff e1005dd8 ffffffff ffffffff ffffffff ffffffff kd> dd e1005de8 ffffffff ffffffff ffffffff ffffffff e1005df8 ffffffff ffffffff ffffffff ffffffff e1005e08 ffffffff ffffffff ffffffff ffffffff e1005e18 ffffffff ffffffff ffffffff 00000000 e1005e28 e1005e28 e1005e28 00000000 00000000 e1005e38 00000000 00000000 e12fbf08 00000000 e1005e48 00000003 801cb3d0 e1005b8c 00000001 e1005e58 00000000 00000000 00040001 00000000 kd> dd e1005e68 e1005e68 e1005e68 00000000 00000000 e1005e78 00000000 00000000 0102220d 6d4e624f e1005e88 0065004b 00000079 00000000 00000000 e1005e98 00000000 00000000 08022201 74536d4d e1005ea8 00000000 00000020 00020000 00000000 e1005eb8 00000020 00000000 806460c8 00000000 e1005ec8 00000000 00000000 00000000 00000000 e1005ed8 00000000 00000000 00000000 00000000