[Libguestfs] [PATCH v3 1/2] lib: change how hbin sections are read.

Dawid Zamirski dzamirski at datto.com
Wed Feb 15 18:42:40 UTC 2017


* hivex_open: when looping over hbin sections (aka pages), handle a
  case where following hbin section may not begin at exactly at the end
  of previous one. If this happens, scan the page section until next
  one is found and validate it by checking declared offset with actual
  one - if they match, all is good and we can safely move on.

Rationale: there are registry hives there is some garbage data between
hbin section but the hive is still perfectly usable as long as the
offsets stated in hbin headers are correct.
---
 lib/handle.c | 39 ++++++++++++++++++++++++++++++++++-----
 1 file changed, 34 insertions(+), 5 deletions(-)

diff --git a/lib/handle.c b/lib/handle.c
index d33c1d0..42fd672 100644
--- a/lib/handle.c
+++ b/lib/handle.c
@@ -226,11 +226,30 @@ hivex_open (const char *filename, int flags)
         page->magic[1] != 'b' ||
         page->magic[2] != 'i' ||
         page->magic[3] != 'n') {
-      SET_ERRNO (ENOTSUP,
-                 "%s: trailing garbage at end of file "
-                 "(at 0x%zx, after %zu pages)",
-                 filename, off, pages);
-      goto error;
+
+      DEBUG (2,
+             "page not found at expected offset 0x%zx, "
+             "seeking until one is found or EOF is reached",
+             off);
+
+      int found = 0;
+      while (off < h->endpages) {
+        off++;
+        page = (struct ntreg_hbin_page *) ((char *) h->addr + off);
+        if (page->magic[0] == 'h' &&
+            page->magic[1] == 'b' &&
+            page->magic[2] == 'i' &&
+            page->magic[3] == 'n') {
+          DEBUG (2, "found next page by seeking at 0x%zx", off);
+          found = 1;
+          break;
+        }
+      }
+
+      if (!found) {
+        DEBUG (2, "page not found and end of pages section reached");
+        break;
+      }
     }
 
     size_t page_size = le32toh (page->page_size);
@@ -254,6 +273,16 @@ hivex_open (const char *filename, int flags)
       goto error;
     }
 
+    size_t page_offset = le32toh(page->offset_first) + 0x1000;
+
+    if (page_offset != off) {
+      SET_ERRNO (ENOTSUP,
+                 "%s: declared page offset (0x%zx) does not match computed "
+                 "offset (0x%zx), bad registry",
+                 filename, page_offset, off);
+      goto error;
+    }
+
     /* Read the blocks in this page. */
     size_t blkoff;
     struct ntreg_hbin_block *block;
-- 
2.9.3




More information about the Libguestfs mailing list