https://bitbucket.org/daniel_fort/magic-lantern
Raw File
Tip revision: baaa387219c58b6ae2e2c457a8a9287121184b12 authored by Daniel Fort on 06 March 2018, 23:00:38 UTC
Closed branch compressed_raw_7D
Tip revision: baaa387
fir_tool2.py
# fir_tool.py 
# Copyright (C) 2010 Arm.Indy arm.indiana at google mail
"""
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.
"""
import os
import sys
import array
from struct import unpack
import ctypes
from binascii import hexlify, unhexlify
from optparse import OptionParser

version_id = "0.5 (20Mar2010)"

# updater decoding tables. since 1d Mark III (2/2007) 
# See 20 dec 2007 (soldeersmurfje), 40D firmware decryption, http://tech.groups.yahoo.com/group/canondigicamhacking/message/7883

t512 = [0x07, 0x9E, 0xD5, 0x5E, 0x19, 0xB5, 0xE6, 0x2B, 0x17, 0xA5, 0xC1, 0xA2, 0xBD, 0x59, 0x38, 0x68, 
  0xEC, 0xFE, 0x2D, 0x8C, 0x14, 0x99, 0xE6, 0xB9, 0x54, 0xAD, 0x85, 0x84, 0x40, 0x48, 0xCE, 0x78,   
  0xA4, 0xA0, 0xA7, 0x4B, 0xEC, 0x59, 0xCD, 0x93, 0xD8, 0x8C, 0xA7, 0x33, 0xB0, 0xA1, 0x78, 0x66, 
  0x0A, 0x8C, 0xB6, 0x26, 0x80, 0xDB, 0x49, 0xC1, 0x54, 0xD9, 0x88, 0x0C, 0xA2, 0x8A, 0xF1, 0x68, 
  0x2A, 0xBC, 0x12, 0x93, 0x23, 0x74, 0x11, 0x4C, 0x66, 0x67, 0x93, 0x81, 0x12, 0x6B, 0x04, 0x52,
  0x79, 0xEC, 0x90, 0xD4, 0xF7, 0x1E, 0xB9, 0x6B, 0xEB, 0x6C, 0xF9, 0x86, 0x58, 0x97, 0xDA, 0xF0, 
  0x7D, 0x3D, 0xC4, 0xEA, 0x8F, 0x48, 0x75, 0x21, 0x62, 0xC7, 0x5F, 0xFB, 0x93, 0xF9, 0xC3, 0x91, 
  0x83, 0xF6, 0x64, 0x46, 0xA9, 0x14, 0x64, 0xCB, 0xF2, 0x4C, 0xAB, 0x8F, 0xE9, 0xAE, 0xC9, 0xE8, 
  0xC3, 0x5D, 0xC0, 0x07, 0xD4, 0xD2, 0xD5, 0xEC, 0x7E, 0x89, 0x3E, 0x65, 0x66, 0xDA, 0x2A, 0xB1, 
  0xB7, 0xD0, 0x47, 0x0A, 0x3A, 0x93, 0x52, 0x49, 0x5F, 0xAB, 0xD7, 0x21, 0x79, 0xF0, 0xF7, 0xAF,
  0x90, 0x60, 0x52, 0x88, 0x80, 0x7F, 0x31, 0xBA, 0xF3, 0x2D, 0x04, 0xA2, 0xE8, 0x66, 0xB5, 0x68, 
  0x6D, 0x15, 0x58, 0x94, 0x1C, 0xC4, 0x16, 0x68, 0xF3, 0xE2, 0x20, 0x68, 0x89, 0x3E, 0x08, 0xD8, 
  0x43, 0xA2, 0xD0, 0x27, 0x55, 0x58, 0x51, 0xF6, 0x8B, 0x49, 0x14, 0xF6, 0xE9, 0xBD, 0x37, 0xFB, 
  0x80, 0xBA, 0x99, 0xAD, 0x4C, 0x55, 0xC1, 0xDD, 0x89, 0xDE, 0xF8, 0x2D, 0x72, 0x2C, 0xB9, 0x37, 
  0x84, 0x45, 0x34, 0x9D, 0xBE, 0x83, 0x42, 0x9A, 0x2D, 0xD7, 0x78, 0xE5, 0x0F, 0xAC, 0xA7, 0xCC,
  0xC3, 0x35, 0xDC, 0x56, 0x7F, 0xBD, 0xC4, 0xBF, 0xA1, 0x41, 0x44, 0x5F, 0xAD, 0x45, 0x68, 0x65, 
  0x7F, 0x10, 0x73, 0x4B, 0x89, 0x72, 0x2F, 0xDA, 0xD0, 0xC3, 0x3F, 0x26, 0xD9, 0x5E, 0x94, 0x61, 
  0xF8, 0x21, 0x19, 0xD5, 0xF9, 0x1B, 0x18, 0xF5, 0xDD, 0x26, 0x79, 0xF4, 0xF2, 0x44, 0x77, 0x44, 
  0xCD, 0x83, 0x44, 0x12, 0xCE, 0x37, 0xB9, 0x25, 0xDE, 0x0F, 0x12, 0x2A, 0x5D, 0xD6, 0x7D, 0x1F, 
  0x39, 0x10, 0x4F, 0x7F, 0xB9, 0x75, 0x1C, 0xAB, 0x8B, 0x43, 0xEB, 0x3D, 0xC1, 0x8C, 0xCB, 0x2B,
  0x1E, 0x45, 0x7D, 0x31, 0x1A, 0xC9, 0x8B, 0xDB, 0x65, 0xD0, 0x75, 0x50, 0xEB, 0xB3, 0x65, 0xFB, 
  0x05, 0xCE, 0xC0, 0xCF, 0x58, 0x24, 0xFB, 0x1C, 0x94, 0x4B, 0x6A, 0x15, 0xEF, 0x32, 0xB3, 0x9B, 
  0x63, 0x91, 0xC2, 0x61, 0xE6, 0x66, 0x0A, 0xCA, 0xA8, 0xE5, 0x5B, 0x98, 0x95, 0x52, 0xAA, 0x9F, 
  0xC5, 0xB0, 0x9D, 0x3A, 0x98, 0x43, 0x2D, 0x7D, 0x14, 0x74, 0x34, 0x6B, 0xB1, 0x11, 0x19, 0x64, 
  0x07, 0x7D, 0x11, 0x0B, 0x13, 0x77, 0xE4, 0x46, 0x86, 0xEF, 0x2B, 0x7F, 0x5E, 0x05, 0xF1, 0xB4,
  0x12, 0xC3, 0xAB, 0x34, 0xCA, 0x64, 0x62, 0x76, 0xA1, 0xDF, 0x37, 0x8F, 0xBF, 0xFA, 0xB3, 0x5C, 
  0xE4, 0x59, 0x84, 0x22, 0xD1, 0x26, 0x8B, 0x5F, 0x8D, 0x44, 0x92, 0xD5, 0xDD, 0x61, 0x0F, 0xF2, 
  0xA1, 0xC9, 0x02, 0x9C, 0x6F, 0xAC, 0x4A, 0x36, 0x99, 0x19, 0xDF, 0xF3, 0x20, 0xBF, 0xD9, 0x02, 
  0xAE, 0x08, 0xF7, 0xC0, 0x6D, 0xA8, 0x24, 0x93, 0x94, 0xD4, 0x40, 0xF9, 0x67, 0xE2, 0x5C, 0x3B, 
  0x37, 0xDF, 0xC8, 0xDB, 0x70, 0x18, 0xC5, 0xA2, 0x55, 0x5A, 0x04, 0xB6, 0x40, 0x63, 0xDE, 0xF6,
  0x4C, 0x78, 0x6F, 0xC7, 0xC2, 0x59, 0xB6, 0x8B, 0xF4, 0x35, 0x31, 0x19, 0x4F, 0xE2, 0x56, 0x39, 
  0x50, 0x5C, 0x65, 0x0C, 0x29, 0xF2, 0x22, 0xE1, 0x35, 0x51, 0xE1, 0x91, 0x89, 0x52, 0xF3, 0x64 ]
