Hilko Bengen
2013-Nov-22 13:08 UTC
[Libguestfs] [PATCH 1/3] Document ntreg_nk_record.flags
--- lib/hivex-internal.h | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/hivex-internal.h b/lib/hivex-internal.h index f391b98..d7ce339 100644 --- a/lib/hivex-internal.h +++ b/lib/hivex-internal.h @@ -125,7 +125,19 @@ struct ntreg_hbin_block { struct ntreg_nk_record { int32_t seg_len; /* length (always -ve because used) */ char id[2]; /* "nk" */ - uint16_t flags; + uint16_t flags; /* bit 1: HiveExit + bit 2: HiveEntry == root key + bit 3: NoDelete + bit 4: SymbolicLink + bit 5: CompressedName: Name is encoded + in ASCII (actually: Latin-1) + rather than UTF-16. + bit 6: PredefinedHandle + bit 7: VirtMirrored + bit 8: VirtTarget + bit 9: VirtualStore */ + /* Information from: Peter Norris: The Internal Structure of the + Windows Registry, 2008, p.220 ff. */ int64_t timestamp; uint32_t unknown1; uint32_t parent; /* offset of owner/parent */ -- 1.8.4.3
Hilko Bengen
2013-Nov-22 13:08 UTC
[Libguestfs] [PATCH 2/3] Handle UTF-16-LE-encoded key/value names
--- lib/node.c | 23 +++++++++++------------ lib/value.c | 18 +++++++++++------- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/lib/node.c b/lib/node.c index 5090dbe..fda4592 100644 --- a/lib/node.c +++ b/lib/node.c @@ -79,11 +79,6 @@ hivex_node_name (hive_h *h, hive_node_h node) struct ntreg_nk_record *nk (struct ntreg_nk_record *) ((char *) h->addr + node); - /* AFAIK the node name is always plain ASCII, so no conversion - * to UTF-8 is necessary. However we do need to nul-terminate - * the string. - */ - /* nk->name_len is unsigned, 16 bit, so this is safe ... However * we have to make sure the length doesn't exceed the block length. */ @@ -93,13 +88,17 @@ hivex_node_name (hive_h *h, hive_node_h node) SET_ERRNO (EFAULT, "node name is too long (%zu, %zu)", len, seg_len); return NULL; } - - char *ret = malloc (len + 1); - if (ret == NULL) - return NULL; - memcpy (ret, nk->name, len); - ret[len] = '\0'; - return ret; + size_t flags = le16toh (nk->flags); + if (flags & 0x20) { + char *ret = malloc (len + 1); + if (ret == NULL) + return NULL; + memcpy (ret, nk->name, len); + ret[len] = '\0'; + return ret; + } else { + return _hivex_windows_utf16_to_utf8 (nk->name, len); + } } static int64_t diff --git a/lib/value.c b/lib/value.c index 6d0f266..66cde48 100644 --- a/lib/value.c +++ b/lib/value.c @@ -213,13 +213,17 @@ hivex_value_key (hive_h *h, hive_value_h value) size_t len = hivex_value_key_len (h, value); if (len == 0 && errno != 0) return NULL; - - char *ret = malloc (len + 1); - if (ret == NULL) - return NULL; - memcpy (ret, vk->name, len); - ret[len] = '\0'; - return ret; + size_t flags = le16toh (vk->flags); + if (flags & 0x01) { + char *ret = malloc (len + 1); + if (ret == NULL) + return NULL; + memcpy (ret, vk->name, len); + ret[len] = '\0'; + return ret; + } else { + return _hivex_windows_utf16_to_utf8 (vk->name, len); + } } int -- 1.8.4.3
Hilko Bengen
2013-Nov-22 13:08 UTC
[Libguestfs] [PATCH 3/3] Correctly handle latin1-encoded key/value names
--- lib/hivex-internal.h | 6 +++++- lib/node.c | 7 +------ lib/utf16.c | 5 ++--- lib/value.c | 7 +------ 4 files changed, 9 insertions(+), 16 deletions(-) diff --git a/lib/hivex-internal.h b/lib/hivex-internal.h index d7ce339..4135f58 100644 --- a/lib/hivex-internal.h +++ b/lib/hivex-internal.h @@ -268,7 +268,11 @@ extern size_t * _hivex_return_offset_list (offset_list *list); extern void _hivex_print_offset_list (offset_list *list, FILE *fp); /* utf16.c */ -extern char *_hivex_windows_utf16_to_utf8 (/* const */ char *input, size_t len); +extern char* _hivex_to_utf8 (/* const */ char *input, size_t len, char* input_encoding); +#define _hivex_windows_utf16_to_utf8(_input, _len) \ + _hivex_to_utf8 (_input, _len, "UTF-16LE") +#define _hivex_windows_latin1_to_utf8(_input, _len) \ + _hivex_to_utf8 (_input, _len, "LATIN1") extern size_t _hivex_utf16_string_len_in_bytes_max (const char *str, size_t len); /* util.c */ diff --git a/lib/node.c b/lib/node.c index fda4592..fcd7442 100644 --- a/lib/node.c +++ b/lib/node.c @@ -90,12 +90,7 @@ hivex_node_name (hive_h *h, hive_node_h node) } size_t flags = le16toh (nk->flags); if (flags & 0x20) { - char *ret = malloc (len + 1); - if (ret == NULL) - return NULL; - memcpy (ret, nk->name, len); - ret[len] = '\0'; - return ret; + return _hivex_windows_latin1_to_utf8 (nk->name, len); } else { return _hivex_windows_utf16_to_utf8 (nk->name, len); } diff --git a/lib/utf16.c b/lib/utf16.c index 844715c..eca2343 100644 --- a/lib/utf16.c +++ b/lib/utf16.c @@ -29,15 +29,14 @@ #include "hivex-internal.h" char * -_hivex_windows_utf16_to_utf8 (/* const */ char *input, size_t len) +_hivex_to_utf8 (/* const */ char *input, size_t len, char* input_encoding) { - iconv_t ic = iconv_open ("UTF-8", "UTF-16LE"); + iconv_t ic = iconv_open ("UTF-8", input_encoding); if (ic == (iconv_t) -1) return NULL; /* iconv(3) has an insane interface ... */ - /* Mostly UTF-8 will be smaller, so this is a good initial guess. */ size_t outalloc = len; again:; diff --git a/lib/value.c b/lib/value.c index 66cde48..3460a8c 100644 --- a/lib/value.c +++ b/lib/value.c @@ -215,12 +215,7 @@ hivex_value_key (hive_h *h, hive_value_h value) return NULL; size_t flags = le16toh (vk->flags); if (flags & 0x01) { - char *ret = malloc (len + 1); - if (ret == NULL) - return NULL; - memcpy (ret, vk->name, len); - ret[len] = '\0'; - return ret; + return _hivex_windows_latin1_to_utf8 (vk->name, len); } else { return _hivex_windows_utf16_to_utf8 (vk->name, len); } -- 1.8.4.3
Richard W.M. Jones
2013-Nov-22 15:59 UTC
Re: [Libguestfs] [PATCH 1/3] Document ntreg_nk_record.flags
On Fri, Nov 22, 2013 at 02:08:33PM +0100, Hilko Bengen wrote:> --- > lib/hivex-internal.h | 14 +++++++++++++- > 1 file changed, 13 insertions(+), 1 deletion(-) > > diff --git a/lib/hivex-internal.h b/lib/hivex-internal.h > index f391b98..d7ce339 100644 > --- a/lib/hivex-internal.h > +++ b/lib/hivex-internal.h > @@ -125,7 +125,19 @@ struct ntreg_hbin_block { > struct ntreg_nk_record { > int32_t seg_len; /* length (always -ve because used) */ > char id[2]; /* "nk" */ > - uint16_t flags; > + uint16_t flags; /* bit 1: HiveExit > + bit 2: HiveEntry == root key > + bit 3: NoDelete > + bit 4: SymbolicLink > + bit 5: CompressedName: Name is encoded > + in ASCII (actually: Latin-1) > + rather than UTF-16. > + bit 6: PredefinedHandle > + bit 7: VirtMirrored > + bit 8: VirtTarget > + bit 9: VirtualStore */ > + /* Information from: Peter Norris: The Internal Structure of the > + Windows Registry, 2008, p.220 ff. */ > int64_t timestamp; > uint32_t unknown1; > uint32_t parent; /* offset of owner/parent */ > -- > 1.8.4.3Simple and obvious documentation fix, so ACK. Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones virt-top is 'top' for virtual machines. Tiny program with many powerful monitoring features, net stats, disk stats, logging, etc. http://people.redhat.com/~rjones/virt-top
Richard W.M. Jones
2013-Nov-22 16:10 UTC
Re: [Libguestfs] [PATCH 3/3] Correctly handle latin1-encoded key/value names
I tested 2 & 3 against the hivex-test-data repository and indeed your patches found (and fixed) some registry encoding issues: http://git.annexia.org/?p=hivex-test-data.git;a=commitdiff_plain;h=d1b6c9d294287642d035f3a7fb20081865962086 Thanks, I have pushed all three patches to hivex. Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones 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
Reasonably Related Threads
- [PATCH 1/3] lib: Further generalize iconv wrapper function.
- [PATCH 2/2] lib: utf16: Fix const-correctness issues in _hivex_recode function.
- Re: [PATCH] Add a cache for iconv_t handles to hive_t
- [PATCH 1/3] Document ntreg_nk_record.flags
- [PATCH] Add a cache for iconv_t handles to hive_t