Esempio n. 1
0
 def process_image(self, config, imagenum, images, cur_image):
     # ASpeed seems to place global footer right after the last image
     # The size contains also part of the footer, so we extract it
     # But if the image is re-packed, that part is lost
     # so we need to check and add it, if needed
     if imagenum == images[-1]:
         if cur_image[-10:-2] != 'ATENs_FW':
             footer = FirmwareFooter()
             footer.rev1 = int(config.get('global', 'major_version'), 0)
             footer.rev2 = int(config.get('global', 'minor_version'), 0)
             footer.footerver = int(config.get('global', 'footer_version'),
                                    0)
             footer.rootfs_nfo = "00000000"
             footer.webfs_nfo = "00000000"
             return cur_image + footer.getRawString()[:10]
     return cur_image
Esempio n. 2
0
	def process_image(self, config, imagenum, images, cur_image):
		# ASpeed seems to place global footer right after the last image
		# The size contains also part of the footer, so we extract it
		# But if the image is re-packed, that part is lost
		# so we need to check and add it, if needed
		if imagenum == images[-1]:
			if cur_image[-10:-2] != 'ATENs_FW':
				footer = FirmwareFooter()
				footer.rev1 = int(config.get('global','major_version'),0)
				footer.rev2 = int(config.get('global','minor_version'),0)
				footer.footerver = int(config.get('global','footer_version'),0)
				footer.rootfs_nfo = "00000000"
				footer.webfs_nfo = "00000000"
				return cur_image + footer.getRawString()[:10]
		return cur_image
Esempio n. 3
0
    def parse(self, ipmifw, extract, config):
        bootloader = ipmifw[:64040]
        bootloader_md5 = hashlib.md5(bootloader).hexdigest()

        if extract:
            print("Dumping bootloader to data/bootloader.bin")
            with open('data/bootloader.bin', 'wb') as f:
                f.write(bootloader)

        imagecrc = []
        # Start by parsing all the different images within the firmware
        # This method comes directly from the SDK.  Read through the file in 64 byte chunks, and look for the signature at a certain point in the string
        # Seems kinda scary, as there might be other parts of the file that include this.
        for i in range(0, len(ipmifw), 64):
            footer = ipmifw[i:i + 64]

            fi = FirmwareImage()
            # 12 bytes of padding.  I think this can really be anything, though it's usually \xFF
            fi.loadFromString(footer[12:])

            if not fi.isValid():
                continue

            print("\n" + str(fi))

            imagestart = fi.base_address
            if imagestart > 0x40000000:
                # I'm unsure where this 0x40000000 byte offset is coming from.  Perhaps I'm not parsing the footer correctly?
                imagestart -= 0x40000000

            imageend = imagestart + fi.length

            curcrc = zlib.crc32(ipmifw[imagestart:imageend]) & 0xffffffff
            imagecrc.append(curcrc)

            if extract:
                print("Dumping 0x%s to 0x%s to data/%s.bin" %
                      (imagestart, imageend, fi.name))
                with open('data/%s.bin' % fi.name, 'wb') as f:
                    f.write(ipmifw[imagestart:imageend])
                computed_image_checksum = FirmwareImage.computeChecksum(
                    ipmifw[imagestart:imageend])

                if computed_image_checksum != fi.image_checksum:
                    print(
                        "Warning: Image checksum mismatch, footer: 0x%x computed: 0x%x"
                        % (fi.image_checksum, computed_image_checksum))
                else:
                    print("Image checksum matches")

            config.set('images', str(fi.imagenum), 'present')
            configkey = 'image_%i' % fi.imagenum
            config.add_section(configkey)
            config.set(configkey, 'length', hex(fi.length))
            config.set(configkey, 'base_addr', hex(fi.base_address))
            config.set(configkey, 'load_addr', hex(fi.load_address))
            config.set(configkey, 'exec_addr', hex(fi.exec_address))
            config.set(configkey, 'name', fi.name)
            config.set(configkey, 'type', hex(fi.type))

        # Next, find and validate the global footer
        for imageFooter in re.findall(b"ATENs_FW(.{8})", ipmifw, re.DOTALL):
            footer = FirmwareFooter()
            footer.loadFromString(imageFooter)
            computed_checksum = footer.computeFooterChecksum(imagecrc)

            print("\n" + str(footer))

            if footer.checksum == computed_checksum:
                print("Firmware checksum matches")
            else:
                print(
                    "Firwamre checksum mismatch, footer: 0x%x computed: 0x%x" %
                    (footer.checksum, computed_checksum))

            config.set('global', 'major_version', str(footer.rev1))
            config.set('global', 'minor_version', str(footer.rev2))
            config.set('global', 'footer_version', str(footer.footerver))