t513 = [ 0xB8, 0xE4, 0x0F, 0xD5, 0xAC, 0x6B, 0x38, 0x5F, 0x4F, 0x75, 0x21, 0x0F, 0x38, 0x3B, 0x43, 0x0D, 0x9F, 0xD8, 0x46, 0xCA,
  0xB0, 0x7C, 0x26, 0x71, 0x6D, 0xCA, 0xB4, 0x48, 0xBE, 0x3C, 0x96, 0xAE, 0xCE, 0x63, 0x88, 0xC2, 0x9A, 0x63, 0x49, 0x5F,
  0xEF, 0xB9, 0x1F, 0xB8, 0x46, 0x66, 0x98, 0xF3, 0x95, 0xB9, 0xBF, 0xBA, 0x15, 0x47, 0x56, 0x3A, 0x70, 0x88, 0x0A, 0x8D,
  0x20, 0x3C, 0x2E, 0x1A, 0x76, 0xDE, 0xE8, 0xB6, 0x9A, 0x65, 0x6B, 0xD8, 0x93, 0xF1, 0x55, 0xC5, 0x65, 0xA7, 0x97, 0xF3,
  0xC7, 0x43, 0x2E, 0xED, 0xA5, 0x19, 0x80, 0xB4, 0xFE, 0x39, 0x02, 0xD2, 0xDE, 0xF7, 0x4D, 0x31, 0x61, 0x10, 0xC0, 0x45,
  0x26, 0x9D, 0x37, 0x94, 0x2C, 0x19, 0xA7, 0xC7, 0x1A, 0xAC, 0xD8, 0xEC, 0xFA, 0x9D, 0x2E, 0x18, 0xFB, 0x8E, 0x26, 0x25,
  0xAD, 0x43, 0xC0, 0x59, 0x3B, 0x6E, 0x55, 0xFA, 0x27, 0x18, 0x21, 0xED, 0x36, 0x54, 0x04, 0xB9, 0x9B, 0x54, 0x5E, 0x12,
  0x31, 0x9E, 0x86, 0xBC, 0xD6, 0x7A, 0x54, 0xF2, 0x02, 0x8B, 0x39, 0xC1, 0x4A, 0xAD, 0x3D, 0x3A, 0x12, 0x5A, 0x90, 0x3D,
  0xD5, 0x6F, 0x4E, 0x30, 0xE5, 0xFC, 0xAF, 0x75, 0x10, 0xB2, 0x0E, 0xE2, 0x8A, 0x9F, 0x46, 0x2B, 0x34, 0xEA, 0x87, 0x73,
  0xB7, 0x39, 0x51, 0x9B, 0xAB, 0x62, 0x27, 0xA8, 0xF1, 0xD7, 0xE7, 0xF2, 0xE3, 0xAE, 0x9F, 0x21, 0x8F, 0x8F, 0x70, 0x0D,
  0x4B, 0x0D, 0x7B, 0x25, 0xFC, 0xC9, 0x8C, 0xF6, 0xD5, 0x21, 0xC1, 0xC8, 0xF9, 0x75, 0xAD, 0xE7, 0xA7, 0xB3, 0xF5, 0x31,
  0xB1, 0xF6, 0x66, 0x7B, 0xCA, 0x34, 0xDA, 0xCD, 0x37, 0xAB, 0x80, 0x44, 0x2F, 0x1C, 0x5B, 0xD3, 0x05, 0x94, 0x65, 0xC7,
  0xDC, 0xC3, 0x82, 0xAF, 0x8F, 0xA6, 0x56, 0x62, 0x28, 0x54, 0x7E, 0xF8, 0xEE, 0x49, 0x78, 0xD9, 0x4B, 0xA8, 0x81, 0xDD,
  0x3B, 0x71, 0xD2, 0x36, 0xB9, 0x18, 0xC9, 0x2D, 0xD7, 0x78, 0xFD, 0x66, 0xE7, 0x85, 0xF2, 0x0F, 0xFC, 0xEB, 0x8B, 0x93,
  0x76, 0x48, 0x53, 0xF8, 0x05, 0x94, 0x93, 0xAC, 0x68, 0xE2, 0x3A, 0xB2, 0xE4, 0x65, 0x8B, 0x47, 0x75, 0x49, 0xF4, 0x5F,
  0x59, 0x64, 0x5A, 0x16, 0x3B, 0xB2, 0xB7, 0x37, 0x50, 0xA3, 0xBA, 0x4B, 0xB4, 0xE6, 0xAF, 0x9A, 0xC7, 0x6E, 0x15, 0x51,
  0x88, 0xB5, 0xE0, 0xFA, 0x09, 0xB4, 0x90, 0x47, 0xDD, 0x3D, 0x86, 0x90, 0xA9, 0x12, 0x30, 0x2F, 0x79, 0x83, 0xDF, 0xF1,
  0xA8, 0x2D, 0xC9, 0xBC, 0xFB, 0xBD, 0x61, 0x93, 0x3F, 0x18, 0xB9, 0x38, 0x5C, 0xCA, 0x20, 0x58, 0x3B, 0x1C, 0xF3, 0xD9,
  0x56, 0xBE, 0x5F, 0x1A, 0x3E, 0x0F, 0x18, 0xD5, 0xF1, 0xA2, 0xFD, 0x8B, 0xB0, 0x27, 0x67, 0x0F, 0xB8, 0x4D, 0x51, 0xEB,
  0x8B, 0x2C, 0x50, 0x14, 0xDC, 0xD2, 0xAD, 0x7E, 0x06, 0xFE, 0x6A, 0x4D, 0x26, 0x38, 0x37, 0x9E, 0x77, 0x16, 0xBF, 0xB4,
  0xA0, 0xF9, 0x0A, 0x64, 0x0E, 0x7F, 0xD0, 0xF4, 0xE5, 0x72, 0x82, 0x72, 0xC8, 0x7A, 0xB7, 0xEC, 0x8D, 0x53, 0x14, 0x2D,
  0xA5, 0x98, 0xAD, 0xBE, 0x17, 0x83, 0x42, 0xD4, 0xC4, 0x04, 0xE7, 0xC2, 0x4D, 0x20, 0x05, 0xDE, 0xAA, 0xE8, 0x09, 0xE7,
  0x45, 0x15, 0x74, 0xEF, 0x7F, 0x6E, 0x38, 0x76, 0xAA, 0x5B, 0x44, 0xCC, 0xFD, 0x82, 0x12, 0xF6, 0xDA, 0x33, 0x84, 0x0A,
  0x6A, 0x5B, 0x34, 0xE7, 0x9E, 0x22, 0x10, 0xF5, 0x8C, 0xA0, 0xCA, 0x92, 0x58, 0xA1, 0xD0, 0x46, 0x47, 0xDA, 0xF6, 0x43,
  0x3C, 0xF1, 0x17, 0x8F, 0x50, 0xE4, 0xFD, 0x33, 0xBD, 0x46, 0x83, 0x41, 0x0E, 0xD5, 0x27, 0x0D, 0xB2, 0x87, 0x86, 0x16,
  0x82, 0x1D, 0xDD, 0xE7, 0xE1, 0xEF, 0x29, 0x5D, 0x48, 0xF4, 0xFC, 0xF2, 0x1D ]            

