Skip to content

Commit

Permalink
Merge 8725581 into b1dc2f7
Browse files Browse the repository at this point in the history
  • Loading branch information
Caesurus committed Feb 17, 2021
2 parents b1dc2f7 + 8725581 commit 2c640f2
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 24 deletions.
55 changes: 54 additions & 1 deletion tests/test_old_image.py
Expand Up @@ -35,7 +35,7 @@ def teardown_module(module):
os.remove(UBOOT_IMG_TEMP)


def test_01():
def test_01_multi_file_image():
# --------------------------------------------------------------------------------
# create dummy firmware image (u-boot executable image)
# --------------------------------------------------------------------------------
Expand Down Expand Up @@ -94,3 +94,56 @@ def test_01():

# check if are identical
assert mimg == img

def test_02_funky_chars_in_name():
# --------------------------------------------------------------------------------
# create dummy firmware image (u-boot executable image)
# --------------------------------------------------------------------------------
fwimg = uboot.StdImage(bytes([1] * 16),
name=str('\x03\x00\x00\x04\x52\x54\x2d\x41\x43\x35\x35\x55\x48\x50\x00\x00\x00\x00\x00\xa9'),
laddr=0,
eaddr=0,
arch=uboot.EnumArchType.ARM,
os=uboot.EnumOsType.LINUX,
image=uboot.EnumImageType.FIRMWARE,
compress=uboot.EnumCompressionType.NONE)

# --------------------------------------------------------------------------------
# save created image into file: uboot_mimg.img
# --------------------------------------------------------------------------------
with open(UBOOT_IMG_TEMP, "wb") as f:
f.write(fwimg.export())

# --------------------------------------------------------------------------------
# open and read image file: uboot_mimg.img
# --------------------------------------------------------------------------------
with open(UBOOT_IMG_TEMP, "rb") as f:
data = f.read()

# --------------------------------------------------------------------------------
# parse binary data into new img object of specific image type
# --------------------------------------------------------------------------------
img = uboot.parse_img(data)
# check if are identical
assert fwimg == img


def test_03_bad_crc():
bad_crc_image = b'\x27\x05\x19\x56\x4F\x7c\x89\x60\x60\x2d\xa6\xec\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00\x0b\xcd\x6a\xaf\x05\x02\x05\x00\x03\x00\x00\x04\x52\x54\x2d\x41\x43\x35\x35\x55\x48\x50\x00\x00\x00\x00\x00\xc2\xa9\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01'

# --------------------------------------------------------------------------------
# parse binary data into new img object of specific image type
# --------------------------------------------------------------------------------
try:
img = uboot.parse_img(bad_crc_image)
except Exception:
pass
else:
assert False, 'Expected Exception when reading header with bad CRC'


# Don't expect an error
img = uboot.parse_img(bad_crc_image, ignore_crc=True)
expected_data = bytes([1] * 64)
assert img.data == expected_data, "Data wasn't correct"

2 changes: 1 addition & 1 deletion uboot/cli_mkimg.py
Expand Up @@ -191,7 +191,7 @@ def get_file_ext(img):
n = 0
for simg in img:
with open(os.path.join(dest_dir, 'image_{0:02d}.bin'.format(n)), 'wb') as f:
f.write(simg.eport())
f.write(simg.export())
n += 1
elif img.header.image_type == uboot.EnumImageType.SCRIPT:
with open(os.path.join(dest_dir, 'script.txt'), 'w') as f:
Expand Down
55 changes: 33 additions & 22 deletions uboot/old_image.py
Expand Up @@ -199,7 +199,7 @@ def export(self):
self.name.encode('utf-8'))

@classmethod
def parse(cls, data, offset=0):
def parse(cls, data, offset=0, ignore_crc=False):
if len(data) < cls.SIZE:
raise Exception("Header: Too small size of input data !")

Expand All @@ -217,13 +217,14 @@ def parse(cls, data, offset=0):
header.arch_type = val[8]
header.image_type = val[9]
header.compression = val[10]
header.name = val[11].decode('utf-8').strip('\0')
header.name = val[11].decode('utf-8', errors='ignore').strip('\0')

if header.magic_number != header.MAGIC_NUMBER:
raise Exception("Header: Magic number not valid !")

if header_crc != header.header_crc:
raise Exception("Header: Uncorrect CRC of input data !")
if not ignore_crc:
if header_crc != header.header_crc:
raise Exception(f"Header: Uncorrect CRC of input data ! {hex(header_crc)} != {hex(header.header_crc)}")

return header
# ----------------------------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -308,20 +309,22 @@ def export(self):
return self.header.export() + self.data

