#!/usr/bin/perl # Assemble a hacked firmware image for the 5D Mark 2 from # the dumped images and the replacement user code # # (c) Trammell Hudson # use warnings; use strict; use Getopt::Long; use File::Slurp; my $user_file; my $header_file = "5d200107.0.header.bin"; my $flasher_file = "5d200107.1.flasher.bin"; my $output_file = "5d200107_dump.fir"; my $offset = 0x5ab8; my $pad_bytes = 24; GetOptions( "header=s" => \$header_file, "o|output=s" => \$output_file, "flasher=s" => \$flasher_file, "user=s" => \$user_file, "offset=o" => \$offset, "pad=o" => \$pad_bytes, ) or die "$0: Unknown option\n"; my $header = read_file( $header_file, binmode => ':raw' ) or die "$0: Unable to open $header_file: $!\n"; my $flasher = read_file( $flasher_file, binmode => ':raw' ) or die "$0: Unable to open $flasher_file: $!\n"; my $user = ''; if( $user_file ) { $user = read_file( $user_file, binmode=> ':raw' ) or die "$0: Unable to open $user_file: $!\n"; } # Generate the image by concatenating everything my $image = $header . $flasher . (chr(0) x $pad_bytes); # Replace the user code in the image substr( $image, $offset, length($user) ) = $user; # Set the offset or type from 0x20 to 0x10? Why? substr( $image, 0x28, 1 ) = chr(0x10); # Zero the CRC and recalc it my $old_crc = unpack( "V", substr( $image, 0x20, 4 ) ); substr( $image, 0x20, 4 ) = chr(0) x 4; my $crc = checksum( $image ); substr( $image, 0x20, 4 ) = pack( "V", $crc ); printf "$output_file: New CRC: %08x OLD %08x\n", $crc, $old_crc; # Write out the file write_file( $output_file, { binmode => ':raw' }, $image ); # # This is the Worst. Checksum algorithm. Ever. # # It has no security or ability to detect byte order # errors. It is literally the sum of the bytes! # sub checksum { my $image = shift; my $sum = 0; for( my $i=0 ; $i