From feb67576ddf09b847c6ecf7b8fd9675ccf74e11c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Thu, 14 Dec 2023 22:02:58 +0100 Subject: [PATCH] [NTOS:CM][CMLIB] In PE mode, allow registry hives (except system ones) to use read/write access. + Improve related comments. Registry hives are opened in shared read access when NT is loaded in PE mode (MININT) or from network (the hives residing on a network share). This is true in particular for the main system hives (SYSTEM, SOFTWARE, DEFAULT, ...). However, in PE mode, we can allow other hives, e.g. those loaded by the user (with NtLoadKey) to be loaded with full read/write access, since we boot from a local computer. --- ntoskrnl/config/cmdata.c | 7 +++++-- ntoskrnl/config/cmlazy.c | 7 ++++++- ntoskrnl/config/cmsysini.c | 10 ++++------ sdk/lib/cmlib/hivewrt.c | 33 ++++++++------------------------- 4 files changed, 23 insertions(+), 34 deletions(-) diff --git a/ntoskrnl/config/cmdata.c b/ntoskrnl/config/cmdata.c index 80c91534b44..693c9ac7b26 100644 --- a/ntoskrnl/config/cmdata.c +++ b/ntoskrnl/config/cmdata.c @@ -54,11 +54,14 @@ UNICODE_STRING CmSymbolicLinkValueName = UNICODE_STRING CmpLoadOptions; +/* TRUE if the system hives must be loaded in shared mode */ BOOLEAN CmpShareSystemHives; +/* TRUE when the registry is in PE mode */ +BOOLEAN CmpMiniNTBoot; + +ULONG CmpBootType; BOOLEAN CmSelfHeal = TRUE; BOOLEAN CmpSelfHeal = TRUE; -BOOLEAN CmpMiniNTBoot; -ULONG CmpBootType; USHORT CmpUnknownBusCount; ULONG CmpTypeCount[MaximumType + 1]; diff --git a/ntoskrnl/config/cmlazy.c b/ntoskrnl/config/cmlazy.c index 6c128cb3954..ebac8a20532 100644 --- a/ntoskrnl/config/cmlazy.c +++ b/ntoskrnl/config/cmlazy.c @@ -261,9 +261,14 @@ CmpCmdInit(IN BOOLEAN SetupBoot) /* Testing: Force Lazy Flushing */ CmpHoldLazyFlush = FALSE; - /* Setup the hive list if this is not a Setup boot */ + /* Setup the system hives list if this is not a Setup boot */ if (!SetupBoot) CmpInitializeHiveList(); + + /* Now that the system hives are loaded, if we are in PE mode, + * all other hives will be loaded with full access */ + if (CmpMiniNTBoot) + CmpShareSystemHives = FALSE; } NTSTATUS diff --git a/ntoskrnl/config/cmsysini.c b/ntoskrnl/config/cmsysini.c index 50283132745..d401c726e1b 100644 --- a/ntoskrnl/config/cmsysini.c +++ b/ntoskrnl/config/cmsysini.c @@ -332,7 +332,7 @@ CmpInitHiveFromFile(IN PCUNICODE_STRING HiveName, *New = FALSE; } - /* Check if we're sharing hives */ + /* Check if the system hives are opened in shared mode */ if (CmpShareSystemHives) { /* Then force using the primary hive */ @@ -928,11 +928,9 @@ CmpInitializeSystemHive(IN PLOADER_PARAMETER_BLOCK LoaderBlock) if (!RtlCreateUnicodeString(&SystemHive->FileFullPath, L"\\SystemRoot\\System32\\Config\\SYSTEM")) return FALSE; - /* Manually set the hive as volatile, if in Live CD mode */ + /* Load the system hive as volatile, if opened in shared mode */ if (HiveBase && CmpShareSystemHives) - { SystemHive->Hive.HiveFlags = HIVE_VOLATILE; - } /* Save the boot type */ CmpBootType = SystemHive->Hive.BaseBlock->BootType; @@ -1508,7 +1506,7 @@ CmpInitializeHiveList(VOID) /* Make sure the list is set up */ ASSERT(CmpMachineHiveList[i].Name != NULL); - /* Load the hive as volatile, if in LiveCD mode */ + /* Load this root hive as volatile, if opened in shared mode */ if (CmpShareSystemHives) CmpMachineHiveList[i].HHiveFlags |= HIVE_VOLATILE; @@ -1630,7 +1628,7 @@ CmInitSystem1(VOID) /* Check if this is PE-boot */ if (InitIsWinPEMode) { - /* Set registry to PE mode */ + /* Set the registry in PE mode and load the system hives in shared mode */ CmpMiniNTBoot = TRUE; CmpShareSystemHives = TRUE; } diff --git a/sdk/lib/cmlib/hivewrt.c b/sdk/lib/cmlib/hivewrt.c index eff699ac876..c4fe4d4059d 100644 --- a/sdk/lib/cmlib/hivewrt.c +++ b/sdk/lib/cmlib/hivewrt.c @@ -21,11 +21,7 @@ IoSetThreadHardErrorMode( _In_ BOOLEAN HardErrorEnabled); #endif -/* GLOBALS *****************************************************************/ - -#if !defined(CMLIB_HOST) && !defined(_BLDR_) -extern BOOLEAN CmpMiniNTBoot; -#endif +/* GLOBALS ******************************************************************/ /* PRIVATE FUNCTIONS ********************************************************/ @@ -477,6 +473,13 @@ HvSyncHive( ASSERT(!RegistryHive->ReadOnly); ASSERT(RegistryHive->Signature == HV_HHIVE_SIGNATURE); + /* Avoid any write operations on volatile hives */ + if (RegistryHive->HiveFlags & HIVE_VOLATILE) + { + DPRINT("Hive 0x%p is volatile\n", RegistryHive); + return TRUE; + } + /* * Check if there's any dirty data in the vector. * A space with clean blocks would be pointless for @@ -490,26 +493,6 @@ HvSyncHive( return TRUE; } - /* - * We are either in Live CD or we are sharing hives. - * In either of the cases, hives can only be read - * so don't do any writing operations on them. - */ -#if !defined(CMLIB_HOST) && !defined(_BLDR_) - if (CmpMiniNTBoot) - { - DPRINT("We are sharing hives or in Live CD mode, abort syncing\n"); - return TRUE; - } -#endif - - /* Avoid any writing operations on volatile hives */ - if (RegistryHive->HiveFlags & HIVE_VOLATILE) - { - DPRINT("The hive is volatile (hive 0x%p)\n", RegistryHive); - return TRUE; - } - #if !defined(CMLIB_HOST) && !defined(_BLDR_) /* Disable hard errors before syncing the hive */ HardErrors = IoSetThreadHardErrorMode(FALSE);