diff --git a/ubireader/ubifs/list.py b/ubireader/ubifs/list.py index bc5a7a6..b7d2c92 100755 --- a/ubireader/ubifs/list.py +++ b/ubireader/ubifs/list.py @@ -20,11 +20,11 @@ import os import time import struct -from ubireader.ubifs.decrypt import lookup_inode_nonce, derive_key_from_nonce, datablock_decrypt, decrypt_symlink_target +from ubireader.ubifs.decrypt import decrypt_symlink_target from ubireader.ubifs.defines import * from ubireader.ubifs import walk -from ubireader.ubifs.misc import decompress -from ubireader.debug import error, log, verbose_log +from ubireader.ubifs.misc import process_reg_file +from ubireader.debug import error def list_files(ubifs, list_path): @@ -88,7 +88,7 @@ def copy_file(ubifs, filepath, destpath): for dent in inodes[inum]['dent']: if dent.name == filename: - filedata = _process_reg_file(ubifs, inodes[dent.inum], filepath, inodes) + filedata = process_reg_file(ubifs, inodes[dent.inum], filepath, inodes) if os.path.isdir(destpath): destpath = os.path.join(destpath, filename) with open(destpath, 'wb') as f: @@ -143,52 +143,3 @@ def file_leng(ubifs, inode): fl = fl + data.size return fl return 0 - - -def _process_reg_file(ubifs, inode, path, inodes): - try: - buf = bytearray() - start_key = (UBIFS_DATA_KEY << UBIFS_S_KEY_BLOCK_BITS) - if 'data' in inode: - compr_type = 0 - sorted_data = sorted(inode['data'], key=lambda x: x.key['khash']) - last_khash = start_key - 1 - - for data in sorted_data: - - # If data nodes are missing in sequence, fill in blanks - # with \x00 * UBIFS_BLOCK_SIZE - if data.key['khash'] - last_khash != 1: - while 1 != (data.key['khash'] - last_khash): - buf += b'\x00' * UBIFS_BLOCK_SIZE - last_khash += 1 - - compr_type = data.compr_type - ubifs.file.seek(data.offset) - d = ubifs.file.read(data.compr_len) - - if ubifs.master_key is not None: - nonce = lookup_inode_nonce(inodes, inode) - block_key = derive_key_from_nonce(ubifs.master_key, nonce) - # block_id is based on the current hash - # there could be empty blocks - block_id = data.key['khash']-start_key - block_iv = struct.pack(" len(buf): - buf += b'\x00' * (inode['ino'].size - len(buf)) - - return bytes(buf) diff --git a/ubireader/ubifs/misc.py b/ubireader/ubifs/misc.py index 2199327..792703c 100755 --- a/ubireader/ubifs/misc.py +++ b/ubireader/ubifs/misc.py @@ -17,11 +17,13 @@ # along with this program. If not, see . ############################################################# -from lzallright import LZOCompressor, LZOError +from lzallright import LZOCompressor import struct import zlib from ubireader.ubifs.defines import * +from ubireader.debug import error, verbose_log from ubireader.debug import error +from ubireader.ubifs.decrypt import lookup_inode_nonce, derive_key_from_nonce, datablock_decrypt # For happy printing ino_types = ['file', 'dir','lnk','blk','chr','fifo','sock'] @@ -74,3 +76,50 @@ def decompress(ctype, unc_len, data): return data +def process_reg_file(ubifs, inode, path, inodes): + try: + buf = bytearray() + start_key = (UBIFS_DATA_KEY << UBIFS_S_KEY_BLOCK_BITS) + if 'data' in inode: + compr_type = 0 + sorted_data = sorted(inode['data'], key=lambda x: x.key['khash']) + last_khash = start_key - 1 + + for data in sorted_data: + # If data nodes are missing in sequence, fill in blanks + # with \x00 * UBIFS_BLOCK_SIZE + if data.key['khash'] - last_khash != 1: + while 1 != (data.key['khash'] - last_khash): + buf += b'\x00' * UBIFS_BLOCK_SIZE + last_khash += 1 + + compr_type = data.compr_type + ubifs.file.seek(data.offset) + d = ubifs.file.read(data.compr_len) + + if ubifs.master_key is not None: + nonce = lookup_inode_nonce(inodes, inode) + block_key = derive_key_from_nonce(ubifs.master_key, nonce) + # block_id is based on the current hash + # there could be empty blocks + block_id = data.key['khash']-start_key + block_iv = struct.pack(" len(buf): + buf += b'\x00' * (inode['ino'].size - len(buf)) + + return bytes(buf) diff --git a/ubireader/ubifs/output.py b/ubireader/ubifs/output.py index 4625eac..349ef58 100755 --- a/ubireader/ubifs/output.py +++ b/ubireader/ubifs/output.py @@ -20,11 +20,11 @@ import os import struct -from ubireader.ubifs.decrypt import lookup_inode_nonce, derive_key_from_nonce, datablock_decrypt, decrypt_symlink_target, decrypt_filenames +from ubireader.ubifs.decrypt import decrypt_symlink_target from ubireader import settings from ubireader.ubifs.defines import * from ubireader.ubifs import walk -from ubireader.ubifs.misc import decompress +from ubireader.ubifs.misc import process_reg_file from ubireader.debug import error, log, verbose_log def is_safe_path(basedir, path): @@ -93,13 +93,13 @@ def extract_dents(ubifs, inodes, dent_node, path='', perms=False): if inode['ino'].nlink > 1: if 'hlink' not in inode: inode['hlink'] = dent_path - buf = _process_reg_file(ubifs, inode, dent_path, inodes) + buf = process_reg_file(ubifs, inode, dent_path, inodes) _write_reg_file(dent_path, buf) else: os.link(inode['hlink'], dent_path) log(extract_dents, 'Make Link: %s > %s' % (dent_path, inode['hlink'])) else: - buf = _process_reg_file(ubifs, inode, dent_path, inodes) + buf = process_reg_file(ubifs, inode, dent_path, inodes) _write_reg_file(dent_path, buf) _set_file_timestamps(dent_path, inode) @@ -174,52 +174,3 @@ def _write_reg_file(path, data): with open(path, 'wb') as f: f.write(data) log(_write_reg_file, 'Make File: %s' % (path)) - - -def _process_reg_file(ubifs, inode, path, inodes): - try: - buf = bytearray() - start_key = (UBIFS_DATA_KEY << UBIFS_S_KEY_BLOCK_BITS) - if 'data' in inode: - compr_type = 0 - sorted_data = sorted(inode['data'], key=lambda x: x.key['khash']) - last_khash = start_key - 1 - - for data in sorted_data: - # If data nodes are missing in sequence, fill in blanks - # with \x00 * UBIFS_BLOCK_SIZE - if data.key['khash'] - last_khash != 1: - while 1 != (data.key['khash'] - last_khash): - buf += b'\x00' * UBIFS_BLOCK_SIZE - last_khash += 1 - - compr_type = data.compr_type - ubifs.file.seek(data.offset) - d = ubifs.file.read(data.compr_len) - - if ubifs.master_key is not None: - nonce = lookup_inode_nonce(inodes, inode) - block_key = derive_key_from_nonce(ubifs.master_key, nonce) - # block_id is based on the current hash - # there could be empty blocks - block_id = data.key['khash']-start_key - block_iv = struct.pack(" len(buf): - buf += b'\x00' * (inode['ino'].size - len(buf)) - - return bytes(buf)