VXWORKS = 0
DRYOS = 1
osName = [ 'VxWorks', 'DryOS' ]
models = [ [ 0x80000169, VXWORKS, '1D Mark III'],           [ 0x80000176, VXWORKS, '450D / Rebel XSi'],
           [ 0x80000190, VXWORKS, '40D'],                   [ 0x80000213, VXWORKS, '5D'],
           [ 0x80000215, VXWORKS, '1Ds Mark III'],          [ 0x80000218, DRYOS,   '5D Mark II'],
           [ 0x80000234, VXWORKS, '30D'],                   [ 0x80000236, VXWORKS, '400D / Rebel XTi'],
           [ 0x80000250, DRYOS, '7D'],                      [ 0x80000252, DRYOS, '500D / T1i'],
           [ 0x80000254, VXWORKS, '1000D / Rebel XS'],      [ 0x80000261, DRYOS, '50D'],
           [ 0x80000270, DRYOS, '550D / T2i'],              [ 0x80000281, DRYOS, '1D Mark IV'],
           [ 0x80000241, DRYOS, 'WFT-E2'],                  [ 0x80000246, DRYOS, 'WFT-E3'] ]

def getLongLE(d, a):
   return unpack('<L',(d)[a:a+4])[0]

def getModel(id):
  for i in models:
    if i[0]==id:
      return i[1], i[2]
  return None, '???'

