Alex Nelson
2011-Dec-08 02:38 UTC
[Libguestfs] [hivex] [PATCH 8/8] hivexml: Add byte run reporting functions
This patch adds value_byte_runs and node_byte_runs. Each byte run represents the offset and length of a data structure within the hive, one per node, and one or two per value depending on the length of the value data. These byte run functions also add additional data sanity checks as a hive is being parsed, mainly checking that a node address actually points to a node, and similarly for values. Signed-off-by: Alex Nelson <ajnelson at cs.ucsc.edu> --- xml/hivexml.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 files changed, 95 insertions(+), 9 deletions(-) diff --git a/xml/hivexml.c b/xml/hivexml.c index d38e9d4..6591c98 100644 --- a/xml/hivexml.c +++ b/xml/hivexml.c @@ -210,6 +210,34 @@ filetime_to_8601 (int64_t windows_ticks) return ret; } +#define BYTE_RUN_BUF_LEN 32 + +static int +node_byte_runs (hive_h *h, void *writer_v, hive_node_h node) +{ + xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v; + char buf[1+BYTE_RUN_BUF_LEN]; + errno = 0; + size_t node_struct_length = hivex_node_struct_length (h, node); + if (errno) { + if (errno == EINVAL) { + fprintf (stderr, "node_byte_runs: Invoked on what does not seem to be a node (%zu).\n", node); + } + return -1; + } + /* A node has one byte run. */ + XML_CHECK (xmlTextWriterStartElement, (writer, BAD_CAST "byte_runs")); + XML_CHECK (xmlTextWriterStartElement, (writer, BAD_CAST "byte_run")); + memset (buf, 0, 1+BYTE_RUN_BUF_LEN); + snprintf (buf, 1+BYTE_RUN_BUF_LEN, "%d", node); + XML_CHECK (xmlTextWriterWriteAttribute, (writer, BAD_CAST "file_offset", BAD_CAST buf)); + snprintf (buf, 1+BYTE_RUN_BUF_LEN, "%d", node_struct_length); + XML_CHECK (xmlTextWriterWriteAttribute, (writer, BAD_CAST "len", BAD_CAST buf)); + XML_CHECK (xmlTextWriterEndElement, (writer)); + XML_CHECK (xmlTextWriterEndElement, (writer)); + return 0; +} + static int node_start (hive_h *h, void *writer_v, hive_node_h node, const char *name) { @@ -236,7 +264,8 @@ node_start (hive_h *h, void *writer_v, hive_node_h node, const char *name) } } - return 0; + ret = node_byte_runs (h, writer_v, node); + return ret; } static int @@ -268,11 +297,53 @@ end_value (xmlTextWriterPtr writer) } static int +value_byte_runs (hive_h *h, void *writer_v, hive_value_h value) { + xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v; + char buf[1+BYTE_RUN_BUF_LEN]; + size_t value_data_cell_length; + errno = 0; + size_t value_data_structure_length = hivex_value_struct_length (h, value); + if (errno != 0) { + if (errno == EINVAL) { + fprintf (stderr, "value_byte_runs: Invoked on what does not seem to be a value (%zu).\n", value); + } + return -1; + } + hive_value_h value_data_cell_offset = hivex_value_data_cell_offset (h, value, &value_data_cell_length); + if (errno != 0) + return -1; + + XML_CHECK (xmlTextWriterStartElement, (writer, BAD_CAST "byte_runs")); + memset (buf, 0, 1+BYTE_RUN_BUF_LEN); + + /* Write first byte run for data structure */ + XML_CHECK (xmlTextWriterStartElement, (writer, BAD_CAST "byte_run")); + snprintf (buf, 1+BYTE_RUN_BUF_LEN, "%d", value); + XML_CHECK (xmlTextWriterWriteAttribute, (writer, BAD_CAST "file_offset", BAD_CAST buf)); + snprintf (buf, 1+BYTE_RUN_BUF_LEN, "%d", value_data_structure_length); + XML_CHECK (xmlTextWriterWriteAttribute, (writer, BAD_CAST "len", BAD_CAST buf)); + XML_CHECK (xmlTextWriterEndElement, (writer)); + + /* Write second byte run for longer values */ + if (value_data_cell_length > 4) { + XML_CHECK (xmlTextWriterStartElement, (writer, BAD_CAST "byte_run")); + snprintf (buf, 1+BYTE_RUN_BUF_LEN, "%d", value_data_cell_offset); + XML_CHECK (xmlTextWriterWriteAttribute, (writer, BAD_CAST "file_offset", BAD_CAST buf)); + snprintf (buf, 1+BYTE_RUN_BUF_LEN, "%d", value_data_cell_length); + XML_CHECK (xmlTextWriterWriteAttribute, (writer, BAD_CAST "len", BAD_CAST buf)); + XML_CHECK (xmlTextWriterEndElement, (writer)); + } + XML_CHECK (xmlTextWriterEndElement, (writer)); + return 0; +} + +static int value_string (hive_h *h, void *writer_v, hive_node_h node, hive_value_h value, hive_type t, size_t len, const char *key, const char *str) { xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v; const char *type; + int ret = 0; switch (t) { case hive_t_string: type = "string"; break; @@ -298,8 +369,9 @@ value_string (hive_h *h, void *writer_v, hive_node_h node, hive_value_h value, XML_CHECK (xmlTextWriterStartAttribute, (writer, BAD_CAST "value")); XML_CHECK (xmlTextWriterWriteString, (writer, BAD_CAST str)); XML_CHECK (xmlTextWriterEndAttribute, (writer)); + ret = value_byte_runs (h, writer_v, value); end_value (writer); - return 0; + return ret; } static int @@ -308,6 +380,7 @@ value_multiple_strings (hive_h *h, void *writer_v, hive_node_h node, const char *key, char **argv) { xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v; + int ret = 0; start_value (writer, key, "string-list", NULL); size_t i; @@ -317,8 +390,9 @@ value_multiple_strings (hive_h *h, void *writer_v, hive_node_h node, XML_CHECK (xmlTextWriterEndElement, (writer)); } + ret = value_byte_runs (h, writer_v, value); end_value (writer); - return 0; + return ret; } static int @@ -329,6 +403,7 @@ value_string_invalid_utf16 (hive_h *h, void *writer_v, hive_node_h node, { xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v; const char *type; + int ret = 0; switch (t) { case hive_t_string: type = "bad-string"; break; @@ -354,9 +429,10 @@ value_string_invalid_utf16 (hive_h *h, void *writer_v, hive_node_h node, XML_CHECK (xmlTextWriterStartAttribute, (writer, BAD_CAST "value")); XML_CHECK (xmlTextWriterWriteBase64, (writer, str, 0, len)); XML_CHECK (xmlTextWriterEndAttribute, (writer)); + ret = value_byte_runs (h, writer_v, value); end_value (writer); - return 0; + return ret; } static int @@ -364,10 +440,12 @@ value_dword (hive_h *h, void *writer_v, hive_node_h node, hive_value_h value, hive_type t, size_t len, const char *key, int32_t v) { xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v; + int ret = 0; start_value (writer, key, "int32", NULL); XML_CHECK (xmlTextWriterWriteFormatAttribute, (writer, BAD_CAST "value", "%" PRIi32, v)); + ret = value_byte_runs (h, writer_v, value); end_value (writer); - return 0; + return ret; } static int @@ -375,10 +453,12 @@ value_qword (hive_h *h, void *writer_v, hive_node_h node, hive_value_h value, hive_type t, size_t len, const char *key, int64_t v) { xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v; + int ret = 0; start_value (writer, key, "int64", NULL); XML_CHECK (xmlTextWriterWriteFormatAttribute, (writer, BAD_CAST "value", "%" PRIi64, v)); + ret = value_byte_runs (h, writer_v, value); end_value (writer); - return 0; + return ret; } static int @@ -386,12 +466,14 @@ value_binary (hive_h *h, void *writer_v, hive_node_h node, hive_value_h value, hive_type t, size_t len, const char *key, const char *v) { xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v; + int ret = 0; start_value (writer, key, "binary", "base64"); XML_CHECK (xmlTextWriterStartAttribute, (writer, BAD_CAST "value")); XML_CHECK (xmlTextWriterWriteBase64, (writer, v, 0, len)); XML_CHECK (xmlTextWriterEndAttribute, (writer)); + ret = value_byte_runs (h, writer_v, value); end_value (writer); - return 0; + return ret; } static int @@ -399,14 +481,16 @@ value_none (hive_h *h, void *writer_v, hive_node_h node, hive_value_h value, hive_type t, size_t len, const char *key, const char *v) { xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v; + int ret = 0; start_value (writer, key, "none", "base64"); if (len > 0) { XML_CHECK (xmlTextWriterStartAttribute, (writer, BAD_CAST "value")); XML_CHECK (xmlTextWriterWriteBase64, (writer, v, 0, len)); XML_CHECK (xmlTextWriterEndAttribute, (writer)); + ret = value_byte_runs (h, writer_v, value); } end_value (writer); - return 0; + return ret; } static int @@ -415,6 +499,7 @@ value_other (hive_h *h, void *writer_v, hive_node_h node, hive_value_h value, { xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v; const char *type; + int ret = 0; switch (t) { case hive_t_none: @@ -441,8 +526,9 @@ value_other (hive_h *h, void *writer_v, hive_node_h node, hive_value_h value, XML_CHECK (xmlTextWriterStartAttribute, (writer, BAD_CAST "value")); XML_CHECK (xmlTextWriterWriteBase64, (writer, v, 0, len)); XML_CHECK (xmlTextWriterEndAttribute, (writer)); + ret = value_byte_runs (h, writer_v, value); } end_value (writer); - return 0; + return ret; } -- 1.7.6.4
Richard W.M. Jones
2012-Jan-05 13:51 UTC
[Libguestfs] [hivex] [PATCH 8/8] hivexml: Add byte run reporting functions
Thanks. I have pushed patches 1-7. I made a small change to the description of the function in patch 3. However this patch (8) cannot go in because it provokes many gcc warnings. Try configuring hivex with: ./configure --enable-gcc-warnings and recompile hivexml (possibly you'll only see warnings on a 64 bit machine). One example of several: On Wed, Dec 07, 2011 at 06:38:15PM -0800, Alex Nelson wrote:> + snprintf (buf, 1+BYTE_RUN_BUF_LEN, "%d", node);You can't do this sort of thing because node is a size_t, not an int. Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones virt-df lists disk usage of guests without needing to install any software inside the virtual machine. Supports Linux and Windows. http://et.redhat.com/~rjones/virt-df/
Reasonably Related Threads
- [PATCH v6] hivexml: Add byte run reporting functions
- [PATCH] hivex: Add byte runs for nodes and values
- [PATCH 6/7] hivexml: Report attributes in values instead of text.
- [hivex] [PATCH 1/1] hivexml: Change value type output to standard names
- [PATCH 1/1] hivexml: Base64-encode non-printable data