Alex Nelson
2011-Dec-08 02:37 UTC
[Libguestfs] [hivex] [PATCH 3/8] hivex: Add offset-&-length function for long value data
This patch adds value_data_cell_offset to the hivex ABI, to report the hive space used for long (>4 bytes) value data. Signed-off-by: Alex Nelson <ajnelson at cs.ucsc.edu> --- generator/generator.ml | 12 +++++++++ lib/hivex.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 0 deletions(-) diff --git a/generator/generator.ml b/generator/generator.ml index 85d1863..f8d9c9b 100755 --- a/generator/generator.ml +++ b/generator/generator.ml @@ -273,6 +273,18 @@ Return the length of the node data structure."; "\ Return the length of the value data structure."; + "value_data_cell_offset", (RLenValue, [AHive; AValue "val"]), + "return the offset and length of a value data cell", + "\ +Return the offset and length of the value's data cell, not value cell. +E.g. if the value data were \"foobar\" then the cell length would be 10, +and the offset would be to a value data cell, which houses the data +prefixed with 4 bytes describing the size. If the data length is not +greater than 4, then 0 is returned as offset and length, as the data +are inline in the value. + +Returns 0 and sets errno on error."; + "value_value", (RLenTypeVal, [AHive; AValue "val"]), "return data length, data type and data of a value", "\ diff --git a/lib/hivex.c b/lib/hivex.c index bf1a860..df313bf 100644 --- a/lib/hivex.c +++ b/lib/hivex.c @@ -1257,6 +1257,66 @@ hivex_value_type (hive_h *h, hive_value_h value, hive_type *t, size_t *len) return 0; } +hive_value_h +hivex_value_data_cell_offset (hive_h *h, hive_value_h value, size_t *len) +{ + if (!IS_VALID_BLOCK (h, value) || !BLOCK_ID_EQ (h, value, "vk")) { + errno = EINVAL; + return 0; + } + + if (h->msglvl >= 2) + fprintf (stderr, "hivex_value_data_cell_offset: value=0x%zx\n", value); + struct ntreg_vk_record *vk = (struct ntreg_vk_record *) (h->addr + value); + + size_t data_len; + int is_inline; + + data_len = le32toh (vk->data_len); + is_inline = !!(data_len & 0x80000000); + data_len &= 0x7fffffff; + + if (h->msglvl >= 2) + fprintf (stderr, "hivex_value_data_cell_offset: is_inline=%d\n", is_inline); + + if (h->msglvl >= 2) + fprintf (stderr, "hivex_value_data_cell_offset: data_len=%zx\n", data_len); + + if (is_inline && data_len > 4) { + errno = ENOTSUP; + return 0; + } + + if (is_inline) { + /* There is no other location for the value data. */ + if (len) + *len = 0; + return 0; + } else { + if (len) + *len = data_len + 4; /* Include 4 header length bytes */ + } + + if (h->msglvl >= 2) + fprintf (stderr, "hivex_value_data_cell_offset: Proceeding with indirect data.\n"); + + size_t data_offset = le32toh (vk->data_offset); + data_offset += 0x1000; /* Add 0x1000 because everything's off by 4KiB */ + if (!IS_VALID_BLOCK (h, data_offset)) { + if (h->msglvl >= 2) + fprintf (stderr, "hivex_value_data_cell_offset: returning EFAULT because data " + "offset is not a valid block (0x%zx)\n", + data_offset); + errno = EFAULT; + return 0; + } + + if (h->msglvl >= 2) + fprintf (stderr, "hivex_value_data_cell_offset: data_offset=%zx\n", data_offset); + + return data_offset; +} + char * hivex_value_value (hive_h *h, hive_value_h value, hive_type *t_rtn, size_t *len_rtn) -- 1.7.6.4
Apparently Analagous Threads
- [hivex][PATCH 3/8] hivex: Add offset-&-length function for long value data
- [PATCH 5/7] hivex: Add offset-&-length function for long value data
- [PATCH] hivex: Add byte runs for nodes and values
- [PATCH 2/7] hivex: Split value_key function into value_key and value_key_len
- Re: [PATCH] Add read support for "big data" blocks to hivex