#from dissect_fw3_2.rar : http://chdk.setepontos.com/index.php?action=dlattach;topic=111.0;attach=2700    
def xor_decode( seed, start, len ):
  o512 = ctypes.c_uint32(seed << 23).value >> 23
  v = (seed * 0xFF803FE1) >> 32
  o513 = seed - ((v>>9) + (v & 0xFFFFFE00))
  out = array.array('B', m[start:start+len] )
  for i in range(len):
    out[i] =  out[i] ^ t512[o512] ^ t513[o513] ^ 0x37 
    o512 = (o512+1) % 512
    o513 = (o513+1) % 513
  return out

def check_xor_decoding( os, out):
  if (os==VXWORKS and out[8:16].tostring() == 'Copyrigh') or (os==DRYOS and out[4:12].tostring() == 'gaonisoy'):
    return True
  else:
    return False

def decipher_updater( xorSeed, offset, len, filename):
  out = xor_decode( xorSeed, offset, len)
  print ' xor_decoding [0x%x-0x%x]...' % ( offset, offset+len),
  if check_xor_decoding( os, out):
    print 'OK (%s)' % filename
    f = open(filename, 'wb')
    out.tofile(f)
    f.close()
  else:
    print 'KO'

parser = OptionParser(usage="usage: %prog [options] filename")
parser.add_option("-z", "--zeros", action="store_true", dest="zeros", help="print fields usually filled with zeros", default=False)
parser.add_option("-c", "--checksum", action="store_true", dest="checksum", default=False, help="verify checksum(s)")
parser.add_option("-x", "--extract", action="store_true", dest="extract", default=False, help="extract updater(s) code")
parser.add_option("-v", "--verbose", action="store_true", dest="verbose", default=False, help="verbose mode")
(options, args) = parser.parse_args()
  
