Add hivex_set_value API call, and ocaml and perl bindings, and tests.
[hivex.git] / lib / tools / fillemptyhbins.ml
1 (* Windows Registry reverse-engineering tool.
2  * Copyright (C) 2010 Red Hat Inc.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  *)
18
19 open Bitstring
20 open ExtString
21 open Printf
22
23 let () =
24   if Array.length Sys.argv <> 3 then (
25     eprintf "Error: missing argument.
26 Usage: %s hivefile startoffset
27 " Sys.executable_name;
28     exit 1
29   )
30
31 let filename = Sys.argv.(1)
32 let offset = int_of_string Sys.argv.(2)
33
34 (* Load the file. *)
35 let bits = bitstring_of_file filename
36
37 (* Split into header + data at the 4KB boundary. *)
38 let header, data = takebits (4096 * 8) bits, dropbits (4096 * 8) bits
39
40 (* Overwrite everything after @offset, so ... *)
41 let nrpages = (bitstring_length data / 8 - offset) / 4096
42 let data = takebits (offset * 8) data
43
44 (* Create the empty pages.  They're not all the same because each
45  * page contains its own page_offset.
46  *)
47 let pages =
48   let noblock =
49     let seg_len = 4096 - 32 in
50     let zeroes = zeroes_bitstring ((seg_len - 4) * 8) in
51     BITSTRING {
52       Int32.of_int seg_len : 4*8 : littleendian;
53       zeroes : (seg_len - 4) * 8 : bitstring
54     } in
55   let zeroes = zeroes_bitstring (20*8) in
56   let rec loop page_offset i =
57     if i < nrpages then (
58       let page =
59         BITSTRING {
60           "hbin" : 4*8 : string;
61           Int32.of_int page_offset : 4*8 : littleendian;
62           4096_l : 4*8 : littleendian; (* page length *)
63           zeroes : 20*8 : bitstring;
64           noblock : (4096 - 32) * 8 : bitstring
65         } in
66       page :: loop (page_offset + 4096) (i+1)
67     ) else []
68   in
69   loop offset 0
70
71 (* Write it. *)
72 let () =
73   let file = concat (header :: data :: pages) in
74   bitstring_to_file file filename