From e85b1eaa268caea316f6aa8e02738b3d94297250 Mon Sep 17 00:00:00 2001 From: Alex Nelson Date: Thu, 1 Sep 2011 18:17:36 -0700 Subject: [PATCH] hivex: Add metadata length functions for nodes and values This patch adds hivex_node_struct_length and hivex_value_struct_length to the hivex ABI, to report the amount of hive space used for each stored structure. Signed-off-by: Alex Nelson A fix added by RWMJ. --- generator/generator.ml | 12 ++++++++++++ lib/hivex.c | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/generator/generator.ml b/generator/generator.ml index 6f318ac..b6fb8b3 100755 --- a/generator/generator.ml +++ b/generator/generator.ml @@ -262,6 +262,18 @@ information, and the value itself. Also, C functions below which can be used to return the value in a more useful form when you know the type in advance."; + "node_struct_length", (RSize, [AHive; ANode "node"]), + "return the length of a node", + "\ +Return the length of the node data structure. Returns 0 +and sets errno on error."; + + "value_struct_length", (RSize, [AHive; AValue "val"]), + "return the length of a value data structure", + "\ +Return the length of the value data structure. 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 a183527..3063c45 100644 --- a/lib/hivex.c +++ b/lib/hivex.c @@ -585,6 +585,30 @@ hivex_root (hive_h *h) return ret; } +size_t +hivex_node_struct_length (hive_h *h, hive_node_h node) +{ + if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) { + errno = EINVAL; + return 0; + } + + struct ntreg_nk_record *nk = (struct ntreg_nk_record *) (h->addr + node); + size_t name_len = le16toh (nk->name_len); + /* -1 to avoid double-counting the first name character */ + size_t ret = name_len + sizeof (struct ntreg_nk_record) - 1; + int used; + size_t seg_len = block_len (h, node, &used); + if (ret > seg_len) { + if (h->msglvl >= 2) + fprintf (stderr, "hivex_node_struct_length: returning EFAULT because" + " node name is too long (%zu, %zu)\n", name_len, seg_len); + errno = EFAULT; + return 0; + } + return ret; +} + char * hivex_node_name (hive_h *h, hive_node_h node) { @@ -1190,6 +1214,20 @@ hivex_node_get_value (hive_h *h, hive_node_h node, const char *key) } size_t +hivex_value_struct_length (hive_h *h, hive_value_h value) +{ + size_t key_len; + + errno = 0; + key_len = hivex_value_key_len (h, value); + if (key_len == 0 && errno != 0) + return 0; + + /* -1 to avoid double-counting the first name character */ + return key_len + sizeof (struct ntreg_vk_record) - 1; +} + +size_t hivex_value_key_len (hive_h *h, hive_value_h value) { if (!IS_VALID_BLOCK (h, value) || !BLOCK_ID_EQ (h, value, "vk")) { -- 1.8.3.1