|
|
33d974 |
From f80b9b31f99ccdc06887c23dab46a37fc4f4ce74 Mon Sep 17 00:00:00 2001
|
|
|
33d974 |
From: Dawid Zamirski <dzamirski@datto.com>
|
|
|
33d974 |
Date: Thu, 16 Feb 2017 18:17:23 -0500
|
|
|
33d974 |
Subject: [PATCH 09/12] lib: change how hbin sections are read.
|
|
|
33d974 |
|
|
|
33d974 |
Only when HIVEX_OPEN_UNSAFE flag is set:
|
|
|
33d974 |
|
|
|
33d974 |
* hivex_open: when looping over hbin sections (aka pages), handle a
|
|
|
33d974 |
case where following hbin section may not begin at exactly at the end
|
|
|
33d974 |
of previous one. If this happens, scan the page section until next
|
|
|
33d974 |
one is found and validate it by checking declared offset with actual
|
|
|
33d974 |
one - if they match, all is good and we can safely move on.
|
|
|
33d974 |
|
|
|
33d974 |
Rationale: there are registry hives there is some garbage data between
|
|
|
33d974 |
hbin section but the hive is still perfectly usable as long as the
|
|
|
33d974 |
offsets stated in hbin headers are correct.
|
|
|
33d974 |
|
|
|
33d974 |
(cherry picked from commit 8d092a746dbd9e61ec85cf17449c201bc0719721)
|
|
|
33d974 |
---
|
|
|
33d974 |
lib/handle.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++-----
|
|
|
33d974 |
1 file changed, 46 insertions(+), 5 deletions(-)
|
|
|
33d974 |
|
|
|
33d974 |
diff --git a/lib/handle.c b/lib/handle.c
|
|
|
33d974 |
index dff2780..8c64b6d 100644
|
|
|
33d974 |
--- a/lib/handle.c
|
|
|
33d974 |
+++ b/lib/handle.c
|
|
|
33d974 |
@@ -227,11 +227,42 @@ hivex_open (const char *filename, int flags)
|
|
|
33d974 |
page->magic[1] != 'b' ||
|
|
|
33d974 |
page->magic[2] != 'i' ||
|
|
|
33d974 |
page->magic[3] != 'n') {
|
|
|
33d974 |
- SET_ERRNO (ENOTSUP,
|
|
|
33d974 |
- "%s: trailing garbage at end of file "
|
|
|
33d974 |
- "(at 0x%zx, after %zu pages)",
|
|
|
33d974 |
- filename, off, pages);
|
|
|
33d974 |
- goto error;
|
|
|
33d974 |
+
|
|
|
33d974 |
+ if (!h->unsafe) {
|
|
|
33d974 |
+ SET_ERRNO (ENOTSUP,
|
|
|
33d974 |
+ "%s: trailing garbage at end of file "
|
|
|
33d974 |
+ "(at 0x%zx, after %zu pages)",
|
|
|
33d974 |
+ filename, off, pages);
|
|
|
33d974 |
+ goto error;
|
|
|
33d974 |
+ }
|
|
|
33d974 |
+
|
|
|
33d974 |
+ DEBUG (2,
|
|
|
33d974 |
+ "page not found at expected offset 0x%zx, "
|
|
|
33d974 |
+ "seeking until one is found or EOF is reached",
|
|
|
33d974 |
+ off);
|
|
|
33d974 |
+
|
|
|
33d974 |
+ int found = 0;
|
|
|
33d974 |
+ while (off < h->size) {
|
|
|
33d974 |
+ off += 0x1000;
|
|
|
33d974 |
+
|
|
|
33d974 |
+ if (off >= h->endpages)
|
|
|
33d974 |
+ break;
|
|
|
33d974 |
+
|
|
|
33d974 |
+ page = (struct ntreg_hbin_page *) ((char *) h->addr + off);
|
|
|
33d974 |
+ if (page->magic[0] == 'h' &&
|
|
|
33d974 |
+ page->magic[1] == 'b' &&
|
|
|
33d974 |
+ page->magic[2] == 'i' &&
|
|
|
33d974 |
+ page->magic[3] == 'n') {
|
|
|
33d974 |
+ DEBUG (2, "found next page by seeking at 0x%zx", off);
|
|
|
33d974 |
+ found = 1;
|
|
|
33d974 |
+ break;
|
|
|
33d974 |
+ }
|
|
|
33d974 |
+ }
|
|
|
33d974 |
+
|
|
|
33d974 |
+ if (!found) {
|
|
|
33d974 |
+ DEBUG (2, "page not found and end of pages section reached");
|
|
|
33d974 |
+ break;
|
|
|
33d974 |
+ }
|
|
|
33d974 |
}
|
|
|
33d974 |
|
|
|
33d974 |
size_t page_size = le32toh (page->page_size);
|
|
|
33d974 |
@@ -255,6 +286,16 @@ hivex_open (const char *filename, int flags)
|
|
|
33d974 |
goto error;
|
|
|
33d974 |
}
|
|
|
33d974 |
|
|
|
33d974 |
+ size_t page_offset = le32toh(page->offset_first) + 0x1000;
|
|
|
33d974 |
+
|
|
|
33d974 |
+ if (page_offset != off) {
|
|
|
33d974 |
+ SET_ERRNO (ENOTSUP,
|
|
|
33d974 |
+ "%s: declared page offset (0x%zx) does not match computed "
|
|
|
33d974 |
+ "offset (0x%zx), bad registry",
|
|
|
33d974 |
+ filename, page_offset, off);
|
|
|
33d974 |
+ goto error;
|
|
|
33d974 |
+ }
|
|
|
33d974 |
+
|
|
|
33d974 |
/* Read the blocks in this page. */
|
|
|
33d974 |
size_t blkoff;
|
|
|
33d974 |
struct ntreg_hbin_block *block;
|
|
|
33d974 |
--
|
|
|
33d974 |
1.8.3.1
|
|
|
33d974 |
|