@classmethod
def parse(cls, data, offset=0):
def parse(cls, data, offset=0, ignore_crc=False):
""" Load the image from byte array.
:param data: The raw image as byte array
:param offset: The offset of input data
:param ignore_crc: ignore crc errors
"""
img = cls()
img.header = Header.parse(data, offset)
img.header = Header.parse(data, offset, ignore_crc)
offset += img.header.size
if len(data[offset:]) < img.header.data_size:
raise Exception("Image: Too small size of input data !")

img.data = data[offset:offset + img.header.data_size]
if CRC32(img.data) != img.header.data_crc:
raise Exception("Image: Uncorrect CRC of input data ")
if not ignore_crc:
raise Exception("Image: Uncorrect CRC of input data ")

return img

Expand Down Expand Up @@ -461,20 +464,22 @@ def export(self):
return self.header.export() + data

@classmethod
def parse(cls, data, offset=0):
def parse(cls, data, offset=0, ignore_crc=False):
""" Load the image from byte array.
:param data: The raw image as byte array
:param offset: The offset of input data
:param ignore_crc: ignore crc errors
"""
img = cls()
img.header = Header.parse(data, offset)
img.header = Header.parse(data, offset, ignore_crc)
offset += img.header.size
if len(data[offset:]) < img.header.data_size:
raise Exception("Image: Too small size of input data !")

data = data[offset:offset + img.header.data_size]
if CRC32(data) != img.header.data_crc:
raise Exception("Image: Uncorrect CRC of input data ")
if not ignore_crc:
raise Exception("Image: Uncorrect CRC of input data ")

# TODO: Check image format for script type
size = unpack_from('!2L', data)[0]
Expand Down Expand Up @@ -588,20 +593,22 @@ def export(self):
return self.header.export() + data

@classmethod
def parse(cls, data, offset=0):
def parse(cls, data, offset=0, ignore_crc=False):
""" Load the image from byte array.
:param data: The raw image as byte array
:param offset: The offset of input data
:param ignore_crc: ignore crc errors
"""
img = cls()
img.header = Header.parse(data, offset)
img.header = Header.parse(data, offset, ignore_crc)
offset += img.header.size

if len(data[offset:]) < img.header.data_size:
raise Exception("MultiImage: Too small size of input data !")

if CRC32(data[offset:offset + img.header.data_size]) != img.header.data_crc:
raise Exception("MultiImage: Uncorrect CRC of input data !")
if not ignore_crc:
raise Exception("MultiImage: Uncorrect CRC of input data !")

if img.header.image_type != EnumImageType.MULTI:
raise Exception("MultiImage: Not a Multi Image Type !")
Expand All @@ -623,22 +630,25 @@ def parse(cls, data, offset=0):
# ----------------------------------------------------------------------------------------------------------------------


def get_img_type(data, offset=0):
def get_img_type(data, offset=0, ignore_crc=False):
""" Help function for extracting image fom raw data
:param data: The raw data as byte array
:param offset: The offset
:return: Image type and offset where image start
"""
while True:
if (offset + Header.SIZE) > len(data):
raise Exception("Not an U-Boot image !")
raise Exception(f"Not an U-Boot image ! {(offset + Header.SIZE)} > {len(data)}")

(header_mn, header_crc,) = unpack_from('!2L', data, offset)
# Check the magic number if is U-Boot image
if header_mn == Header.MAGIC_NUMBER:
header = bytearray(data[offset:offset+Header.SIZE])
header[4:8] = [0]*4
if header_crc == CRC32(header):
if not ignore_crc:
if header_crc == CRC32(header):
break
else:
break
offset += 4

Expand Down Expand Up @@ -675,25 +685,26 @@ def new_img(**kwargs):
return img_obj


def parse_img(data, offset=0):
def parse_img(data, offset=0, ignore_crc=False):
""" Help function for extracting image fom raw data
:param data: The raw data as byte array
:param offset: The offset
:param ignore_crc: Ignore CRC mismatches
:return: Image object
"""
(img_type, offset) = get_img_type(bytearray(data), offset)
(img_type, offset) = get_img_type(bytearray(data), offset, ignore_crc)

if img_type not in EnumImageType:
raise Exception("Not a valid image type")

if img_type == EnumImageType.MULTI:
img = MultiImage.parse(data, offset)
img = MultiImage.parse(data, offset, ignore_crc)
elif img_type == EnumImageType.FIRMWARE:
img = FwImage.parse(data, offset)
img = FwImage.parse(data, offset, ignore_crc)
elif img_type == EnumImageType.SCRIPT:
img = ScriptImage.parse(data, offset)
img = ScriptImage.parse(data, offset, ignore_crc)
else:
img = StdImage.parse(data, offset)
img = StdImage.parse(data, offset, ignore_crc)
img.header.image_type = img_type

return img

0 comments on commit 2c640f2

Please sign in to comment.