f = open(args[0], 'rb')
m = f.read()
fileLen = f.tell()
f.close()

print 'Fir_tool %s\n' % version_id
print 'fileLen = 0x%x' % fileLen
print '---.fir header---'
model = getLongLE( m, 0 )
print '0x000: modelId = 0x%08x,' % model,
os, modelName = getModel( model )
if (os!=None):
  print '(%s, %s)' % (modelName, osName[os] )
if options.zeros:
  print '0x004: %s' % hexlify( m[ 4:0x10 ] ) 
print '0x010: version = %s' % ( m[0x10:0x10+5] )
if model==0x80000213 or model==0x80000234 or model==0x80000236: # 5D, 400D and 30D
  print 'not supported by python version of fir_tool'
  sys.exit()

if options.zeros:
  print '0x015: %s' % hexlify( m[ 0x15:0x20 ] ) 
fsum = getLongLE( m, 0x20 )
print '0x020: checksum = 0x%08x' %  fsum 
if options.checksum:
  csum = sum( array.array('B', m[ 0:0x20 ]) ) + sum( array.array('B', m[ 0x24:fileLen ]) )
  if fsum != ctypes.c_uint32(~csum).value:
   print " checksum error (decryption2) csum=%x" % (csum)
  else:
    print " checksum computing [0x%x-0x%x] is OK!" % (0 , fileLen)
