class Uboot: def __init__(self, filename): self.firmware_filepath = filename statinfo = os.stat(self.firmware_filepath) self.firmware_size = statinfo.st_size self.carver = Carver(self.firmware_filepath) self.ubootheader = self._set_uboot_header() def get_remaining_blocks(self): non_carved_areas = self.carver.carved.non_carved_areas remaining = {} for area in non_carved_areas: remaining[area[0]] = self.carver.extract_data(area[0], area[1]) return remaining def extract_uboot_image(self): return self.carver.extract_data( uBootHeader.HEADER_LENGTH, uBootHeader.HEADER_LENGTH + self.ubootheader.image_data_size) def _set_uboot_header(self): with open(self.firmware_filepath, 'r+b') as raw_file: mm = mmap.mmap(raw_file.fileno(), 0) ubootheader = uBootHeader() ubootheader.create_from_binary(mm.read(uBootHeader.HEADER_LENGTH)) return ubootheader def extract_uboot_header(self): return self.carver.extract_data(0, uBootHeader.HEADER_LENGTH)
def __init__(self, filename): self.firmware_filepath = filename statinfo = os.stat(self.firmware_filepath) self.firmware_size = statinfo.st_size self.carver = Carver(self.firmware_filepath) self.ubootheader = self._set_uboot_header()
def __init__(self, filename): self.img0 = None self.md5_checksum = None self.firmware_filepath = filename self.firmware = open(filename, 'rb') self._read_container_information() self.firmware.close() self.carver = Carver(self.firmware_filepath)
class TPWR702N: MD5SIZE = 16 # -------- Devices -------- IMG0_OFFSET = 20 IMG0_HEADER_SIZE = 12 BOOTLOADER_OFFSET = 26820 OS_OFFSET = 262420 def __init__(self, filename): self.img0 = None self.md5_checksum = None self.firmware_filepath = filename self.firmware = open(filename, 'rb') self._read_container_information() self.firmware.close() self.carver = Carver(self.firmware_filepath) def __str__(self): return 'MD5: {} \n Included Header:\n{}'.format( self.get_md5string(), str(self.img0)) def get_remaining_blocks(self): non_carved_areas = self.carver.carved.non_carved_areas remaining = {} for area in non_carved_areas: remaining[area[0]] = self.carver.extract_data(area[0], area[1]) return remaining def get_container_header(self): return self.carver.extract_data(0, 19) def get_md5string(self): return binascii.hexlify(self.md5_checksum).decode('ascii') def get_meta_dict(self): meta_data = {} meta_data['bootloader_offset'] = self.BOOTLOADER_OFFSET meta_data['os_offset'] = self.OS_OFFSET meta_data['md5'] = self.get_md5string() meta_data['img0'] = self.img0.get_meta_dict() meta_data['uncarved_area'] = self.carver.carved.non_carved_areas return meta_data def _read_container_information(self): header = unpack('>4s16s', self.firmware.read(4 + self.MD5SIZE)) self.container_format = header[0] self.md5_checksum = header[1] self._read_img0() def _read_img0(self): self.img0 = TPIMG0(self.firmware_filepath, self.IMG0_OFFSET) def get_container_format(self): return self.container_format def get_checksum(self): return self.md5_checksum def get_tpimg0_header(self): return self.carver.extract_data( self.IMG0_OFFSET, self.IMG0_OFFSET + self.IMG0_HEADER_SIZE) def get_bootloader(self): bootloader_size = self._get_end_of_bootloader( ) - self.BOOTLOADER_OFFSET bootloader = self.carver.extract_data( self.BOOTLOADER_OFFSET, self.BOOTLOADER_OFFSET + bootloader_size) self._check_expected_lzma_property(bootloader) return bootloader def _get_end_of_bootloader(self): if self.img0 is None: raise Img0MissingException('Main IMG0 is missing') if self.img0.sub_header is None: raise Img0MissingException('Sub IMG0 is missing') return self.img0.sub_header.offset - 1 @staticmethod def _check_expected_lzma_property(data_block): lzma_first_byte = b'\x6e' if data_block[0] is not lzma_first_byte[0]: raise NotLZMAException def get_os_and_fs(self): os_and_fs = self.carver.extract_data(self.OS_OFFSET) self._check_expected_lzma_property(os_and_fs) return os_and_fs def get_os(self): os_and_fs = self.get_os_and_fs() end = self._find_fs_magic_string(os_and_fs) return os_and_fs[:end] def get_fs(self): os_and_fs = self.get_os_and_fs() end = self._find_fs_magic_string(os_and_fs) return os_and_fs[end:] @staticmethod def _find_fs_magic_string(os_and_fs): search_pattern = b'owowowowowowowowowowowowowowowow' return os_and_fs.find(search_pattern) def check_container_validity(self): self._check_img0_information() self._check_boot_and_os_blocks() if not self._check_md5(): raise MD5Exception return True def _check_img0_information(self): if self.img0 is None: raise InvalidContainerInformationException( 'IMG0 header is missing') if self.img0.sub_header is None: raise InvalidContainerInformationException( 'IMG0 sub header is missing') self.img0.check_header() self.img0.sub_header.check_header() expected_device = b'\x07\x02' if self.img0.device_id != expected_device: raise InvalidContainerInformationException( 'Wrong device id {}'.format(self.img0.device_id)) def _check_boot_and_os_blocks(self): with open(self.firmware_filepath, 'rb') as firmware: self._check_blocks(firmware, self.BOOTLOADER_OFFSET) self._check_blocks(firmware, self.OS_OFFSET) def _check_blocks(self, firmware_file, offset): firmware_file.seek(offset) first_byte = firmware_file.read(1) self._check_expected_lzma_property(first_byte) def _check_md5(self): with open(self.firmware_filepath, 'rb') as firmware: image = firmware.read() image = bytearray(image) image[4] = int('cc', 16) image[5] = int('96', 16) image[6] = int('28', 16) image[7] = int('ee', 16) image[8] = int('8d', 16) image[9] = int('fb', 16) image[10] = int('21', 16) image[11] = int('bb', 16) image[12] = int('3d', 16) image[13] = int('ef', 16) image[14] = int('6c', 16) image[15] = int('b5', 16) image[16] = int('9f', 16) image[17] = int('77', 16) image[18] = int('4c', 16) image[19] = int('7c', 16) image = bytes(image) m = hashlib.md5() m.update(image) return m.digest() == self.md5_checksum
class TPWR702N: MD5SIZE = 16 # -------- Devices -------- IMG0_OFFSET = 20 IMG0_HEADER_SIZE = 12 BOOTLOADER_OFFSET = 26820 OS_OFFSET = 262420 def __init__(self, filename): self.img0 = None self.md5_checksum = None self.firmware_filepath = filename self.firmware = open(filename, 'rb') self._read_container_information() self.firmware.close() self.carver = Carver(self.firmware_filepath) def __str__(self): return 'MD5: {} \n Included Header:\n{}'.format( self.get_md5string(), str(self.img0)) def get_remaining_blocks(self): non_carved_areas = self.carver.carved.non_carved_areas remaining = {} for area in non_carved_areas: remaining[area[0]] = self.carver.extract_data(area[0], area[1]) return remaining def get_container_header(self): return self.carver.extract_data(0, 19) def get_md5string(self): return binascii.hexlify(self.md5_checksum).decode('ascii') def get_meta_dict(self): meta_data = {} meta_data['bootloader_offset'] = self.BOOTLOADER_OFFSET meta_data['os_offset'] = self.OS_OFFSET meta_data['md5'] = self.get_md5string() meta_data['img0'] = self.img0.get_meta_dict() meta_data['uncarved_area'] = self.carver.carved.non_carved_areas return meta_data def _read_container_information(self): header = unpack('>4s16s', self.firmware.read(4 + self.MD5SIZE)) self.container_format = header[0] self.md5_checksum = header[1] self._read_img0() def _read_img0(self): self.img0 = TPIMG0(self.firmware_filepath, self.IMG0_OFFSET) def get_tpimg0_header(self): return self.carver.extract_data( self.IMG0_OFFSET, self.IMG0_OFFSET + self.IMG0_HEADER_SIZE) def get_bootloader(self): bootloader_size = self._get_end_of_bootloader( ) - self.BOOTLOADER_OFFSET bootloader = self.carver.extract_data( self.BOOTLOADER_OFFSET, self.BOOTLOADER_OFFSET + bootloader_size) self._check_expected_lzma_property(bootloader) return bootloader def _get_end_of_bootloader(self): if self.img0 is None: raise Img0MissingException('Main IMG0 is missing') if self.img0.sub_header is None: raise Img0MissingException('Sub IMG0 is missing') return self.img0.sub_header.offset - 1 @staticmethod def _check_expected_lzma_property(data_block): lzma_first_byte = b'\x6e' if data_block[0] is not lzma_first_byte[0]: raise NotLZMAException def get_os_and_fs(self): os_and_fs = self.carver.extract_data(self.OS_OFFSET) self._check_expected_lzma_property(os_and_fs) return os_and_fs def get_os(self): os_and_fs = self.get_os_and_fs() end = self._find_fs_magic_string(os_and_fs) return os_and_fs[:end] def get_fs(self): os_and_fs = self.get_os_and_fs() end = self._find_fs_magic_string(os_and_fs) return os_and_fs[end:] @staticmethod def _find_fs_magic_string(os_and_fs): search_pattern = b'owowowowowowowowowowowowowowowow' return os_and_fs.find(search_pattern)