Esempio n. 4
0
	def parse(self, ipmifw, extract, config):
		bootloader = ipmifw[:64040]
		bootloader_md5 = hashlib.md5(bootloader).hexdigest()


		if extract:
			print "Dumping bootloader to data/bootloader.bin"
			with open('data/bootloader.bin','w') as f:
				f.write(bootloader)


		imagecrc = []
		# Start by parsing all the different images within the firmware
		# This method comes directly from the SDK.  Read through the file in 64 byte chunks, and look for the signature at a certain point in the string
		# Seems kinda scary, as there might be other parts of the file that include this.
		for i in range(0,len(ipmifw),64):
			footer = ipmifw[i:i+64]

			fi = FirmwareImage()
			# 12 bytes of padding.  I think this can really be anything, though it's usually \xFF
			fi.loadFromString(footer[12:])

			if not fi.isValid():
				continue

			print "\n"+str(fi)

			imagestart = fi.base_address
			if imagestart > 0x40000000:
				# I'm unsure where this 0x40000000 byte offset is coming from.  Perhaps I'm not parsing the footer correctly?
				imagestart -= 0x40000000

			imageend = imagestart + fi.length

			curcrc = zlib.crc32(ipmifw[imagestart:imageend]) & 0xffffffff
			imagecrc.append(curcrc)

			if extract:
				print "Dumping 0x%s to 0x%s to data/%s.bin" % (imagestart, imageend, fi.name)
				with open('data/%s.bin' % fi.name.replace("\x00",""),'w') as f:
					f.write(ipmifw[imagestart:imageend])
				computed_image_checksum = FirmwareImage.computeChecksum(ipmifw[imagestart:imageend])

				if computed_image_checksum != fi.image_checksum:
					print "Warning: Image checksum mismatch, footer: 0x%x computed: 0x%x" % (fi.image_checksum,computed_image_checksum)
				else:
					print "Image checksum matches"


			config.set('images', str(fi.imagenum), 'present')
			configkey = 'image_%i' % fi.imagenum
			config.add_section(configkey)
			config.set(configkey, 'length', hex(fi.length))
			config.set(configkey, 'base_addr', hex(fi.base_address))
			config.set(configkey, 'load_addr', hex(fi.load_address))
			config.set(configkey, 'exec_addr', hex(fi.exec_address))
			config.set(configkey, 'name', fi.name)
			config.set(configkey, 'type', hex(fi.type))

		# Next, find and validate the global footer
		for imageFooter in re.findall("ATENs_FW(.{8})",ipmifw,re.DOTALL):
			footer = FirmwareFooter()
			footer.loadFromString(imageFooter)
			computed_checksum = footer.computeFooterChecksum(imagecrc)

			print "\n"+str(footer)

			if footer.checksum == computed_checksum:
				print "Firmware checksum matches"
			else:
				print "Firwamre checksum mismatch, footer: 0x%x computed: 0x%x" % (footer.checksum, computed_checksum)

			config.set('global', 'major_version', footer.rev1)
			config.set('global', 'minor_version', footer.rev2)
			config.set('global', 'footer_version', footer.footerver)
    curblockend = curblock * 65536

    last_image_end = new_image.tell()

    # If we don't have space to write the footer at the end of the current block, move to the next block
    if curblockend - 61 < last_image_end:
        curblock += 1

    footerpos = (curblock * 65536) - 61

    new_image.seek(footerpos)

    # And write the footer to the output file
    new_image.write(fi.getRawString())

footer = FirmwareFooter()
footer.rev1 = int(config.get('global', 'major_version'), 0)
footer.rev2 = int(config.get('global', 'minor_version'), 0)
footer.footerver = int(config.get('global', 'footer_version'), 0)
footer.checksum = footer.computeFooterChecksum(imagecrc)

# Hmm... no documentation on where this should be, but in the firmware I have it's been palced right before the last image footer
# Unsure if that's where it goes, or if it doesn't matter
# 16 includes 8 padding \xFF's between the global footer and the last image footer
global_start = footerpos - 16
if global_start < curblockend:
    print "ERROR: Would have written global footer over last image"
    print "Aborting"
    sys.exit(1)

# Write the global footer
Esempio n. 6
0
	last_image_end = new_image.tell()

	# If we don't have space to write the footer at the end of the current block, move to the next block
	if curblockend - 61 < last_image_end:
		curblock += 1

	footerpos = (curblock * 65536) - 61

	new_image.seek(footerpos)

	# And write the footer to the output file
	new_image.write(fi.getRawString())


footer = FirmwareFooter()
footer.rev1 = int(config.get('global','major_version'),0)
footer.rev2 = int(config.get('global','minor_version'),0)
footer.footerver = int(config.get('global','footer_version'),0)
footer.checksum = footer.computeFooterChecksum(imagecrc)

# Hmm... no documentation on where this should be, but in the firmware I have it's been palced right before the last image footer
# Unsure if that's where it goes, or if it doesn't matter
# 16 includes 8 padding \xFF's between the global footer and the last image footer
global_start = footerpos-16
if global_start < curblockend:
	print "ERROR: Would have written global footer over last image"
	print "Aborting"
	sys.exit(1)

# Write the global footer