def index(ubifs, lnum, offset, inodes={}, bad_blocks=[]): """Walk the index gathering Inode, Dir Entry, and File nodes. Arguments: Obj:ubifs -- UBIFS object. Int:lnum -- Logical erase block number. Int:offset -- Offset in logical erase block. Dict:inodes -- Dict of ino/dent/file nodes keyed to inode number. Returns: Dict:inodes -- Dict of ino/dent/file nodes keyed to inode number. 'ino' -- Inode node. 'data' -- List of data nodes if present. 'dent' -- List of directory entry nodes if present. """ try: if len(bad_blocks): if lnum in bad_blocks: return ubifs.file.seek((ubifs.leb_size * lnum) + offset) buf = ubifs.file.read(UBIFS_COMMON_HDR_SZ) chdr = nodes.common_hdr(buf) log(index , '%s file addr: %s' % (chdr, ubifs.file.last_read_addr())) verbose_display(chdr) node_buf = ubifs.file.read(chdr.len - UBIFS_COMMON_HDR_SZ) file_offset = ubifs.file.last_read_addr() except Exception, e: if e.message == 'Bad Read Offset Request' and settings.warn_only_block_read_errors: bad_blocks.append(lnum) return else: error(index, 'Fatal', 'LEB: %s, UBIFS offset: %s, error: %s' % (lnum, ((ubifs.leb_size * lnum) + offset), e))
def extract_blocks(ubi): """Get a list of UBI block objects from file Arguments:. Obj:ubi -- UBI object. Returns: Dict -- Of block objects keyed by PEB number. """ blocks = {} ubi.file.seek(ubi.file.start_offset) peb_count = 0 cur_offset = 0 # range instead of xrange, as xrange breaks > 4GB end_offset. for i in range(ubi.file.start_offset, ubi.file.end_offset, ubi.file.block_size): buf = ubi.file.read(ubi.file.block_size) if buf.startswith(UBI_EC_HDR_MAGIC): blk = description(buf) blk.file_offset = i blk.peb_num = ubi.first_peb_num + peb_count blk.size = ubi.file.block_size blocks[blk.peb_num] = blk peb_count += 1 log(extract_blocks, blk) verbose_log(extract_blocks, 'file addr: %s' % (ubi.file.last_read_addr())) verbose_display(blk) else: cur_offset += ubi.file.block_size ubi.first_peb_num = cur_offset/ubi.file.block_size ubi.file.start_offset = cur_offset return blocks
def index(ubifs, lnum, offset, inodes={}): """Walk the index gathering Inode, Dir Entry, and File nodes. Arguments: Obj:ubifs -- UBIFS object. Int:lnum -- Logical erase block number. Int:offset -- Offset in logical erase block. Dict:inodes -- Dict of ino/dent/file nodes keyed to inode number. Returns: Dict:inodes -- Dict of ino/dent/file nodes keyed to inode number. 'ino' -- Inode node. 'data' -- List of data nodes if present. 'dent' -- List of directory entry nodes if present. """ try: ubifs.file.seek((ubifs.leb_size * lnum) + offset) buf = ubifs.file.read(UBIFS_COMMON_HDR_SZ) chdr = nodes.common_hdr(buf) log(index, '%s file addr: %s' % (chdr, ubifs.file.last_read_addr())) verbose_display(chdr) node_buf = ubifs.file.read(chdr.len - UBIFS_COMMON_HDR_SZ) file_offset = ubifs.file.last_read_addr() except Exception, e: error( index, 'Fatal', 'leb: %s, ubifs offset: %s, error: %s' % (lnum, ((ubifs.leb_size * lnum) + offset), e))
def index(ubifs, lnum, offset, inodes={}): """Walk the index gathering Inode, Dir Entry, and File nodes. Arguments: Obj:ubifs -- UBIFS object. Int:lnum -- Logical erase block number. Int:offset -- Offset in logical erase block. Dict:inodes -- Dict of ino/dent/file nodes keyed to inode number. Returns: Dict:inodes -- Dict of ino/dent/file nodes keyed to inode number. 'ino' -- Inode node. 'data' -- List of data nodes if present. 'dent' -- List of directory entry nodes if present. """ try: ubifs.file.seek((ubifs.leb_size * lnum) + offset) buf = ubifs.file.read(UBIFS_COMMON_HDR_SZ) chdr = nodes.common_hdr(buf) log(index , '%s file addr: %s' % (chdr, ubifs.file.last_read_addr())) verbose_display(chdr) node_buf = ubifs.file.read(chdr.len - UBIFS_COMMON_HDR_SZ) file_offset = ubifs.file.last_read_addr() except Exception, e: error(index, 'Fatal', 'leb: %s, ubifs offset: %s, error: %s' % (lnum, ((ubifs.leb_size * lnum) + offset), e))
def extract_blocks(ubi): """Get a list of UBI block objects from file Arguments:. Obj:ubi -- UBI object. Returns: Dict -- Of block objects keyed by PEB number. """ blocks = {} ubi.file.seek(ubi.file.start_offset) peb_count = 0 cur_offset = 0 bad_blocks = [] # range instead of xrange, as xrange breaks > 4GB end_offset. for i in range(ubi.file.start_offset, ubi.file.end_offset, ubi.file.block_size): try: buf = ubi.file.read(ubi.file.block_size) except Exception as e: if settings.warn_only_block_read_errors: error(extract_blocks, 'Error', 'PEB: %s: %s' % (ubi.first_peb_num + peb_count, str(e))) continue else: error(extract_blocks, 'Fatal', 'PEB: %s: %s' % (ubi.first_peb_num + peb_count, str(e))) if buf.startswith(UBI_EC_HDR_MAGIC): blk = description(buf) blk.file_offset = i blk.peb_num = ubi.first_peb_num + peb_count blk.size = ubi.file.block_size blocks[blk.peb_num] = blk peb_count += 1 log(extract_blocks, blk) verbose_log(extract_blocks, 'file addr: %s' % (ubi.file.last_read_addr())) ec_hdr_errors = '' vid_hdr_errors = '' if blk.ec_hdr.errors: ec_hdr_errors = ','.join(blk.ec_hdr.errors) if blk.vid_hdr and blk.vid_hdr.errors: vid_hdr_errors = ','.join(blk.vid_hdr.errors) if ec_hdr_errors or vid_hdr_errors: if blk.peb_num not in bad_blocks: bad_blocks.append(blk.peb_num) log(extract_blocks, 'PEB: %s has possible issue EC_HDR [%s], VID_HDR [%s]' % (blk.peb_num, ec_hdr_errors, vid_hdr_errors)) verbose_display(blk) else: cur_offset += ubi.file.block_size ubi.first_peb_num = cur_offset/ubi.file.block_size ubi.file.start_offset = cur_offset return blocks
def __init__(self, ubifs_file): self.__name__ = 'UBIFS' self._file = ubifs_file try: self.file.reset() sb_chdr = nodes.common_hdr(self.file.read(UBIFS_COMMON_HDR_SZ)) log(self, '%s file addr: %s' % (sb_chdr, self.file.last_read_addr())) verbose_display(sb_chdr) if sb_chdr.node_type == UBIFS_SB_NODE: self.file.seek(UBIFS_COMMON_HDR_SZ) buf = self.file.read(UBIFS_SB_NODE_SZ) self._sb_node = nodes.sb_node(buf) self._min_io_size = self._sb_node.min_io_size self._leb_size = self._sb_node.leb_size log( self, '%s file addr: %s' % (self._sb_node, self.file.last_read_addr())) verbose_display(self._sb_node) else: raise Exception('Wrong node type.') except Exception as e: error(self, 'Fatal', 'Super block error: %s' % e) self._mst_nodes = [None, None] for i in range(0, 2): try: mst_offset = self.leb_size * (UBIFS_MST_LNUM + i) while True: try: self.file.seek(mst_offset) mst_chdr = nodes.common_hdr( self.file.read(UBIFS_COMMON_HDR_SZ)) log( self, '%s file addr: %s' % (mst_chdr, self.file.last_read_addr())) verbose_display(mst_chdr) if mst_chdr.node_type == UBIFS_MST_NODE: self.file.seek(mst_offset + UBIFS_COMMON_HDR_SZ) buf = self.file.read(UBIFS_MST_NODE_SZ) self._mst_nodes[i] = nodes.mst_node(buf) log( self, '%s%s file addr: %s' % (self._mst_nodes[i], i, self.file.last_read_addr())) verbose_display(self._mst_nodes[i]) else: raise Exception('Wrong node type.') mst_offset += 0x1000 except: break except Exception as e: error(self, 'Fatal', 'Master block %s error: %s' % (i, e)) if not self._mst_nodes[0] or not self._mst_nodes[1]: error(self, 'Fatal', 'Less than 2 Master blocks found.')
def __init__(self, ubifs_file): self.__name__ = 'UBIFS' self._file = ubifs_file try: self.file.reset() sb_chdr = nodes.common_hdr(self.file.read(UBIFS_COMMON_HDR_SZ)) log(self, '%s file addr: %s' % (sb_chdr, self.file.last_read_addr())) verbose_display(sb_chdr) if sb_chdr.node_type == UBIFS_SB_NODE: self.file.seek(UBIFS_COMMON_HDR_SZ) buf = self.file.read(UBIFS_SB_NODE_SZ) self._sb_node = nodes.sb_node(buf, self.file.last_read_addr()) self._min_io_size = self._sb_node.min_io_size self._leb_size = self._sb_node.leb_size log( self, '%s file addr: %s' % (self._sb_node, self.file.last_read_addr())) verbose_display(self._sb_node) else: raise Exception('Wrong node type.') except Exception as e: error(self, 'Fatal', 'Super block error: %s' % e) self._mst_nodes = [None, None] for i in range(0, 2): try: mst_offset = self.leb_size * (UBIFS_MST_LNUM + i) self.file.seek(mst_offset) mst_chdr = nodes.common_hdr( self.file.read(UBIFS_COMMON_HDR_SZ)) log( self, '%s file addr: %s' % (mst_chdr, self.file.last_read_addr())) verbose_display(mst_chdr) if mst_chdr.node_type == UBIFS_MST_NODE: self.file.seek(mst_offset + UBIFS_COMMON_HDR_SZ) buf = self.file.read(UBIFS_MST_NODE_SZ) self._mst_nodes[i] = nodes.mst_node( buf, self.file.last_read_addr()) log( self, '%s%s file addr: %s' % (self._mst_nodes[i], i, self.file.last_read_addr())) verbose_display(self._mst_nodes[i]) else: raise Exception('Wrong node type.') except Exception as e: error(self, 'Warn', 'Master block %s error: %s' % (i, e)) if self._mst_nodes[0] is None and self._mst_nodes[1] is None: error(self, 'Fatal', 'No valid Master Node found.') elif self._mst_nodes[0] is None and self._mst_nodes[1] is not None: self._mst_nodes[0] = self._mst_nodes[1] self._mst_nodes[1] = None log(self, 'Swapping Master Nodes due to bad first node.')
def __init__(self, ubifs_file): self.__name__ = 'UBIFS' self._file = ubifs_file try: self.file.reset() sb_chdr = nodes.common_hdr(self.file.read(UBIFS_COMMON_HDR_SZ)) log(self , '%s file addr: %s' % (sb_chdr, self.file.last_read_addr())) verbose_display(sb_chdr) if sb_chdr.node_type == UBIFS_SB_NODE: self.file.seek(UBIFS_COMMON_HDR_SZ) buf = self.file.read(UBIFS_SB_NODE_SZ) self._sb_node = nodes.sb_node(buf) self._min_io_size = self._sb_node.min_io_size self._leb_size = self._sb_node.leb_size log(self , '%s file addr: %s' % (self._sb_node, self.file.last_read_addr())) verbose_display(self._sb_node) else: raise Exception('Wrong node type.') except Exception, e: error(self, 'Fatal', 'Super block error: %s' % e)
def extract_blocks(ubi): """Get a list of UBI block objects from file Arguments:. Obj:ubi -- UBI object. Returns: Dict -- Of block objects keyed by PEB number. """ blocks = {} ubi.file.seek(ubi.file.start_offset) peb_count = 0 cur_offset = 0 # range instead of xrange, as xrange breaks > 4GB end_offset. for i in range(ubi.file.start_offset, ubi.file.end_offset, ubi.file.block_size): buf = ubi.file.read(ubi.file.block_size) if buf.startswith(UBI_EC_HDR_MAGIC): blk = description(buf) blk.file_offset = i blk.peb_num = ubi.first_peb_num + peb_count blk.size = ubi.file.block_size blocks[blk.peb_num] = blk peb_count += 1 log(extract_blocks, blk) verbose_log(extract_blocks, 'file addr: %s' % (ubi.file.last_read_addr())) verbose_display(blk) else: cur_offset += ubi.file.block_size ubi.first_peb_num = cur_offset / ubi.file.block_size ubi.file.start_offset = cur_offset return blocks
def __init__(self, ubifs_file): self.__name__ = 'UBIFS' self._file = ubifs_file try: self.file.reset() sb_chdr = nodes.common_hdr(self.file.read(UBIFS_COMMON_HDR_SZ)) log(self, '%s file addr: %s' % (sb_chdr, self.file.last_read_addr())) verbose_display(sb_chdr) if sb_chdr.node_type == UBIFS_SB_NODE: self.file.seek(UBIFS_COMMON_HDR_SZ) buf = self.file.read(UBIFS_SB_NODE_SZ) self._sb_node = nodes.sb_node(buf) self._min_io_size = self._sb_node.min_io_size self._leb_size = self._sb_node.leb_size log( self, '%s file addr: %s' % (self._sb_node, self.file.last_read_addr())) verbose_display(self._sb_node) else: raise Exception('Wrong node type.') except Exception, e: error(self, 'Fatal', 'Super block error: %s' % e)
def __init__(self, ubifs_file): self.__name__ = 'UBIFS' self._file = ubifs_file try: self.file.reset() sb_chdr = nodes.common_hdr(self.file.read(UBIFS_COMMON_HDR_SZ)) log(self , '%s file addr: %s' % (sb_chdr, self.file.last_read_addr())) verbose_display(sb_chdr) if sb_chdr.node_type == UBIFS_SB_NODE: self.file.seek(UBIFS_COMMON_HDR_SZ) buf = self.file.read(UBIFS_SB_NODE_SZ) self._sb_node = nodes.sb_node(buf) self._min_io_size = self._sb_node.min_io_size self._leb_size = self._sb_node.leb_size log(self , '%s file addr: %s' % (self._sb_node, self.file.last_read_addr())) verbose_display(self._sb_node) else: raise Exception('Wrong node type.') except Exception as e: error(self, 'Fatal', 'Super block error: %s' % e) self._mst_nodes = [None, None] for i in range(0, 2): try: mst_offset = self.leb_size * (UBIFS_MST_LNUM + i) self.file.seek(mst_offset) mst_chdr = nodes.common_hdr(self.file.read(UBIFS_COMMON_HDR_SZ)) log(self , '%s file addr: %s' % (mst_chdr, self.file.last_read_addr())) verbose_display(mst_chdr) if mst_chdr.node_type == UBIFS_MST_NODE: self.file.seek(mst_offset + UBIFS_COMMON_HDR_SZ) buf = self.file.read(UBIFS_MST_NODE_SZ) self._mst_nodes[i] = nodes.mst_node(buf) log(self , '%s%s file addr: %s' % (self._mst_nodes[i], i, self.file.last_read_addr())) verbose_display(self._mst_nodes[i]) else: raise Exception('Wrong node type.') except Exception as e: error(self, 'Fatal', 'Master block %s error: %s' % (i, e)) if not self._mst_nodes[0] or not self._mst_nodes[1]: error(self, 'Fatal', 'Less than 2 Master blocks found.')
def index(ubifs, lnum, offset, inodes={}, bad_blocks=[]): """Walk the index gathering Inode, Dir Entry, and File nodes. Arguments: Obj:ubifs -- UBIFS object. Int:lnum -- Logical erase block number. Int:offset -- Offset in logical erase block. Dict:inodes -- Dict of ino/dent/file nodes keyed to inode number. Returns: Dict:inodes -- Dict of ino/dent/file nodes keyed to inode number. 'ino' -- Inode node. 'data' -- List of data nodes if present. 'dent' -- List of directory entry nodes if present. """ try: if len(bad_blocks): if lnum in bad_blocks: return ubifs.file.seek((ubifs.leb_size * lnum) + offset) buf = ubifs.file.read(UBIFS_COMMON_HDR_SZ) chdr = nodes.common_hdr(buf) log(index , '%s file addr: %s' % (chdr, ubifs.file.last_read_addr())) verbose_display(chdr) node_buf = ubifs.file.read(chdr.len - UBIFS_COMMON_HDR_SZ) file_offset = ubifs.file.last_read_addr() except Exception as e: if str(e) == 'Bad Read Offset Request' and settings.warn_only_block_read_errors: bad_blocks.append(lnum) return else: error(index, 'Fatal', 'LEB: %s, UBIFS offset: %s, error: %s' % (lnum, ((ubifs.leb_size * lnum) + offset), e)) if chdr.node_type == UBIFS_IDX_NODE: try: idxn = nodes.idx_node(node_buf) except Exception as e: if settings.warn_only_block_read_errors: error(index, 'Error', 'Problem at file address: %s extracting idx_node: %s' % (file_offset, e)) return else: error(index, 'Fatal', 'Problem at file address: %s extracting idx_node: %s' % (file_offset, e)) log(index, '%s file addr: %s' % (idxn, file_offset)) verbose_display(idxn) branch_idx = 0 for branch in idxn.branches: verbose_log(index, '-------------------') log(index, '%s file addr: %s' % (branch, file_offset + UBIFS_IDX_NODE_SZ + (branch_idx * UBIFS_BRANCH_SZ))) verbose_display(branch) index(ubifs, branch.lnum, branch.offs, inodes, bad_blocks) branch_idx += 1 elif chdr.node_type == UBIFS_INO_NODE: try: inon = nodes.ino_node(node_buf) except Exception as e: if settings.warn_only_block_read_errors: error(index, 'Error', 'Problem at file address: %s extracting ino_node: %s' % (file_offset, e)) return else: error(index, 'Fatal', 'Problem at file address: %s extracting ino_node: %s' % (file_offset, e)) ino_num = inon.key['ino_num'] log(index, '%s file addr: %s, ino num: %s' % (inon, file_offset, ino_num)) verbose_display(inon) if not ino_num in inodes: inodes[ino_num] = {} inodes[ino_num]['ino'] = inon elif chdr.node_type == UBIFS_DATA_NODE: try: datn = nodes.data_node(node_buf, (ubifs.leb_size * lnum) + UBIFS_COMMON_HDR_SZ + offset + UBIFS_DATA_NODE_SZ) except Exception as e: if settings.warn_only_block_read_errors: error(index, 'Error', 'Problem at file address: %s extracting data_node: %s' % (file_offset, e)) return else: error(index, 'Fatal', 'Problem at file address: %s extracting data_node: %s' % (file_offset, e)) ino_num = datn.key['ino_num'] log(index, '%s file addr: %s, ino num: %s' % (datn, file_offset, ino_num)) verbose_display(datn) if not ino_num in inodes: inodes[ino_num] = {} if not 'data' in inodes[ino_num]: inodes[ino_num]['data']= [] inodes[ino_num]['data'].append(datn) elif chdr.node_type == UBIFS_DENT_NODE: try: dn = nodes.dent_node(node_buf) except Exception as e: if settings.warn_only_block_read_errors: error(index, 'Error', 'Problem at file address: %s extracting dent_node: %s' % (file_offset, e)) return else: error(index, 'Fatal', 'Problem at file address: %s extracting dent_node: %s' % (file_offset, e)) ino_num = dn.key['ino_num'] log(index, '%s file addr: %s, ino num: %s' % (dn, file_offset, ino_num)) verbose_display(dn) if not ino_num in inodes: inodes[ino_num] = {} if not 'dent' in inodes[ino_num]: inodes[ino_num]['dent']= [] inodes[ino_num]['dent'].append(dn)
class ubifs(): """UBIFS object Arguments: Str:path -- File path to UBIFS image. Attributes: Obj:file -- File object Int:leb_size -- Size of Logical Erase Blocks. Int:min_io -- Size of min I/O from vid_hdr_offset. Obj:sb_node -- Superblock node of UBIFS image LEB0 Obj:mst_node -- Master Node of UBIFS image LEB1 Obj:mst_node2 -- Master Node 2 of UBIFS image LEB2 """ def __init__(self, ubifs_file): self.__name__ = 'UBIFS' self._file = ubifs_file try: self.file.reset() sb_chdr = nodes.common_hdr(self.file.read(UBIFS_COMMON_HDR_SZ)) log(self, '%s file addr: %s' % (sb_chdr, self.file.last_read_addr())) verbose_display(sb_chdr) if sb_chdr.node_type == UBIFS_SB_NODE: self.file.seek(UBIFS_COMMON_HDR_SZ) buf = self.file.read(UBIFS_SB_NODE_SZ) self._sb_node = nodes.sb_node(buf) self._min_io_size = self._sb_node.min_io_size self._leb_size = self._sb_node.leb_size log( self, '%s file addr: %s' % (self._sb_node, self.file.last_read_addr())) verbose_display(self._sb_node) else: raise Exception('Wrong node type.') except Exception, e: error(self, 'Fatal', 'Super block error: %s' % e) self._mst_nodes = [None, None] for i in xrange(0, 2): try: mst_offset = self.leb_size * (UBIFS_MST_LNUM + i) self.file.seek(mst_offset) mst_chdr = nodes.common_hdr( self.file.read(UBIFS_COMMON_HDR_SZ)) log( self, '%s file addr: %s' % (mst_chdr, self.file.last_read_addr())) verbose_display(mst_chdr) if mst_chdr.node_type == UBIFS_MST_NODE: self.file.seek(mst_offset + UBIFS_COMMON_HDR_SZ) buf = self.file.read(UBIFS_MST_NODE_SZ) self._mst_nodes[i] = nodes.mst_node(buf) log( self, '%s%s file addr: %s' % (self._mst_nodes[i], i, self.file.last_read_addr())) verbose_display(self._mst_nodes[i]) else: raise Exception('Wrong node type.') except Exception, e: error(self, 'Fatal', 'Master block %s error: %s' % (i, e))
error(index, 'Fatal', 'LEB: %s, UBIFS offset: %s, error: %s' % (lnum, ((ubifs.leb_size * lnum) + offset), e)) if chdr.node_type == UBIFS_IDX_NODE: try: idxn = nodes.idx_node(node_buf) except Exception as e: if settings.warn_only_block_read_errors: error(index, 'Error', 'Problem at file address: %s extracting idx_node: %s' % (file_offset, e)) return else: error(index, 'Fatal', 'Problem at file address: %s extracting idx_node: %s' % (file_offset, e)) log(index, '%s file addr: %s' % (idxn, file_offset)) verbose_display(idxn) branch_idx = 0 for branch in idxn.branches: verbose_log(index, '-------------------') log(index, '%s file addr: %s' % (branch, file_offset + UBIFS_IDX_NODE_SZ + (branch_idx * UBIFS_BRANCH_SZ))) verbose_display(branch) index(ubifs, branch.lnum, branch.offs, inodes, bad_blocks) branch_idx += 1 elif chdr.node_type == UBIFS_INO_NODE: try: inon = nodes.ino_node(node_buf) except Exception as e: if settings.warn_only_block_read_errors:
buf = ubifs.file.read(UBIFS_COMMON_HDR_SZ) chdr = nodes.common_hdr(buf) log(index , '%s file addr: %s' % (chdr, ubifs.file.last_read_addr())) verbose_display(chdr) node_buf = ubifs.file.read(chdr.len - UBIFS_COMMON_HDR_SZ) file_offset = ubifs.file.last_read_addr() except Exception, e: error(index, 'Fatal', 'leb: %s, ubifs offset: %s, error: %s' % (lnum, ((ubifs.leb_size * lnum) + offset), e)) if chdr.node_type == UBIFS_IDX_NODE: idxn = nodes.idx_node(node_buf) log(index, '%s file addr: %s' % (idxn, file_offset)) verbose_display(idxn) branch_idx = 0 for branch in idxn.branches: verbose_log(index, '-------------------') log(index, '%s file addr: %s' % (branch, file_offset + UBIFS_IDX_NODE_SZ + (branch_idx * UBIFS_BRANCH_SZ))) verbose_display(branch) index(ubifs, branch.lnum, branch.offs, inodes) branch_idx += 1 elif chdr.node_type == UBIFS_INO_NODE: inon = nodes.ino_node(node_buf) ino_num = inon.key['ino_num'] log(index, '%s file addr: %s, ino num: %s' % (inon, file_offset, ino_num)) verbose_display(inon)
def index(ubifs, lnum, offset, inodes={}): """Walk the index gathering Inode, Dir Entry, and File nodes. Arguments: Obj:ubifs -- UBIFS object. Int:lnum -- Logical erase block number. Int:offset -- Offset in logical erase block. Dict:inodes -- Dict of ino/dent/file nodes keyed to inode number. Returns: Dict:inodes -- Dict of ino/dent/file nodes keyed to inode number. 'ino' -- Inode node. 'data' -- List of data nodes if present. 'dent' -- List of directory entry nodes if present. """ try: ubifs.file.seek((ubifs.leb_size * lnum) + offset) buf = ubifs.file.read(UBIFS_COMMON_HDR_SZ) chdr = nodes.common_hdr(buf) log(index, '%s file addr: %s' % (chdr, ubifs.file.last_read_addr())) verbose_display(chdr) node_buf = ubifs.file.read(chdr.len - UBIFS_COMMON_HDR_SZ) file_offset = ubifs.file.last_read_addr() except Exception as e: error( index, 'Fatal', 'leb: %s, ubifs offset: %s, error: %s' % (lnum, ((ubifs.leb_size * lnum) + offset), e)) if chdr.node_type == UBIFS_IDX_NODE: idxn = nodes.idx_node(node_buf) log(index, '%s file addr: %s' % (idxn, file_offset)) verbose_display(idxn) branch_idx = 0 for branch in idxn.branches: verbose_log(index, '-------------------') log( index, '%s file addr: %s' % (branch, file_offset + UBIFS_IDX_NODE_SZ + (branch_idx * UBIFS_BRANCH_SZ))) verbose_display(branch) index(ubifs, branch.lnum, branch.offs, inodes) branch_idx += 1 elif chdr.node_type == UBIFS_INO_NODE: inon = nodes.ino_node(node_buf) ino_num = inon.key['ino_num'] log(index, '%s file addr: %s, ino num: %s' % (inon, file_offset, ino_num)) verbose_display(inon) if not ino_num in inodes: inodes[ino_num] = {} inodes[ino_num]['ino'] = inon elif chdr.node_type == UBIFS_DATA_NODE: datn = nodes.data_node(node_buf, (ubifs.leb_size * lnum) + UBIFS_COMMON_HDR_SZ + offset + UBIFS_DATA_NODE_SZ) ino_num = datn.key['ino_num'] log(index, '%s file addr: %s, ino num: %s' % (datn, file_offset, ino_num)) verbose_display(datn) if not ino_num in inodes: inodes[ino_num] = {} if not 'data' in inodes[ino_num]: inodes[ino_num]['data'] = [] inodes[ino_num]['data'].append(datn) elif chdr.node_type == UBIFS_DENT_NODE: dn = nodes.dent_node(node_buf) ino_num = dn.key['ino_num'] log(index, '%s file addr: %s, ino num: %s' % (dn, file_offset, ino_num)) verbose_display(dn) if not ino_num in inodes: inodes[ino_num] = {} if not 'dent' in inodes[ino_num]: inodes[ino_num]['dent'] = [] inodes[ino_num]['dent'].append(dn)