Beispiel #1
0
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)
Beispiel #2
0
    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()
Beispiel #3
0
    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)
Beispiel #4
0
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
Beispiel #5
0
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)