hivex: Send all debug messages to stderr.
[libguestfs.git] / hivex / hivex.c
1 /* hivex - Windows Registry "hive" extraction library.
2  * Copyright (C) 2009 Red Hat Inc.
3  * Derived from code by Petter Nordahl-Hagen under a compatible license:
4  *   Copyright (c) 1997-2007 Petter Nordahl-Hagen.
5  * Derived from code by Markus Stephany under a compatible license:
6  *   Copyright (c) 2000-2004, Markus Stephany.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation;
11  * version 2.1 of the License.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * See file LICENSE for the full license.
19  */
20
21 #include <config.h>
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <stdint.h>
26 #include <string.h>
27 #include <fcntl.h>
28 #include <unistd.h>
29 #include <errno.h>
30 #include <iconv.h>
31 #include <sys/mman.h>
32 #include <sys/stat.h>
33 #ifdef HAVE_ENDIAN_H
34 #include <endian.h>
35 #endif
36 #ifdef HAVE_BYTESWAP_H
37 #include <byteswap.h>
38 #endif
39
40 #define STREQ(a,b) (strcmp((a),(b)) == 0)
41 #define STRCASEEQ(a,b) (strcasecmp((a),(b)) == 0)
42 //#define STRNEQ(a,b) (strcmp((a),(b)) != 0)
43 //#define STRCASENEQ(a,b) (strcasecmp((a),(b)) != 0)
44 #define STREQLEN(a,b,n) (strncmp((a),(b),(n)) == 0)
45 //#define STRCASEEQLEN(a,b,n) (strncasecmp((a),(b),(n)) == 0)
46 //#define STRNEQLEN(a,b,n) (strncmp((a),(b),(n)) != 0)
47 //#define STRCASENEQLEN(a,b,n) (strncasecmp((a),(b),(n)) != 0)
48 //#define STRPREFIX(a,b) (strncmp((a),(b),strlen((b))) == 0)
49
50 #if __BYTE_ORDER == __LITTLE_ENDIAN
51 #ifndef be32toh
52 #define be32toh(x) __bswap_32 (x)
53 #endif
54 #ifndef be64toh
55 #define be64toh(x) __bswap_64 (x)
56 #endif
57 #ifndef le16toh
58 #define le16toh(x) (x)
59 #endif
60 #ifndef le32toh
61 #define le32toh(x) (x)
62 #endif
63 #ifndef le64toh
64 #define le64toh(x) (x)
65 #endif
66 #else
67 #ifndef be32toh
68 #define be32toh(x) (x)
69 #endif
70 #ifndef be64toh
71 #define be64toh(x) (x)
72 #endif
73 #ifndef le16toh
74 #define le16toh(x) __bswap_16 (x)
75 #endif
76 #ifndef le32toh
77 #define le32toh(x) __bswap_32 (x)
78 #endif
79 #ifndef le64toh
80 #define le64toh(x) __bswap_64 (x)
81 #endif
82 #endif
83
84 #include "hivex.h"
85
86 struct hive_h {
87   int fd;
88   size_t size;
89   int msglvl;
90
91   /* Memory-mapped (readonly) registry file. */
92   union {
93     char *addr;
94     struct ntreg_header *hdr;
95   };
96
97   /* Use a bitmap to store which file offsets are valid (point to a
98    * used block).  We only need to store 1 bit per 32 bits of the file
99    * (because blocks are 4-byte aligned).  We found that the average
100    * block size in a registry file is ~50 bytes.  So roughly 1 in 12
101    * bits in the bitmap will be set, making it likely a more efficient
102    * structure than a hash table.
103    */
104   char *bitmap;
105 #define BITMAP_SET(bitmap,off) (bitmap[(off)>>5] |= 1 << (((off)>>2)&7))
106 #define BITMAP_CLR(bitmap,off) (bitmap[(off)>>5] &= ~ (1 << (((off)>>2)&7)))
107 #define BITMAP_TST(bitmap,off) (bitmap[(off)>>5] & (1 << (((off)>>2)&7)))
108 #define IS_VALID_BLOCK(h,off)               \
109   (((off) & 3) == 0 &&                      \
110    (off) >= 0x1000 &&                       \
111    (off) < (h)->size &&                     \
112    BITMAP_TST((h)->bitmap,(off)))
113
114   /* Fields from the header, extracted from little-endianness. */
115   size_t rootoffs;              /* Root key offset (always an nk-block). */
116
117   /* Stats. */
118   size_t pages;                 /* Number of hbin pages read. */
119   size_t blocks;                /* Total number of blocks found. */
120   size_t used_blocks;           /* Total number of used blocks found. */
121   size_t used_size;             /* Total size (bytes) of used blocks. */
122 };
123
124 /* NB. All fields are little endian. */
125 struct ntreg_header {
126   char magic[4];                /* "regf" */
127   uint32_t unknown1;
128   uint32_t unknown2;
129   char last_modified[8];
130   uint32_t unknown3;            /* 1 */
131   uint32_t unknown4;            /* 3 */
132   uint32_t unknown5;            /* 0 */
133   uint32_t unknown6;            /* 1 */
134   uint32_t offset;              /* offset of root key record - 4KB */
135   uint32_t blocks;              /* size in bytes of data (filesize - 4KB) */
136   uint32_t unknown7;            /* 1 */
137   char name[0x1fc-0x2c];
138   uint32_t csum;                /* checksum: sum of 32 bit words 0-0x1fb. */
139 } __attribute__((__packed__));
140
141 struct ntreg_hbin_page {
142   char magic[4];                /* "hbin" */
143   uint32_t offset_first;        /* offset from 1st block */
144   uint32_t offset_next;         /* offset of next (relative to this) */
145   char unknown[20];
146   /* Linked list of blocks follows here. */
147 } __attribute__((__packed__));
148
149 struct ntreg_hbin_block {
150   int32_t seg_len;              /* length of this block (-ve for used block) */
151   char id[2];                   /* the block type (eg. "nk" for nk record) */
152   /* Block data follows here. */
153 } __attribute__((__packed__));
154
155 #define BLOCK_ID_EQ(h,offs,eqid) \
156   (STREQLEN (((struct ntreg_hbin_block *)((h)->addr + (offs)))->id, (eqid), 2))
157
158 static size_t
159 block_len (hive_h *h, size_t blkoff, int *used)
160 {
161   struct ntreg_hbin_block *block;
162   block = (struct ntreg_hbin_block *) (h->addr + blkoff);
163
164   int32_t len = le32toh (block->seg_len);
165   if (len < 0) {
166     if (used) *used = 1;
167     len = -len;
168   } else {
169     if (used) *used = 0;
170   }
171
172   return (size_t) len;
173 }
174
175 struct ntreg_nk_record {
176   int32_t seg_len;              /* length (always -ve because used) */
177   char id[2];                   /* "nk" */
178   uint16_t flags;
179   char timestamp[12];
180   uint32_t parent;              /* offset of owner/parent */
181   uint32_t nr_subkeys;          /* number of subkeys */
182   uint32_t unknown1;
183   uint32_t subkey_lf;           /* lf record containing list of subkeys */
184   uint32_t unknown2;
185   uint32_t nr_values;           /* number of values */
186   uint32_t vallist;             /* value-list record */
187   uint32_t sk;                  /* offset of sk-record */
188   uint32_t classname;           /* offset of classname record */
189   char unknown3[16];
190   uint32_t unknown4;
191   uint16_t name_len;            /* length of name */
192   uint16_t classname_len;       /* length of classname */
193   char name[1];                 /* name follows here */
194 } __attribute__((__packed__));
195
196 struct ntreg_lf_record {
197   int32_t seg_len;
198   char id[2];                   /* "lf" */
199   uint16_t nr_keys;             /* number of keys in this record */
200   struct {
201     uint32_t offset;            /* offset of nk-record for this subkey */
202     char name[4];               /* first 4 characters of subkey name */
203   } keys[1];
204 } __attribute__((__packed__));
205
206 struct ntreg_ri_record {
207   int32_t seg_len;
208   char id[2];                   /* "ri" */
209   uint16_t nr_offsets;          /* number of pointers to lh records */
210   uint32_t offset[1];           /* list of pointers to lh records */
211 } __attribute__((__packed__));
212
213 /* This has no ID header. */
214 struct ntreg_value_list {
215   int32_t seg_len;
216   uint32_t offset[1];           /* list of pointers to vk records */
217 } __attribute__((__packed__));
218
219 struct ntreg_vk_record {
220   int32_t seg_len;              /* length (always -ve because used) */
221   char id[2];                   /* "vk" */
222   uint16_t name_len;            /* length of name */
223   /* length of the data:
224    * If data_len is <= 4, then it's stored inline.
225    * If data_len is 0x80000000, then it's an inline dword.
226    * Top bit may be set or not set at random.
227    */
228   uint32_t data_len;
229   uint32_t data_offset;         /* pointer to the data (or data if inline) */
230   hive_type data_type;          /* type of the data */
231   uint16_t unknown1;            /* possibly always 1 */
232   uint16_t unknown2;
233   char name[1];                 /* key name follows here */
234 } __attribute__((__packed__));
235
236 hive_h *
237 hivex_open (const char *filename, int flags)
238 {
239   hive_h *h = NULL;
240
241   h = calloc (1, sizeof *h);
242   if (h == NULL)
243     goto error;
244
245   h->msglvl = flags & HIVEX_OPEN_MSGLVL_MASK;
246
247   const char *debug = getenv ("HIVEX_DEBUG");
248   if (debug && STREQ (debug, "1"))
249     h->msglvl = 2;
250
251   if (h->msglvl >= 2)
252     fprintf (stderr, "hivex_open: created handle %p\n", h);
253
254   h->fd = open (filename, O_RDONLY);
255   if (h->fd == -1)
256     goto error;
257
258   struct stat statbuf;
259   if (fstat (h->fd, &statbuf) == -1)
260     goto error;
261
262   h->size = statbuf.st_size;
263
264   h->addr = mmap (NULL, h->size, PROT_READ, MAP_SHARED, h->fd, 0);
265   if (h->addr == MAP_FAILED)
266     goto error;
267
268   if (h->msglvl >= 2)
269     fprintf (stderr, "hivex_open: mapped file at %p\n", h->addr);
270
271   /* Check header. */
272   if (h->hdr->magic[0] != 'r' ||
273       h->hdr->magic[1] != 'e' ||
274       h->hdr->magic[2] != 'g' ||
275       h->hdr->magic[3] != 'f') {
276     fprintf (stderr, "hivex: %s: not a Windows NT Registry hive file\n",
277              filename);
278     errno = ENOTSUP;
279     goto error;
280   }
281
282   h->bitmap = calloc (1 + h->size / 32, 1);
283   if (h->bitmap == NULL)
284     goto error;
285
286 #if 0                           /* Doesn't work. */
287   /* Header checksum. */
288   uint32_t *daddr = h->addr;
289   size_t i;
290   uint32_t sum = 0;
291   for (i = 0; i < 0x1fc / 4; ++i) {
292     sum += le32toh (*daddr);
293     daddr++;
294   }
295   if (sum != le32toh (h->hdr->csum)) {
296     fprintf (stderr, "hivex: %s: bad checksum in hive header\n", filename);
297     errno = EINVAL;
298     goto error;
299   }
300 #endif
301
302   h->rootoffs = le32toh (h->hdr->offset) + 0x1000;
303
304   if (h->msglvl >= 2)
305     fprintf (stderr, "hivex_open: root offset = %zu\n", h->rootoffs);
306
307   /* We'll set this flag when we see a block with the root offset (ie.
308    * the root block).
309    */
310   int seen_root_block = 0, bad_root_block = 0;
311
312   /* Read the pages and blocks.  The aim here is to be robust against
313    * corrupt or malicious registries.  So we make sure the loops
314    * always make forward progress.  We add the address of each block
315    * we read to a hash table so pointers will only reference the start
316    * of valid blocks.
317    */
318   size_t off;
319   struct ntreg_hbin_page *page;
320   for (off = 0x1000; off < h->size; off += le32toh (page->offset_next)) {
321     h->pages++;
322
323     page = (struct ntreg_hbin_page *) (h->addr + off);
324     if (page->magic[0] != 'h' ||
325         page->magic[1] != 'b' ||
326         page->magic[2] != 'i' ||
327         page->magic[3] != 'n') {
328       /* NB: This error is seemingly common in uncorrupt registry files. */
329       if (h->msglvl >= 2)
330         fprintf (stderr, "hivex: %s: ignoring trailing garbage at end of file (at %zu, after %zu pages)\n",
331                  filename, off, h->pages);
332       break;
333     }
334
335     if (h->msglvl >= 2)
336       fprintf (stderr, "hivex_open: page at %zu\n", off);
337
338     if (le32toh (page->offset_next) <= sizeof (struct ntreg_hbin_page) ||
339         (le32toh (page->offset_next) & 3) != 0) {
340       fprintf (stderr, "hivex: %s: pagesize %d at %zu, bad registry\n",
341                filename, le32toh (page->offset_next), off);
342       errno = ENOTSUP;
343       goto error;
344     }
345
346     /* Read the blocks in this page. */
347     size_t blkoff;
348     struct ntreg_hbin_block *block;
349     int32_t seg_len;
350     for (blkoff = off + 0x20;
351          blkoff < off + le32toh (page->offset_next);
352          blkoff += seg_len) {
353       h->blocks++;
354
355       int is_root = blkoff == h->rootoffs;
356       if (is_root)
357         seen_root_block = 1;
358
359       block = (struct ntreg_hbin_block *) (h->addr + blkoff);
360       int used;
361       seg_len = block_len (h, blkoff, &used);
362       if (seg_len <= 4 || (seg_len & 3) != 0) {
363         fprintf (stderr, "hivex: %s: block size %d at %zu, bad registry\n",
364                  filename, le32toh (block->seg_len), blkoff);
365         errno = ENOTSUP;
366         goto error;
367       }
368
369       if (h->msglvl >= 2)
370         fprintf (stderr, "hivex_open: %s block id %d,%d at %zu%s\n",
371                  used ? "used" : "free", block->id[0], block->id[1], blkoff,
372                  is_root ? " (root)" : "");
373
374       if (is_root && !used)
375         bad_root_block = 1;
376
377       if (used) {
378         h->used_blocks++;
379         h->used_size += seg_len;
380
381         /* Root block must be an nk-block. */
382         if (is_root && (block->id[0] != 'n' || block->id[1] != 'k'))
383           bad_root_block = 1;
384
385         /* Note this blkoff is a valid address. */
386         BITMAP_SET (h->bitmap, blkoff);
387       }
388     }
389   }
390
391   if (!seen_root_block) {
392     fprintf (stderr, "hivex: %s: no root block found\n", filename);
393     errno = ENOTSUP;
394     goto error;
395   }
396
397   if (bad_root_block) {
398     fprintf (stderr, "hivex: %s: bad root block (free or not nk)\n", filename);
399     errno = ENOTSUP;
400     goto error;
401   }
402
403   if (h->msglvl >= 1)
404     fprintf (stderr,
405              "hivex_open: successfully read Windows Registry hive file:\n"
406              "  pages:                  %zu\n"
407              "  blocks:                 %zu\n"
408              "  blocks used:            %zu\n"
409              "  bytes used:             %zu\n",
410              h->pages, h->blocks, h->used_blocks, h->used_size);
411
412   return h;
413
414  error:;
415   int err = errno;
416   if (h) {
417     free (h->bitmap);
418     if (h->addr && h->size && h->addr != MAP_FAILED)
419       munmap (h->addr, h->size);
420     if (h->fd >= 0)
421       close (h->fd);
422     free (h);
423   }
424   errno = err;
425   return NULL;
426 }
427
428 int
429 hivex_close (hive_h *h)
430 {
431   int r;
432
433   free (h->bitmap);
434   munmap (h->addr, h->size);
435   r = close (h->fd);
436   free (h);
437
438   return r;
439 }
440
441 hive_node_h
442 hivex_root (hive_h *h)
443 {
444   hive_node_h ret = h->rootoffs;
445   if (!IS_VALID_BLOCK (h, ret)) {
446     errno = ENOKEY;
447     return 0;
448   }
449   return ret;
450 }
451
452 char *
453 hivex_node_name (hive_h *h, hive_node_h node)
454 {
455   if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) {
456     errno = EINVAL;
457     return NULL;
458   }
459
460   struct ntreg_nk_record *nk = (struct ntreg_nk_record *) (h->addr + node);
461
462   /* AFAIK the node name is always plain ASCII, so no conversion
463    * to UTF-8 is necessary.  However we do need to nul-terminate
464    * the string.
465    */
466
467   /* nk->name_len is unsigned, 16 bit, so this is safe ...  However
468    * we have to make sure the length doesn't exceed the block length.
469    */
470   size_t len = le16toh (nk->name_len);
471   size_t seg_len = block_len (h, node, NULL);
472   if (sizeof (struct ntreg_nk_record) + len - 1 > seg_len) {
473     if (h->msglvl >= 2)
474       fprintf (stderr, "hivex_node_name: returning EFAULT because node name is too long (%zu, %zu)\n",
475               len, seg_len);
476     errno = EFAULT;
477     return NULL;
478   }
479
480   char *ret = malloc (len + 1);
481   if (ret == NULL)
482     return NULL;
483   memcpy (ret, nk->name, len);
484   ret[len] = '\0';
485   return ret;
486 }
487
488 #if 0
489 /* I think the documentation for the sk and classname fields in the nk
490  * record is wrong, or else the offset field is in the wrong place.
491  * Otherwise this makes no sense.  Disabled this for now -- it's not
492  * useful for reading the registry anyway.
493  */
494
495 hive_security_h
496 hivex_node_security (hive_h *h, hive_node_h node)
497 {
498   if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) {
499     errno = EINVAL;
500     return 0;
501   }
502
503   struct ntreg_nk_record *nk = (struct ntreg_nk_record *) (h->addr + node);
504
505   hive_node_h ret = le32toh (nk->sk);
506   ret += 0x1000;
507   if (!IS_VALID_BLOCK (h, ret)) {
508     errno = EFAULT;
509     return 0;
510   }
511   return ret;
512 }
513
514 hive_classname_h
515 hivex_node_classname (hive_h *h, hive_node_h node)
516 {
517   if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) {
518     errno = EINVAL;
519     return 0;
520   }
521
522   struct ntreg_nk_record *nk = (struct ntreg_nk_record *) (h->addr + node);
523
524   hive_node_h ret = le32toh (nk->classname);
525   ret += 0x1000;
526   if (!IS_VALID_BLOCK (h, ret)) {
527     errno = EFAULT;
528     return 0;
529   }
530   return ret;
531 }
532 #endif
533
534 hive_node_h *
535 hivex_node_children (hive_h *h, hive_node_h node)
536 {
537   if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) {
538     errno = EINVAL;
539     return NULL;
540   }
541
542   struct ntreg_nk_record *nk = (struct ntreg_nk_record *) (h->addr + node);
543
544   size_t nr_subkeys_in_nk = le32toh (nk->nr_subkeys);
545
546   /* Deal with the common "no subkeys" case quickly. */
547   hive_node_h *ret;
548   if (nr_subkeys_in_nk == 0) {
549     ret = malloc (sizeof (hive_node_h));
550     if (ret == NULL)
551       return NULL;
552     ret[0] = 0;
553     return ret;
554   }
555
556   /* Arbitrarily limit the number of subkeys we will ever deal with. */
557   if (nr_subkeys_in_nk > 1000000) {
558     errno = ERANGE;
559     return NULL;
560   }
561
562   /* The subkey_lf field can point either to an lf-record, which is
563    * the common case, or if there are lots of subkeys, to an
564    * ri-record.
565    */
566   size_t subkey_lf = le32toh (nk->subkey_lf);
567   subkey_lf += 0x1000;
568   if (!IS_VALID_BLOCK (h, subkey_lf)) {
569     if (h->msglvl >= 2)
570       fprintf (stderr, "hivex_node_children: returning EFAULT because subkey_lf is not a valid block (%zu)\n",
571                subkey_lf);
572     errno = EFAULT;
573     return NULL;
574   }
575
576   struct ntreg_hbin_block *block =
577     (struct ntreg_hbin_block *) (h->addr + subkey_lf);
578
579   /* Points to lf-record?  (Note, also "lh" but that is basically the
580    * same as "lf" as far as we are concerned here).
581    */
582   if (block->id[0] == 'l' && (block->id[1] == 'f' || block->id[1] == 'h')) {
583     struct ntreg_lf_record *lf = (struct ntreg_lf_record *) block;
584
585     /* Check number of subkeys in the nk-record matches number of subkeys
586      * in the lf-record.
587      */
588     size_t nr_subkeys_in_lf = le16toh (lf->nr_keys);
589
590     if (h->msglvl >= 2)
591       fprintf (stderr, "hivex_node_children: nr_subkeys_in_nk = %zu, nr_subkeys_in_lf = %zu\n",
592                nr_subkeys_in_nk, nr_subkeys_in_lf);
593
594     if (nr_subkeys_in_nk != nr_subkeys_in_lf) {
595       errno = ENOTSUP;
596       return NULL;
597     }
598
599     size_t len = block_len (h, subkey_lf, NULL);
600     if (8 + nr_subkeys_in_lf * 8 > len) {
601       if (h->msglvl >= 2)
602         fprintf (stderr, "hivex_node_children: returning EFAULT because too many subkeys (%zu, %zu)\n",
603                  nr_subkeys_in_lf, len);
604       errno = EFAULT;
605       return NULL;
606     }
607
608     /* Allocate space for the returned values.  Note that
609      * nr_subkeys_in_lf is limited to a 16 bit value.
610      */
611     ret = malloc ((1 + nr_subkeys_in_lf) * sizeof (hive_node_h));
612     if (ret == NULL)
613       return NULL;
614
615     size_t i;
616     for (i = 0; i < nr_subkeys_in_lf; ++i) {
617       hive_node_h subkey = lf->keys[i].offset;
618       subkey += 0x1000;
619       if (!IS_VALID_BLOCK (h, subkey)) {
620         if (h->msglvl >= 2)
621           fprintf (stderr, "hivex_node_children: returning EFAULT because subkey is not a valid block (%zu)\n",
622                    subkey);
623         errno = EFAULT;
624         free (ret);
625         return NULL;
626       }
627       ret[i] = subkey;
628     }
629     ret[i] = 0;
630     return ret;
631   }
632   /* Points to ri-record? */
633   else if (block->id[0] == 'r' && block->id[1] == 'i') {
634     struct ntreg_ri_record *ri = (struct ntreg_ri_record *) block;
635
636     size_t nr_offsets = le16toh (ri->nr_offsets);
637
638     /* Count total number of children. */
639     size_t i, count = 0;
640     for (i = 0; i < nr_offsets; ++i) {
641       hive_node_h offset = ri->offset[i];
642       offset += 0x1000;
643       if (!IS_VALID_BLOCK (h, offset)) {
644         if (h->msglvl >= 2)
645           fprintf (stderr, "hivex_node_children: returning EFAULT because ri-offset is not a valid block (%zu)\n",
646                    offset);
647         errno = EFAULT;
648         return NULL;
649       }
650       if (!BLOCK_ID_EQ (h, offset, "lf") && !BLOCK_ID_EQ (h, offset, "lh")) {
651         errno = ENOTSUP;
652         return NULL;
653       }
654
655       struct ntreg_lf_record *lf =
656         (struct ntreg_lf_record *) (h->addr + offset);
657
658       count += le16toh (lf->nr_keys);
659     }
660
661     if (h->msglvl >= 2)
662       fprintf (stderr, "hivex_node_children: nr_subkeys_in_nk = %zu, counted = %zu\n",
663                nr_subkeys_in_nk, count);
664
665     if (nr_subkeys_in_nk != count) {
666       errno = ENOTSUP;
667       return NULL;
668     }
669
670     /* Copy list of children.  Note nr_subkeys_in_nk is limited to
671      * something reasonable above.
672      */
673     ret = malloc ((1 + nr_subkeys_in_nk) * sizeof (hive_node_h));
674     if (ret == NULL)
675       return NULL;
676
677     count = 0;
678     for (i = 0; i < nr_offsets; ++i) {
679       hive_node_h offset = ri->offset[i];
680       offset += 0x1000;
681       if (!IS_VALID_BLOCK (h, offset)) {
682         if (h->msglvl >= 2)
683           fprintf (stderr, "hivex_node_children: returning EFAULT because ri-offset is not a valid block (%zu)\n",
684                    offset);
685         errno = EFAULT;
686         return NULL;
687       }
688       if (!BLOCK_ID_EQ (h, offset, "lf") && !BLOCK_ID_EQ (h, offset, "lh")) {
689         errno = ENOTSUP;
690         return NULL;
691       }
692
693       struct ntreg_lf_record *lf =
694         (struct ntreg_lf_record *) (h->addr + offset);
695
696       size_t j;
697       for (j = 0; j < le16toh (lf->nr_keys); ++j) {
698         hive_node_h subkey = lf->keys[j].offset;
699         subkey += 0x1000;
700         if (!IS_VALID_BLOCK (h, subkey)) {
701           if (h->msglvl >= 2)
702             fprintf (stderr, "hivex_node_children: returning EFAULT because indirect subkey is not a valid block (%zu)\n",
703                      subkey);
704           errno = EFAULT;
705           free (ret);
706           return NULL;
707         }
708         ret[count++] = subkey;
709       }
710     }
711     ret[count] = 0;
712
713     return ret;
714   }
715   else {
716     errno = ENOTSUP;
717     return NULL;
718   }
719 }
720
721 /* Very inefficient, but at least having a separate API call
722  * allows us to make it more efficient in future.
723  */
724 hive_node_h
725 hivex_node_get_child (hive_h *h, hive_node_h node, const char *nname)
726 {
727   hive_node_h *children = NULL;
728   char *name = NULL;
729   hive_node_h ret = 0;
730
731   children = hivex_node_children (h, node);
732   if (!children) goto error;
733
734   size_t i;
735   for (i = 0; children[i] != 0; ++i) {
736     name = hivex_node_name (h, children[i]);
737     if (!name) goto error;
738     if (STRCASEEQ (name, nname)) {
739       ret = children[i];
740       break;
741     }
742     free (name); name = NULL;
743   }
744
745  error:
746   free (children);
747   free (name);
748   return ret;
749 }
750
751 hive_node_h
752 hivex_node_parent (hive_h *h, hive_node_h node)
753 {
754   if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) {
755     errno = EINVAL;
756     return 0;
757   }
758
759   struct ntreg_nk_record *nk = (struct ntreg_nk_record *) (h->addr + node);
760
761   hive_node_h ret = le32toh (nk->parent);
762   ret += 0x1000;
763   if (!IS_VALID_BLOCK (h, ret)) {
764     if (h->msglvl >= 2)
765       fprintf (stderr, "hivex_node_parent: returning EFAULT because parent is not a valid block (%zu)\n",
766               ret);
767     errno = EFAULT;
768     return 0;
769   }
770   return ret;
771 }
772
773 hive_value_h *
774 hivex_node_values (hive_h *h, hive_node_h node)
775 {
776   if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) {
777     errno = EINVAL;
778     return 0;
779   }
780
781   struct ntreg_nk_record *nk = (struct ntreg_nk_record *) (h->addr + node);
782
783   size_t nr_values = le32toh (nk->nr_values);
784
785   if (h->msglvl >= 2)
786     fprintf (stderr, "hivex_node_values: nr_values = %zu\n", nr_values);
787
788   /* Deal with the common "no values" case quickly. */
789   hive_node_h *ret;
790   if (nr_values == 0) {
791     ret = malloc (sizeof (hive_node_h));
792     if (ret == NULL)
793       return NULL;
794     ret[0] = 0;
795     return ret;
796   }
797
798   /* Arbitrarily limit the number of values we will ever deal with. */
799   if (nr_values > 100000) {
800     errno = ERANGE;
801     return NULL;
802   }
803
804   /* Get the value list and check it looks reasonable. */
805   size_t vlist_offset = le32toh (nk->vallist);
806   vlist_offset += 0x1000;
807   if (!IS_VALID_BLOCK (h, vlist_offset)) {
808     if (h->msglvl >= 2)
809       fprintf (stderr, "hivex_node_values: returning EFAULT because value list is not a valid block (%zu)\n",
810                vlist_offset);
811     errno = EFAULT;
812     return NULL;
813   }
814
815   struct ntreg_value_list *vlist =
816     (struct ntreg_value_list *) (h->addr + vlist_offset);
817
818   size_t len = block_len (h, vlist_offset, NULL);
819   if (4 + nr_values * 4 > len) {
820     if (h->msglvl >= 2)
821       fprintf (stderr, "hivex_node_values: returning EFAULT because value list is too long (%zu, %zu)\n",
822                nr_values, len);
823     errno = EFAULT;
824     return NULL;
825   }
826
827   /* Allocate return array and copy values in. */
828   ret = malloc ((1 + nr_values) * sizeof (hive_node_h));
829   if (ret == NULL)
830     return NULL;
831
832   size_t i;
833   for (i = 0; i < nr_values; ++i) {
834     hive_node_h value = vlist->offset[i];
835     value += 0x1000;
836     if (!IS_VALID_BLOCK (h, value)) {
837       if (h->msglvl >= 2)
838         fprintf (stderr, "hivex_node_values: returning EFAULT because value is not a valid block (%zu)\n",
839                  value);
840       errno = EFAULT;
841       free (ret);
842       return NULL;
843     }
844     ret[i] = value;
845   }
846
847   ret[i] = 0;
848   return ret;
849 }
850
851 /* Very inefficient, but at least having a separate API call
852  * allows us to make it more efficient in future.
853  */
854 hive_value_h
855 hivex_node_get_value (hive_h *h, hive_node_h node, const char *key)
856 {
857   hive_value_h *values = NULL;
858   char *name = NULL;
859   hive_value_h ret = 0;
860
861   values = hivex_node_values (h, node);
862   if (!values) goto error;
863
864   size_t i;
865   for (i = 0; values[i] != 0; ++i) {
866     name = hivex_value_key (h, values[i]);
867     if (!name) goto error;
868     if (STRCASEEQ (name, key)) {
869       ret = values[i];
870       break;
871     }
872     free (name); name = NULL;
873   }
874
875  error:
876   free (values);
877   free (name);
878   return ret;
879 }
880
881 char *
882 hivex_value_key (hive_h *h, hive_value_h value)
883 {
884   if (!IS_VALID_BLOCK (h, value) || !BLOCK_ID_EQ (h, value, "vk")) {
885     errno = EINVAL;
886     return 0;
887   }
888
889   struct ntreg_vk_record *vk = (struct ntreg_vk_record *) (h->addr + value);
890
891   /* AFAIK the key is always plain ASCII, so no conversion to UTF-8 is
892    * necessary.  However we do need to nul-terminate the string.
893    */
894
895   /* vk->name_len is unsigned, 16 bit, so this is safe ...  However
896    * we have to make sure the length doesn't exceed the block length.
897    */
898   size_t len = le16toh (vk->name_len);
899   size_t seg_len = block_len (h, value, NULL);
900   if (sizeof (struct ntreg_vk_record) + len - 1 > seg_len) {
901     if (h->msglvl >= 2)
902       fprintf (stderr, "hivex_value_key: returning EFAULT because key length is too long (%zu, %zu)\n",
903                len, seg_len);
904     errno = EFAULT;
905     return NULL;
906   }
907
908   char *ret = malloc (len + 1);
909   if (ret == NULL)
910     return NULL;
911   memcpy (ret, vk->name, len);
912   ret[len] = '\0';
913   return ret;
914 }
915
916 int
917 hivex_value_type (hive_h *h, hive_value_h value, hive_type *t, size_t *len)
918 {
919   if (!IS_VALID_BLOCK (h, value) || !BLOCK_ID_EQ (h, value, "vk")) {
920     errno = EINVAL;
921     return -1;
922   }
923
924   struct ntreg_vk_record *vk = (struct ntreg_vk_record *) (h->addr + value);
925
926   if (t)
927     *t = le32toh (vk->data_type);
928
929   if (len) {
930     *len = le32toh (vk->data_len);
931     if (*len == 0x80000000) {   /* special case */
932       *len = 4;
933       if (t) *t = hive_t_dword;
934     }
935     *len &= 0x7fffffff;
936   }
937
938   return 0;
939 }
940
941 char *
942 hivex_value_value (hive_h *h, hive_value_h value,
943                    hive_type *t_rtn, size_t *len_rtn)
944 {
945   if (!IS_VALID_BLOCK (h, value) || !BLOCK_ID_EQ (h, value, "vk")) {
946     errno = EINVAL;
947     return NULL;
948   }
949
950   struct ntreg_vk_record *vk = (struct ntreg_vk_record *) (h->addr + value);
951
952   hive_type t;
953   size_t len;
954
955   t = le32toh (vk->data_type);
956
957   len = le32toh (vk->data_len);
958   if (len == 0x80000000) {      /* special case */
959     len = 4;
960     t = hive_t_dword;
961   }
962   len &= 0x7fffffff;
963
964   if (h->msglvl >= 2)
965     fprintf (stderr, "hivex_value_value: value=%zu, t=%d, len=%zu\n",
966              value, t, len);
967
968   if (t_rtn)
969     *t_rtn = t;
970   if (len_rtn)
971     *len_rtn = len;
972
973   /* Arbitrarily limit the length that we will read. */
974   if (len > 1000000) {
975     errno = ERANGE;
976     return NULL;
977   }
978
979   char *ret = malloc (len);
980   if (ret == NULL)
981     return NULL;
982
983   /* If length is <= 4 it's always stored inline. */
984   if (len <= 4) {
985     memcpy (ret, (char *) &vk->data_offset, len);
986     return ret;
987   }
988
989   size_t data_offset = vk->data_offset;
990   data_offset += 0x1000;
991   if (!IS_VALID_BLOCK (h, data_offset)) {
992     if (h->msglvl >= 2)
993       fprintf (stderr, "hivex_value_value: returning EFAULT because data offset is not a valid block (%zu)\n",
994                data_offset);
995     errno = EFAULT;
996     free (ret);
997     return NULL;
998   }
999
1000   /* Check that the declared size isn't larger than the block its in. */
1001   size_t blen = block_len (h, data_offset, NULL);
1002   if (blen < len) {
1003     if (h->msglvl >= 2)
1004       fprintf (stderr, "hivex_value_value: returning EFAULT because data is longer than its block (%zu, %zu)\n",
1005                blen, len);
1006     errno = EFAULT;
1007     free (ret);
1008     return NULL;
1009   }
1010
1011   char *data = h->addr + data_offset + 4;
1012   memcpy (ret, data, len);
1013   return ret;
1014 }
1015
1016 static char *
1017 windows_utf16_to_utf8 (/* const */ char *input, size_t len)
1018 {
1019   iconv_t ic = iconv_open ("UTF-8", "UTF-16");
1020   if (ic == (iconv_t) -1)
1021     return NULL;
1022
1023   /* iconv(3) has an insane interface ... */
1024
1025   /* Mostly UTF-8 will be smaller, so this is a good initial guess. */
1026   size_t outalloc = len;
1027
1028  again:;
1029   size_t inlen = len;
1030   size_t outlen = outalloc;
1031   char *out = malloc (outlen + 1);
1032   if (out == NULL) {
1033     int err = errno;
1034     iconv_close (ic);
1035     errno = err;
1036     return NULL;
1037   }
1038   char *inp = input;
1039   char *outp = out;
1040
1041   size_t r = iconv (ic, &inp, &inlen, &outp, &outlen);
1042   if (r == (size_t) -1) {
1043     if (errno == E2BIG) {
1044       size_t prev = outalloc;
1045       /* Try again with a larger output buffer. */
1046       free (out);
1047       outalloc *= 2;
1048       if (outalloc < prev)
1049         return NULL;
1050       goto again;
1051     }
1052     else {
1053       /* Else some conversion failure, eg. EILSEQ, EINVAL. */
1054       int err = errno;
1055       iconv_close (ic);
1056       free (out);
1057       errno = err;
1058       return NULL;
1059     }
1060   }
1061
1062   *outp = '\0';
1063   iconv_close (ic);
1064
1065   return out;
1066 }
1067
1068 char *
1069 hivex_value_string (hive_h *h, hive_value_h value)
1070 {
1071   hive_type t;
1072   size_t len;
1073   char *data = hivex_value_value (h, value, &t, &len);
1074
1075   if (data == NULL)
1076     return NULL;
1077
1078   if (t != hive_t_string && t != hive_t_expand_string && t != hive_t_link) {
1079     free (data);
1080     errno = EINVAL;
1081     return NULL;
1082   }
1083
1084   char *ret = windows_utf16_to_utf8 (data, len);
1085   free (data);
1086   if (ret == NULL)
1087     return NULL;
1088
1089   return ret;
1090 }
1091
1092 static void
1093 free_strings (char **argv)
1094 {
1095   if (argv) {
1096     size_t i;
1097
1098     for (i = 0; argv[i] != NULL; ++i)
1099       free (argv[i]);
1100     free (argv);
1101   }
1102 }
1103
1104 /* Get the length of a UTF-16 format string.  Handle the string as
1105  * pairs of bytes, looking for the first \0\0 pair.
1106  */
1107 static size_t
1108 utf16_string_len_in_bytes (const char *str)
1109 {
1110   size_t ret = 0;
1111
1112   while (str[0] || str[1]) {
1113     str += 2;
1114     ret += 2;
1115   }
1116
1117   return ret;
1118 }
1119
1120 /* http://blogs.msdn.com/oldnewthing/archive/2009/10/08/9904646.aspx */
1121 char **
1122 hivex_value_multiple_strings (hive_h *h, hive_value_h value)
1123 {
1124   hive_type t;
1125   size_t len;
1126   char *data = hivex_value_value (h, value, &t, &len);
1127
1128   if (data == NULL)
1129     return NULL;
1130
1131   if (t != hive_t_multiple_strings) {
1132     free (data);
1133     errno = EINVAL;
1134     return NULL;
1135   }
1136
1137   size_t nr_strings = 0;
1138   char **ret = malloc ((1 + nr_strings) * sizeof (char *));
1139   if (ret == NULL) {
1140     free (data);
1141     return NULL;
1142   }
1143   ret[0] = NULL;
1144
1145   char *p = data;
1146   size_t plen;
1147
1148   while (p < data + len && (plen = utf16_string_len_in_bytes (p)) > 0) {
1149     nr_strings++;
1150     char **ret2 = realloc (ret, (1 + nr_strings) * sizeof (char *));
1151     if (ret2 == NULL) {
1152       free_strings (ret);
1153       free (data);
1154       return NULL;
1155     }
1156     ret = ret2;
1157
1158     ret[nr_strings-1] = windows_utf16_to_utf8 (p, plen);
1159     ret[nr_strings] = NULL;
1160     if (ret[nr_strings-1] == NULL) {
1161       free_strings (ret);
1162       free (data);
1163       return NULL;
1164     }
1165
1166     p += plen + 2 /* skip over UTF-16 \0\0 at the end of this string */;
1167   }
1168
1169   free (data);
1170   return ret;
1171 }
1172
1173 int32_t
1174 hivex_value_dword (hive_h *h, hive_value_h value)
1175 {
1176   hive_type t;
1177   size_t len;
1178   char *data = hivex_value_value (h, value, &t, &len);
1179
1180   if (data == NULL)
1181     return -1;
1182
1183   if ((t != hive_t_dword && t != hive_t_dword_be) || len != 4) {
1184     free (data);
1185     errno = EINVAL;
1186     return -1;
1187   }
1188
1189   int32_t ret = *(int32_t*)data;
1190   free (data);
1191   if (t == hive_t_dword)        /* little endian */
1192     ret = le32toh (ret);
1193   else
1194     ret = be32toh (ret);
1195
1196   return ret;
1197 }
1198
1199 int64_t
1200 hivex_value_qword (hive_h *h, hive_value_h value)
1201 {
1202   hive_type t;
1203   size_t len;
1204   char *data = hivex_value_value (h, value, &t, &len);
1205
1206   if (data == NULL)
1207     return -1;
1208
1209   if (t != hive_t_qword || len != 8) {
1210     free (data);
1211     errno = EINVAL;
1212     return -1;
1213   }
1214
1215   int64_t ret = *(int64_t*)data;
1216   free (data);
1217   ret = le64toh (ret);          /* always little endian */
1218
1219   return ret;
1220 }
1221
1222 int
1223 hivex_visit (hive_h *h, const struct hivex_visitor *visitor, size_t len,
1224              void *opaque, int flags)
1225 {
1226   return hivex_visit_node (h, hivex_root (h), visitor, len, opaque, flags);
1227 }
1228
1229 static int hivex__visit_node (hive_h *h, hive_node_h node, const struct hivex_visitor *vtor, char *unvisited, void *opaque, int flags);
1230
1231 int
1232 hivex_visit_node (hive_h *h, hive_node_h node,
1233                   const struct hivex_visitor *visitor, size_t len, void *opaque,
1234                   int flags)
1235 {
1236   struct hivex_visitor vtor;
1237   memset (&vtor, 0, sizeof vtor);
1238
1239   /* Note that len might be larger *or smaller* than the expected size. */
1240   size_t copysize = len <= sizeof vtor ? len : sizeof vtor;
1241   memcpy (&vtor, visitor, copysize);
1242
1243   /* This bitmap records unvisited nodes, so we don't loop if the
1244    * registry contains cycles.
1245    */
1246   char *unvisited = malloc (1 + h->size / 32);
1247   if (unvisited == NULL)
1248     return -1;
1249   memcpy (unvisited, h->bitmap, 1 + h->size / 32);
1250
1251   int r = hivex__visit_node (h, node, &vtor, unvisited, opaque, flags);
1252   free (unvisited);
1253   return r;
1254 }
1255
1256 static int
1257 hivex__visit_node (hive_h *h, hive_node_h node,
1258                    const struct hivex_visitor *vtor, char *unvisited,
1259                    void *opaque, int flags)
1260 {
1261   int skip_bad = flags & HIVEX_VISIT_SKIP_BAD;
1262   char *name = NULL;
1263   hive_value_h *values = NULL;
1264   hive_node_h *children = NULL;
1265   char *key = NULL;
1266   char *str = NULL;
1267   char **strs = NULL;
1268   int i;
1269
1270   /* Return -1 on all callback errors.  However on internal errors,
1271    * check if skip_bad is set and suppress those errors if so.
1272    */
1273   int ret = -1;
1274
1275   if (!BITMAP_TST (unvisited, node)) {
1276     if (h->msglvl >= 2)
1277       fprintf (stderr, "hivex__visit_node: contains cycle: visited node %zu already\n",
1278                node);
1279
1280     errno = ELOOP;
1281     return skip_bad ? 0 : -1;
1282   }
1283   BITMAP_CLR (unvisited, node);
1284
1285   name = hivex_node_name (h, node);
1286   if (!name) return skip_bad ? 0 : -1;
1287   if (vtor->node_start && vtor->node_start (h, opaque, node, name) == -1)
1288     goto error;
1289
1290   values = hivex_node_values (h, node);
1291   if (!values) {
1292     ret = skip_bad ? 0 : -1;
1293     goto error;
1294   }
1295
1296   for (i = 0; values[i] != 0; ++i) {
1297     hive_type t;
1298     size_t len;
1299
1300     if (hivex_value_type (h, values[i], &t, &len) == -1) {
1301       ret = skip_bad ? 0 : -1;
1302       goto error;
1303     }
1304
1305     key = hivex_value_key (h, values[i]);
1306     if (key == NULL) {
1307       ret = skip_bad ? 0 : -1;
1308       goto error;
1309     }
1310
1311     switch (t) {
1312     case hive_t_none:
1313       str = hivex_value_value (h, values[i], &t, &len);
1314       if (str == NULL) {
1315         ret = skip_bad ? 0 : -1;
1316         goto error;
1317       }
1318       if (t != hive_t_none) {
1319         ret = skip_bad ? 0 : -1;
1320         goto error;
1321       }
1322       if (vtor->value_none &&
1323           vtor->value_none (h, opaque, node, values[i], t, len, key, str) == -1)
1324         goto error;
1325       free (str); str = NULL;
1326       break;
1327
1328     case hive_t_string:
1329     case hive_t_expand_string:
1330     case hive_t_link:
1331       str = hivex_value_string (h, values[i]);
1332       if (str == NULL) {
1333         if (errno != EILSEQ && errno != EINVAL) {
1334           ret = skip_bad ? 0 : -1;
1335           goto error;
1336         }
1337         if (vtor->value_string_invalid_utf16) {
1338           str = hivex_value_value (h, values[i], &t, &len);
1339           if (vtor->value_string_invalid_utf16 (h, opaque, node, values[i], t, len, key, str) == -1)
1340             goto error;
1341           free (str); str = NULL;
1342         }
1343         break;
1344       }
1345       if (vtor->value_string &&
1346           vtor->value_string (h, opaque, node, values[i], t, len, key, str) == -1)
1347         goto error;
1348       free (str); str = NULL;
1349       break;
1350
1351     case hive_t_dword:
1352     case hive_t_dword_be: {
1353       int32_t i32 = hivex_value_dword (h, values[i]);
1354       if (vtor->value_dword &&
1355           vtor->value_dword (h, opaque, node, values[i], t, len, key, i32) == -1)
1356         goto error;
1357       break;
1358     }
1359
1360     case hive_t_qword: {
1361       int64_t i64 = hivex_value_qword (h, values[i]);
1362       if (vtor->value_qword &&
1363           vtor->value_qword (h, opaque, node, values[i], t, len, key, i64) == -1)
1364         goto error;
1365       break;
1366     }
1367
1368     case hive_t_binary:
1369       str = hivex_value_value (h, values[i], &t, &len);
1370       if (str == NULL) {
1371         ret = skip_bad ? 0 : -1;
1372         goto error;
1373       }
1374       if (t != hive_t_binary) {
1375         ret = skip_bad ? 0 : -1;
1376         goto error;
1377       }
1378       if (vtor->value_binary &&
1379           vtor->value_binary (h, opaque, node, values[i], t, len, key, str) == -1)
1380         goto error;
1381       free (str); str = NULL;
1382       break;
1383
1384     case hive_t_multiple_strings:
1385       strs = hivex_value_multiple_strings (h, values[i]);
1386       if (strs == NULL) {
1387         if (errno != EILSEQ && errno != EINVAL) {
1388           ret = skip_bad ? 0 : -1;
1389           goto error;
1390         }
1391         if (vtor->value_string_invalid_utf16) {
1392           str = hivex_value_value (h, values[i], &t, &len);
1393           if (vtor->value_string_invalid_utf16 (h, opaque, node, values[i], t, len, key, str) == -1)
1394             goto error;
1395           free (str); str = NULL;
1396         }
1397         break;
1398       }
1399       if (vtor->value_multiple_strings &&
1400           vtor->value_multiple_strings (h, opaque, node, values[i], t, len, key, strs) == -1)
1401         goto error;
1402       free_strings (strs); strs = NULL;
1403       break;
1404
1405     case hive_t_resource_list:
1406     case hive_t_full_resource_description:
1407     case hive_t_resource_requirements_list:
1408     default:
1409       str = hivex_value_value (h, values[i], &t, &len);
1410       if (str == NULL) {
1411         ret = skip_bad ? 0 : -1;
1412         goto error;
1413       }
1414       if (vtor->value_other &&
1415           vtor->value_other (h, opaque, node, values[i], t, len, key, str) == -1)
1416         goto error;
1417       free (str); str = NULL;
1418       break;
1419     }
1420
1421     free (key); key = NULL;
1422   }
1423
1424   children = hivex_node_children (h, node);
1425   if (children == NULL) {
1426     ret = skip_bad ? 0 : -1;
1427     goto error;
1428   }
1429
1430   for (i = 0; children[i] != 0; ++i) {
1431     if (h->msglvl >= 2)
1432       fprintf (stderr, "hivex__visit_node: %s: visiting subkey %d (%zu)\n",
1433                name, i, children[i]);
1434
1435     if (hivex__visit_node (h, children[i], vtor, unvisited, opaque, flags) == -1)
1436       goto error;
1437   }
1438
1439   if (vtor->node_end && vtor->node_end (h, opaque, node, name) == -1)
1440     goto error;
1441
1442   ret = 0;
1443
1444  error:
1445   free (name);
1446   free (values);
1447   free (children);
1448   free (key);
1449   free (str);
1450   free_strings (strs);
1451   return ret;
1452 }