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
Maybe Matching 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