On Tue, Feb 14, 2017 at 12:05:20PM -0500, Dawid Zamirski wrote:
* 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 4565d7d..e183ff2 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) {
GCC 7 warns:
handle.c: In function 'hivex_open':
handle.c:236:13: error: missed loop optimization, the loop counter may overflow
[-Werror=unsafe-loop-optimizations]
while (off < h->endpages) {
^
I suspect this means that GCC might try to turn this into an infinite
loop.
There are actually a few more of these in the existing code - I'm
going to push a patch to fix these in a minute.
Rich.
+ off += 0x1000;
+ 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
_______________________________________________
Libguestfs mailing list
Libguestfs(a)redhat.com
https://www.redhat.com/mailman/listinfo/libguestfs
--
Richard Jones, Virtualization Group, Red Hat
http://people.redhat.com/~rjones
Read my programming and virtualization blog:
http://rwmj.wordpress.com
virt-p2v converts physical machines to virtual machines. Boot with a
live CD or over the network (PXE) and turn machines into KVM guests.
http://libguestfs.org/virt-v2v