X-Git-Url: http://git.annexia.org/?a=blobdiff_plain;f=hivex%2Fhivex.c;h=d2c450fe192e3011425114d8718168e33828fd60;hb=2abb2ba8ca2d82a40cc96583fb7dd3dea7b37c7a;hp=e1df96a5eabf7c2ba7bc64b3a430e55e40638507;hpb=38c427268f887393b5ff0346eee2129e2c334ec2;p=hivex.git diff --git a/hivex/hivex.c b/hivex/hivex.c index e1df96a..d2c450f 100644 --- a/hivex/hivex.c +++ b/hivex/hivex.c @@ -196,18 +196,25 @@ struct ntreg_nk_record { int32_t seg_len; /* length (always -ve because used) */ char id[2]; /* "nk" */ uint16_t flags; - char timestamp[12]; + char timestamp[8]; + uint32_t unknown1; uint32_t parent; /* offset of owner/parent */ uint32_t nr_subkeys; /* number of subkeys */ - uint32_t unknown1; + uint32_t nr_subkeys_volatile; uint32_t subkey_lf; /* lf record containing list of subkeys */ - uint32_t unknown2; + uint32_t subkey_lf_volatile; uint32_t nr_values; /* number of values */ uint32_t vallist; /* value-list record */ uint32_t sk; /* offset of sk-record */ uint32_t classname; /* offset of classname record */ - char unknown3[16]; - uint32_t unknown4; + uint16_t max_subkey_name_len; /* maximum length of a subkey name in bytes + if the subkey was reencoded as UTF-16LE */ + uint16_t unknown2; + uint32_t unknown3; + uint32_t max_vk_name_len; /* maximum length of any vk name in bytes + if the name was reencoded as UTF-16LE */ + uint32_t max_vk_data_len; /* maximum length of any vk data in bytes */ + uint32_t unknown6; uint16_t name_len; /* length of name */ uint16_t classname_len; /* length of classname */ char name[1]; /* name follows here */ @@ -219,7 +226,7 @@ struct ntreg_lf_record { uint16_t nr_keys; /* number of keys in this record */ struct { uint32_t offset; /* offset of nk-record for this subkey */ - char name[4]; /* first 4 characters of subkey name */ + char hash[4]; /* hash of subkey name */ } keys[1]; } __attribute__((__packed__)); @@ -247,7 +254,7 @@ struct ntreg_vk_record { */ uint32_t data_len; uint32_t data_offset; /* pointer to the data (or data if inline) */ - hive_type data_type; /* type of the data */ + uint32_t data_type; /* type of the data */ uint16_t flags; /* bit 0 set => key name ASCII, bit 0 clr => key name UTF-16. Only seen ASCII here in the wild. */ @@ -256,7 +263,7 @@ struct ntreg_vk_record { } __attribute__((__packed__)); static uint32_t -header_checksum (hive_h *h) +header_checksum (const hive_h *h) { uint32_t *daddr = (uint32_t *) h->addr; size_t i; @@ -441,7 +448,7 @@ hivex_open (const char *filename, int flags) int used; seg_len = block_len (h, blkoff, &used); if (seg_len <= 4 || (seg_len & 3) != 0) { - fprintf (stderr, "hivex: %s: block size %d at %zu, bad registry\n", + fprintf (stderr, "hivex: %s: block size %" PRIu32 " at 0x%zx, bad registry\n", filename, le32toh (block->seg_len), blkoff); errno = ENOTSUP; goto error; @@ -762,7 +769,7 @@ get_children (hive_h *h, hive_node_h node, size_t i; for (i = 0; i < nr_subkeys_in_lf; ++i) { - hive_node_h subkey = lf->keys[i].offset; + hive_node_h subkey = le32toh (lf->keys[i].offset); subkey += 0x1000; if (!IS_VALID_BLOCK (h, subkey)) { if (h->msglvl >= 2) @@ -840,7 +847,7 @@ get_children (hive_h *h, hive_node_h node, size_t j; for (j = 0; j < le16toh (lf->nr_keys); ++j) { - hive_node_h subkey = lf->keys[j].offset; + hive_node_h subkey = le32toh (lf->keys[j].offset); subkey += 0x1000; if (!IS_VALID_BLOCK (h, subkey)) { if (h->msglvl >= 2) @@ -1173,7 +1180,7 @@ hivex_value_value (hive_h *h, hive_value_h value, return ret; } - size_t data_offset = vk->data_offset; + size_t data_offset = le32toh (vk->data_offset); data_offset += 0x1000; if (!IS_VALID_BLOCK (h, data_offset)) { if (h->msglvl >= 2) @@ -1186,7 +1193,7 @@ hivex_value_value (hive_h *h, hive_value_h value, /* Check that the declared size isn't larger than the block its in. */ size_t blen = block_len (h, data_offset, NULL); - if (len > blen) { + if (len > blen - 4 /* subtract 4 for block header */) { if (h->msglvl >= 2) fprintf (stderr, "hivex_value_value: returning EFAULT because data is longer than its block (data 0x%zx, data len %zu, block len %zu)\n", data_offset, len, blen);