updater1header = getLongLE( m, 0x24 )
updater1 = getLongLE( m, 0x28 )
print '0x024: updater1 header = 0x%x' % ( updater1header )
print '0x028: updater1 offset = 0x%x' % updater1
updater2header = getLongLE( m, 0x2c )
print '0x02c: updater2 offset = 0x%x' % updater2header
firmware = getLongLE( m, 0x30 )
print '0x030: firmware offset = 0x%x' % firmware
print '0x034: 0x%x' % getLongLE( m, 0x34 )
efileLen = getLongLE( m, 0x38 )
print '0x038: embedded file size = 0x%x' % efileLen
if efileLen != fileLen:
  print 'error file size != embedded file size'
print '0x03c: 0x%x' % getLongLE( m, 0x3c )
print '0x040: sha1 seed = 0x%x' % getLongLE( m, 0x40 )
print '0x044:',
for i in range(7):
  print '0x%08x' % getLongLE( m, 0x44+i*4 ),
print
updater1total = getLongLE( m, 0x60 )
print '0x060: 0x%x' % updater1total 
firmwareLen = getLongLE( m, 0x64 )
print '0x064: firmware length = 0x%x' % firmwareLen
if (firmwareLen + firmware) != efileLen:
  print 'error : (firmwareLen + firmware) != efileLen'
print '0x068: updater1 hmac-sha1 = %s' % hexlify( m[ 0x68:0x68+20 ] ) 
print '0x088: firmware hmac-sha1 = %s' % hexlify( m[ 0x88:0x88+20 ] ) 
print '---updater1 header---'
updater1len = getLongLE( m, updater1header )
print '0x%03x: updater1 length = 0x%x. starts at 0x%x' % (updater1header, updater1len, updater1)
print '0x%03x: 0x%x' % ( updater1header + 4, getLongLE( m, updater1header+4 ))
print '0x%03x: 0x%x' % ( updater1header + 8, getLongLE( m, updater1header+8 ))
xorSeed = getLongLE( m, updater1header + 0xc )
print '0x%03x: xor seed value = 0x%x' % ( updater1header + 0xc, xorSeed)
if getLongLE( m, 0xc0 )!=0 or options.zeros:
  print '0x0c0: %s' % hexlify( m[ 0x0c0:0x0d0 ] ) 
  print '0x0d0: %s' % hexlify( m[ 0x0d0:0x0f0 ] ) 
  print '0x0f0: %s' % hexlify( m[ 0x0f0:0x100 ] ) 
  print '0x100: %s' % hexlify( m[ 0x100:0x120 ] ) 
print '0x%03x: --- updater1 (ciphered) ---' % updater1
prefix = '{0:04x}'.format(model & 0xffff) + "_" + m[0x10]+m[0x12]+m[0x14] 
if options.extract:
  decipher_updater( xorSeed, updater1, updater1len, prefix+'_updater1_.bin')

