Skip to content

Commit

Permalink
[SDK][CMLIB] Implement log transaction writes & Resuscitation
Browse files Browse the repository at this point in the history
=== DOCUMENTATION REMARKS ===

This implements (also enables some parts of code been decayed for years) the transacted writing of the registry. Transacted writing (or writing into registry in a transactional way) is an operation that ensures the successfulness can be achieved by monitoring two main points.
In CMLIB, such points are what we internally call them the primary and secondary sequences. A sequence is a numeric field that is incremented each time a writing operation (namely done with the FileWrite function and such) has successfully completed.

The primary sequence is incremented to suggest that the initial work of syncing the registry is in progress. During this phase, the base block header is written into the primary hive file and registry data is being written to said file in form of blocks. Afterwards the seconady sequence
is increment to report completion of the transactional writing of the registry. This operation occurs in HvpWriteHive function (invoked by HvSyncHive for syncing). If the transactional writing fails or if the lazy flushing of the registry fails, LOG files come into play.

Like HvpWriteHive, LOGs are updated by the HvpWriteLog which writes dirty data (base block header included) to the LOG themselves. These files serve for recovery and emergency purposes in case the primary machine hive has been damaged due to previous forced interruption of writing stuff into
the registry hive. With specific recovery algorithms, the data that's been gathered from a LOG will be applied to the primary hive, salvaging it. But if a LOG file is corrupt as well, then the system will perform resuscitation techniques by reconstructing the base block header to reasonable values,
reset the registry signature and whatnot.

This work is an inspiration from PR reactos#3932 by mrmks04 (aka Max Korostil). I have continued his work by doing some more tweaks and whatnot. In addition to that, the whole transaction writing code is documented.

=== IMPORTANT NOTES ===

HvpWriteLog -- Currently this function lacks the ability to grow the log file size since we pretty much lack the necessary code that deals with hive shrinking and log shrinking/growing as well. This part is not super critical for us so this shall be left as a TODO for future.

HvLoadHive -- Currently there's a hack that prevents us from refactoring this function in a proper way. That is, we should not be reading the whole and prepare the hive storage using HvpInitializeMemoryHive which is strictly used for HINIT_MEMORY but rather we must read the hive file block by block
and deconstruct the read buffer from the file so that we can get the bins that we read from the file. With the hive bins we got the hive storage will be prepared based on such bins. If one of the bins is corrupt, self healing is applied in such scenario.

For this matter, if in any case the hive we'll be reading is corrupt we could potentially read corrupt data and lead the system into failure. So we have to perform header and data recovery as well before reading the whole hive.

Another important note is that the added code grew up the binary size of x64 FreeLdr and that makes a PE image check fail because the bootloader is too large. Currently such code is disabled for AMD64, until
a real fix comes into place.
  • Loading branch information
GeoB99 committed Sep 9, 2023
1 parent c65ed82 commit 8aa29cc
Show file tree
Hide file tree
Showing 3 changed files with 1,445 additions and 241 deletions.
10 changes: 10 additions & 0 deletions sdk/lib/cmlib/cmlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,11 @@ BOOLEAN CMAPI
HvWriteHive(
PHHIVE RegistryHive);

BOOLEAN
CMAPI
HvSyncHiveFromRecover(
_In_ PHHIVE RegistryHive);

BOOLEAN
CMAPI
HvTrackCellRef(
Expand Down Expand Up @@ -545,6 +550,11 @@ ULONG CMAPI
HvpHiveHeaderChecksum(
PHBASE_BLOCK HiveHeader);

BOOLEAN CMAPI
HvpVerifyHiveHeader(
_In_ PHBASE_BLOCK BaseBlock,
_In_ ULONG FileType);

//
// Registry Self-Heal Routines
//
Expand Down

0 comments on commit 8aa29cc

Please sign in to comment.