+++ /dev/null
-(* 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
-open Visualizer_utils
-
-let () =
- if Array.length Sys.argv <> 2 then (
- eprintf "Error: missing argument.
-Usage: %s hivefile
-" Sys.executable_name;
- exit 1
- )
-
-let filename = Sys.argv.(1)
-
-(* 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
-
-(* Read the header fields. *)
-let seq, last_modified, major, minor, unknown1, unknown2,
- root_key, end_pages, unknown3, fname =
- bitmatch header with
- | { "regf" : 4*8 : string;
- seq1 : 4*8 : littleendian;
- seq2 : 4*8 : littleendian;
- last_modified : 64 : bitstring;
- major : 4*8 : littleendian;
- minor : 4*8 : littleendian;
- unknown1 : 4*8 : littleendian;
- unknown2 : 4*8 : littleendian;
- root_key : 4*8 : littleendian;
- end_pages : 4*8 : littleendian;
- unknown3 : 4*8 : littleendian;
- fname : 64*8 : string;
- unknownguid1 : 16*8 : bitstring;
- unknownguid2 : 16*8 : bitstring;
- unknown4 : 4*8 : littleendian;
- unknownguid3 : 16*8 : bitstring;
- unknown5 : 4*8 : string;
- unknown6 : 340*8 : bitstring;
- csum : 4*8
- : littleendian, save_offset_to (crc_offset),
- check (assert (crc_offset = 0x1fc * 8); true);
- unknown7 : (0x1000-0x200)*8 : bitstring } ->
- seq1, last_modified, major, minor, unknown1, unknown2,
- root_key, end_pages, unknown3, fname
- | {_} -> assert false
-
-(* Create a new header, but with unknown fields cleared. Do it in
- * two parts, first creating everything up to the checksum, then
- * calculating the checksum and appending checksum and the final
- * field.
- *)
-let header =
- let zeroguid = zeroes_bitstring (16*8) in
- let before_csum =
- BITSTRING {
- "regf" : 4*8 : string;
- seq : 4*8 : littleendian;
- seq : 4*8 : littleendian;
- last_modified : 64 : bitstring;
- major : 4*8 : littleendian;
- minor : 4*8 : littleendian;
- unknown1 : 4*8 : littleendian;
- unknown2 : 4*8 : littleendian;
- root_key : 4*8 : littleendian;
- end_pages : 4*8 : littleendian;
- unknown3 : 4*8 : littleendian;
- fname : 64*8 : string;
- zeroguid : 16*8 : bitstring;
- zeroguid : 16*8 : bitstring;
- 0_l : 4*8 : littleendian;
- zeroguid : 16*8 : bitstring;
- 0_l : 4*8 : littleendian;
- zeroes_bitstring (340*8) : 340*8 : bitstring
- } in
- assert (bitstring_length before_csum = 0x1fc * 8);
- let csum = bitstring_fold_left_int32_le Int32.logxor 0_l before_csum in
- let csum_and_after =
- BITSTRING {
- csum : 4*8 : littleendian;
- zeroes_bitstring ((0x1000-0x200)*8) : (0x1000-0x200)*8 : bitstring
- } in
- let new_header = concat [before_csum; csum_and_after] in
- assert (bitstring_length header = bitstring_length new_header);
- new_header
-
-(* Write it. *)
-let () =
- let file = concat [header; data] in
- bitstring_to_file file filename