if ctypes.c_int32(updater2header).value!=-1:
  print '---updater2 header---'
  model2 = getLongLE( m, updater2header )
  print '0x%03x: (+0x000), modelId = 0x%08x,' % (updater2header, model2),
  os2, modelName2 = getModel( model2 )
  if (os2 != None):
    print '(%s, %s)' % (modelName2, osName[os2] )
  print '0x%03x: (+0x010), version = %s' % ( updater2header+0x10, m[updater2header+0x10:updater2header+0x10+5] )
  fsum2 = getLongLE( m, updater2header+0x20 )
  print '0x%03x: (+0x020), checksum? = 0x%08x' %  ( updater2header+0x20, fsum2 )
  print '0x%03x: (+0x024), 0x%x' %  ( updater2header+0x24, getLongLE( m, updater2header+0x24 ) )
  print '0x%03x: (+0x028), 0x%x' %  ( updater2header+0x28, getLongLE( m, updater2header+0x28 ) )
  print '0x%03x: (+0x02c),' % (updater2header+0x2c),
  for i in range (3):
    print '%x' %  ( getLongLE( m, updater2header+0x2c+i*4 ) ),
  print
  print '0x%03x: (+0x038), updater length (including header) = 0x%x. starts at 0x%x' \
   %  ( updater2header+0x38, getLongLE( m, updater2header+0x38 ), updater2header )
  if options.zeros:
    print '0x%03x: (+0x03c), %s' % ( updater2header+0x3c, hexlify( m[ updater2header+0x3c:updater2header+0x3c+0x30 ] ) )
    print '0x%03x: (+0x06c), %s' % ( updater2header+0x6c, hexlify( m[ updater2header+0x6c:updater2header+0x6c+0x30 ] ) )
    print '0x%03x: (+0x09c), %s' % ( updater2header+0x9c, hexlify( m[ updater2header+0x9c:updater2header+0x9c+0x14 ] ) )
  updater2len = getLongLE( m, updater2header+0xb0 )
  updater2 = updater2header+0x120
  print '0x%03x: (+0x0b0), updater length = 0x%x. starts at 0x%x' %  ( updater2header+0xb0, updater2len, updater2 )
  print '0x%03x: (+0x0b4), 0x%x' %  ( updater2header+0xb4, getLongLE( m, updater2header+0xb4 ) )
  print '0x%03x: (+0x0b8), 0x%x' %  ( updater2header+0xb8, getLongLE( m, updater2header+0xb8 ) )
  xorSeed2 = getLongLE( m, updater2header+0xbc )
  print '0x%03x: (+0x0bc), xor seed value = 0x%x' %  ( updater2+0xbc, xorSeed2 )
  if options.zeros:
    print '0x%03x: (+0x0c0), %s' % ( updater2header+0xc0, hexlify( m[ updater2header+0xc0:updater2header+0xe0 ] ) )
    print '0x%03x: (+0x0e0), %s' % ( updater2header+0xe0, hexlify( m[ updater2header+0xe0:updater2header+0x100 ] ) )
    print '0x%03x: (+0x100), %s' % ( updater2header+0x100, hexlify( m[ updater2header+0x100:updater2header+0x120 ] ) )
  print '0x%03x: (+0x120), --- updater2 (ciphered) ---' % (updater2)
  if options.extract:
    decipher_updater( xorSeed2, updater2, updater2len, prefix+'_updater2_.bin')

print '---firmware header---'
print '0x%06x: (+0x000), offset to decryption data = 0x%x' % ( firmware,  getLongLE( m, firmware ))
print '0x%06x: (+0x004), offset to encrypted data = 0x%x. starts at 0x%x' % ( firmware+4,  getLongLE( m, firmware+4 ), firmware)
print '0x%06x: (+0x008), total firmware length (including header) = 0x%x. starts at 0x%x' % ( firmware+8,  getLongLE( m, firmware+8 ), firmware)
print '-'
print '0x%06x: (+0x00c), firmware length (encrypted part) = 0x%x. starts at 0x%x' % ( firmware+0xc,  getLongLE( m, firmware+0xc ), firmware+0x7c)
print '0x%06x: (+0x010), 0x%08x' % ( firmware+0x10,  getLongLE( m, firmware+0x10 ))
print '0x%06x: (+0x014), 0x%x' % ( firmware+0x14,  getLongLE( m, firmware+0x14 ))
print '0x%06x: (+0x018), 0x%08x' % ( firmware+0x18,  getLongLE( m, firmware+0x18 ))
print '0x%06x: (+0x01c), %s' % ( firmware+0x1c, hexlify( m[ firmware+0x1c:firmware+0x1c+0x10 ] ) )
print '0x%06x: (+0x02c), %s' % ( firmware+0x2c, hexlify( m[ firmware+0x2c:firmware+0x2c+0x20 ] ) )
print '0x%06x: (+0x04c), %s' % ( firmware+0x4c, hexlify( m[ firmware+0x4c:firmware+0x4c+0x10 ] ) )
print '0x%06x: (+0x05c), %s' % ( firmware+0x5c, hexlify( m[ firmware+0x5c:firmware+0x5c+0x20 ] ) )
print '---firmware (encrypted)---'
print '0x%06x: (+0x07c)' % ( firmware+0x7c )
back to top