Source

Magic Lantern / assemble_fw

Trammell Hudson 3559959 
















hud...@kremvax b7afd08 
Trammell Hudson 3559959 







hud...@kremvax b7afd08 

Trammell Hudson 3559959 















hud...@kremvax b7afd08 
Trammell Hudson 3559959 

hud...@kremvax b7afd08 





Trammell Hudson 3559959 
Trammell Hudson 4577cda 


Trammell Hudson 3559959 
Trammell Hudson 4577cda 
Trammell Hudson 3559959 
Trammell Hudson 4577cda 



Trammell Hudson 3559959 


Trammell Hudson 4577cda 

















#!/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;
my $zero_bytes;

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,
	"z|zero+"		=> \$zero_bytes,
) or die "$0: Unknown option (read the source for options)\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);
my $user_len = length($user);

# Replace the user code in the image
substr( $image, $offset, $user_len ) = $user;

# Zero the rest of the bytes if the user requests it
my $zero_len = length($image) - $user_len - $offset;
substr( $image, $offset + $user_len, $zero_len ) = chr(0) x $zero_len
	if $zero_bytes;

# 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<length $image ; $i ++ )
	{
		$sum += ord( substr( $image, $i, 1 ) );
	}

	return ~$sum;
}