Blob Blame History Raw
From 691f5532ab4138093cdd8c661aba7519b0b1e2ad Mon Sep 17 00:00:00 2001
From: Dawid Zamirski <dzamirski@datto.com>
Date: Thu, 16 Feb 2017 18:17:22 -0500
Subject: [PATCH 08/16] add HIVEX_OPEN_UNSAFE flag.

This flag will be used to control behavior of libhivex API functions so
that they tolerate corruption in hives by either using heuristic
recovery from unexpected situations or simply ignore bad registry
keys/values whenever possible.

(cherry picked from commit 507f9328c67c701c32894249437551395bd8072c)
---
 generator/generator.ml | 8 ++++++++
 lib/handle.c           | 1 +
 lib/hivex-internal.h   | 1 +
 3 files changed, 10 insertions(+)

diff --git a/generator/generator.ml b/generator/generator.ml
index 64c7681..249a317 100755
--- a/generator/generator.ml
+++ b/generator/generator.ml
@@ -113,6 +113,7 @@ let open_flags = [
   1, "VERBOSE", "Verbose messages";
   2, "DEBUG", "Debug messages";
   4, "WRITE", "Enable writes to the hive";
+  8, "UNSAFE", "Enable heuristics to allow read/write of corrupted hives";
 ]
 
 (* The API calls. *)
@@ -145,6 +146,13 @@ Open the hive for writing.  If omitted, the hive is read-only.
 
 See L<hivex(3)/WRITING TO HIVE FILES>.
 
+=item HIVEX_OPEN_UNSAFE
+
+Open the hive in unsafe mode that enables heuristics to handle corrupted hives.
+
+This may allow to read or write registry keys/values that appear intact in an
+otherwise corrupted hive. Use at your own risk.
+
 =back";
 
   "close", (RErrDispose, [AHive]),
diff --git a/lib/handle.c b/lib/handle.c
index 3a8f09b..dff2780 100644
--- a/lib/handle.c
+++ b/lib/handle.c
@@ -83,6 +83,7 @@ hivex_open (const char *filename, int flags)
   DEBUG (2, "created handle %p", h);
 
   h->writable = !!(flags & HIVEX_OPEN_WRITE);
+  h->unsafe = !!(flags & HIVEX_OPEN_UNSAFE);
   h->filename = strdup (filename);
   if (h->filename == NULL)
     goto error;
diff --git a/lib/hivex-internal.h b/lib/hivex-internal.h
index bfd24c8..bbca215 100644
--- a/lib/hivex-internal.h
+++ b/lib/hivex-internal.h
@@ -30,6 +30,7 @@ struct hive_h {
   size_t size;
   int msglvl;                   /* 1 = verbose, 2 or 3 = debug */
   int writable;
+  int unsafe;
 
   /* Registry file, memory mapped if read-only, or malloc'd if writing. */
   union {
-- 
1.8.3.1