Rename hivex/ -> lib/
[hivex.git] / lib / tools / fillemptyhbins.ml
diff --git a/lib/tools/fillemptyhbins.ml b/lib/tools/fillemptyhbins.ml
new file mode 100644 (file)
index 0000000..14eae96
--- /dev/null
@@ -0,0 +1,74 @@
+(* Windows Registry reverse-engineering tool.
+ * Copyright (C) 2010 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *)
+
+open Bitstring
+open ExtString
+open Printf
+
+let () =
+  if Array.length Sys.argv <> 3 then (
+    eprintf "Error: missing argument.
+Usage: %s hivefile startoffset
+" Sys.executable_name;
+    exit 1
+  )
+
+let filename = Sys.argv.(1)
+let offset = int_of_string Sys.argv.(2)
+
+(* Load the file. *)
+let bits = bitstring_of_file filename
+
+(* Split into header + data at the 4KB boundary. *)
+let header, data = takebits (4096 * 8) bits, dropbits (4096 * 8) bits
+
+(* Overwrite everything after @offset, so ... *)
+let nrpages = (bitstring_length data / 8 - offset) / 4096
+let data = takebits (offset * 8) data
+
+(* Create the empty pages.  They're not all the same because each
+ * page contains its own page_offset.
+ *)
+let pages =
+  let noblock =
+    let seg_len = 4096 - 32 in
+    let zeroes = zeroes_bitstring ((seg_len - 4) * 8) in
+    BITSTRING {
+      Int32.of_int seg_len : 4*8 : littleendian;
+      zeroes : (seg_len - 4) * 8 : bitstring
+    } in
+  let zeroes = zeroes_bitstring (20*8) in
+  let rec loop page_offset i =
+    if i < nrpages then (
+      let page =
+        BITSTRING {
+          "hbin" : 4*8 : string;
+          Int32.of_int page_offset : 4*8 : littleendian;
+          4096_l : 4*8 : littleendian; (* page length *)
+          zeroes : 20*8 : bitstring;
+          noblock : (4096 - 32) * 8 : bitstring
+        } in
+      page :: loop (page_offset + 4096) (i+1)
+    ) else []
+  in
+  loop offset 0
+
+(* Write it. *)
+let () =
+  let file = concat (header :: data :: pages) in
+  bitstring_to_file file filename