X-Git-Url: http://git.annexia.org/?a=blobdiff_plain;ds=sidebyside;f=hivex%2Ftools%2Ftruncatefile.ml;fp=hivex%2Ftools%2Ftruncatefile.ml;h=b519f7a54478d1e064212abd1cf8deb7da19ff11;hb=db8a46aa1165479ddf2b551e81a7e96bb06fc942;hp=0000000000000000000000000000000000000000;hpb=6ea059d6a1bd1be605278057025d34dee675d64d;p=libguestfs.git diff --git a/hivex/tools/truncatefile.ml b/hivex/tools/truncatefile.ml new file mode 100644 index 0000000..b519f7a --- /dev/null +++ b/hivex/tools/truncatefile.ml @@ -0,0 +1,112 @@ +(* 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 <> 3 then ( + eprintf "Error: missing argument. +Usage: %s hivefile endpages +" Sys.executable_name; + exit 1 + ) + +let filename = Sys.argv.(1) +let new_end_pages = 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 + +(* Truncate the file data. *) +let data = takebits (new_end_pages * 8) data + +(* 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, with endpages updated. *) +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; + Int32.of_int new_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