예제 #1
0
def create_output_dir(outpath):
    if not os.path.exists(outpath):
        try:
            os.makedirs(outpath)
            log(create_output_dir, 'Created output path: %s' % outpath)
        except Exception, e:
            error(create_output_dir, 'Fatal', '%s' % e)
예제 #2
0
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))
예제 #3
0
파일: layout.py 프로젝트: blueguy/bat
def group_pairs(blocks, layout_blocks_list):
    """Sort a list of layout blocks into pairs

    Arguments:
    List:blocks        -- List of block objects
    List:layout_blocks -- List of layout block indexes

    Returns:
    List -- Layout block pair indexes grouped in a list
    """
    try:
        layouts_grouped = [[blocks[layout_blocks_list[0]].peb_num]]

        for l in layout_blocks_list[1:]:
            for lnd in layouts_grouped:
                if blocks[l].vtbl_recs[0].name == blocks[
                        lnd[0]].vtbl_recs[0].name:
                    lnd.append(blocks[l].peb_num)
                    break
            else:
                layouts_grouped.append([blocks[l].peb_num])

        log(group_pairs, layouts_grouped)
        return layouts_grouped
    except Exception, e:
        error(group_pairs, 'Fatal', e)
예제 #4
0
def create_output_dir(outpath):
    if not os.path.exists(outpath):
        try:
            os.makedirs(outpath)
            log(create_output_dir, 'Created output path: %s' % outpath)
        except Exception, e:
            error(create_output_dir, 'Fatal', '%s' % e)
예제 #5
0
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
예제 #6
0
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', 'buf read, %s' % (e))
예제 #7
0
def group_pairs(blocks, layout_blocks_list):
    """Sort a list of layout blocks into pairs

    Arguments:
    List:blocks        -- List of block objects
    List:layout_blocks -- List of layout block indexes

    Returns:
    List -- Layout block pair indexes grouped in a list
    """
    try:
        layouts_grouped = [[blocks[layout_blocks_list[0]].peb_num]]

        for l in layout_blocks_list[1:]:
            for lnd in layouts_grouped:
                if blocks[l].vtbl_recs[0].name == blocks[lnd[0]].vtbl_recs[0].name:
                    lnd.append(blocks[l].peb_num)
                    break
            else:
                    layouts_grouped.append([blocks[l].peb_num])

        log(group_pairs, layouts_grouped)
        return layouts_grouped
    except Exception, e:
        error(group_pairs, 'Fatal', e)
예제 #8
0
 def __init__(self, path, block_size, start_offset=0, end_offset=None):
     self.__name__ = 'UBI_File'
     self.is_valid = False
     try:
         log(self, 'Open Path: %s' % path)
         self._fhandle = open(path, 'rb')
     except Exception, e:
         error(self, 'Fatal', 'Open file: %s' % e)
예제 #9
0
파일: __init__.py 프로젝트: blueguy/bat
 def __init__(self, vol_id, vol_rec, block_list):
     self._vol_id = vol_id
     self._vol_rec = vol_rec
     self._name = self._vol_rec.name
     self._block_list = block_list
     log(
         description, 'Create Volume: %s, ID: %s, Block Cnt: %s' %
         (self.name, self.vol_id, len(self.block_list)))
예제 #10
0
 def __init__(self, path, block_size, start_offset=0, end_offset=None):
     self.__name__ = 'UBI_File'
     self.is_valid = False
     try:
         log(self, 'Open Path: %s' % path)
         self._fhandle = open(path, 'rb')
     except Exception, e:
         error(self, 'Fatal', 'Open file: %s' % e)
예제 #11
0
def create_output_dir(outpath):
    if os.path.exists(outpath):
        if os.listdir(outpath):
            error(create_output_dir, 'Fatal', 'Output directory is not empty. %s' % outpath)
    else:
        try:
            os.makedirs(outpath)
            log(create_output_dir, 'Created output path: %s' % outpath)
        except Exception, e:
            error(create_output_dir, 'Fatal', '%s' % e)
예제 #12
0
파일: __init__.py 프로젝트: blueguy/bat
 def __init__(self, blocks, layout_info):
     self._image_seq = blocks[layout_info[0]].ec_hdr.image_seq
     self.vid_hdr_offset = blocks[layout_info[0]].ec_hdr.vid_hdr_offset
     self.version = blocks[layout_info[0]].ec_hdr.version
     self._block_list = layout_info[2]
     self._start_peb = min(layout_info[2])
     self._end_peb = max(layout_info[2])
     self._volumes = get_volumes(blocks, layout_info)
     log(
         description, 'Created Image: %s, Volume Cnt: %s' %
         (self.image_seq, len(self.volumes)))
예제 #13
0
def create_output_dir(outpath):
    if os.path.exists(outpath):
        if os.listdir(outpath):
            error(create_output_dir, 'Fatal',
                  'Output directory is not empty. %s' % outpath)
    else:
        try:
            os.makedirs(outpath)
            log(create_output_dir, 'Created output path: %s' % outpath)
        except Exception, e:
            error(create_output_dir, 'Fatal', '%s' % e)
예제 #14
0
파일: utils.py 프로젝트: blueguy/bat
def guess_filetype(path, start_offset=0):
    with open(path, 'rb') as f:
        f.seek(start_offset)
        buf = f.read(4)

        if buf == UBI_EC_HDR_MAGIC:
            ftype = UBI_EC_HDR_MAGIC
            log(guess_filetype, 'File looks like a UBI image.')

        elif buf == UBIFS_NODE_MAGIC:
            ftype = UBIFS_NODE_MAGIC
            log(guess_filetype, 'File looks like a UBIFS image.')
        else:
            ftype = None
            error(guess_filetype, 'Fatal', 'Could not determine file type.')

    return ftype
예제 #15
0
def guess_filetype(path, start_offset=0):
    with open(path, 'rb') as f:
        f.seek(start_offset)
        buf = f.read(4)

        if buf == UBI_EC_HDR_MAGIC:
            ftype = UBI_EC_HDR_MAGIC
            log(guess_filetype, 'File looks like a UBI image.')

        elif buf == UBIFS_NODE_MAGIC:
            ftype = UBIFS_NODE_MAGIC
            log(guess_filetype, 'File looks like a UBIFS image.')
        else:
            ftype = None
            error(guess_filetype, 'Fatal', 'Could not determine file type.')
    
    return ftype
예제 #16
0
def extract_dents(ubifs, inodes, dent_node, path='', perms=False):
    inode = inodes[dent_node.inum]
    dent_path = os.path.join(path, dent_node.name)

    if dent_node.type == UBIFS_ITYPE_DIR:
        try:
            if not os.path.exists(dent_path):
                os.mkdir(dent_path)
                log(extract_dents, 'Make Dir: %s' % (dent_path))

                if perms:
                    _set_file_perms(dent_path, inode)
        except Exception, e:
            error(extract_dents, 'Warn', 'DIR Fail: %s' % e)

        if 'dent' in inode:
            for dnode in inode['dent']:
                extract_dents(ubifs, inodes, dnode, dent_path, perms)
예제 #17
0
    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)
예제 #18
0
파일: __init__.py 프로젝트: blueguy/bat
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
예제 #19
0
파일: __init__.py 프로젝트: blueguy/bat
    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)
예제 #20
0
        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)
예제 #21
0
class ubi_file(object):
    """UBI image file object

    Arguments:
    Str:path         -- Path to file to parse
    Int:block_size   -- Erase block size of NAND in bytes.
    Int:start_offset -- (optional) Where to start looking in the file for
                        UBI data.
    Int:end_offset   -- (optional) Where to stop looking in the file.
    
    Methods:
    seek            -- Put file head to specified byte offset.
        Int:offset
    read            -- Read specified bytes from file handle.
        Int:size
    tell            -- Returns byte offset of current file location.
    read_block      -- Returns complete PEB data of provided block
                       description.
        Obj:block
    read_block_data -- Returns LEB data only from provided block.
        Obj:block
    reader          -- Generator that returns data from file.
    reset           -- Reset file position to start_offset.
    is_valid        -- If the object intialized okay.

    Handles all the actual file interactions, read, seek,
    extract blocks, etc.
    """
    def __init__(self, path, block_size, start_offset=0, end_offset=None):
        self.__name__ = 'UBI_File'
        self.is_valid = False
        try:
            log(self, 'Open Path: %s' % path)
            self._fhandle = open(path, 'rb')
        except Exception, e:
            error(self, 'Fatal', 'Open file: %s' % e)

        self._fhandle.seek(0, 2)
        file_size = self.tell()
        log(self, 'File Size: %s' % file_size)

        self._start_offset = start_offset
        log(self, 'Start Offset: %s' % (self._start_offset))

        if end_offset:
            self._end_offset = end_offset
        else:
            self._end_offset = file_size
        log(self, 'End Offset: %s' % (self._end_offset))

        self._block_size = block_size
        log(self, 'Block Size: %s' % block_size)

        if start_offset > self._end_offset:
            error(self, 'Fatal', 'Start offset larger than end offset.')

        if end_offset > file_size:
            error(self, 'Fatal', 'End offset larger than file size.')

        self._fhandle.seek(self._start_offset)
        self._last_read_addr = self._fhandle.tell()
        self.is_valid = True
예제 #22
0
def _write_reg_file(path, data):
    with open(path, 'wb') as f:
        f.write(data)
    log(_write_reg_file, 'Make File: %s' % (path))
예제 #23
0
            error(extract_dents, 'Warn', 'DIR Fail: %s' % e)

        if 'dent' in inode:
            for dnode in inode['dent']:
                extract_dents(ubifs, inodes, dnode, dent_path, perms)

    elif dent_node.type == UBIFS_ITYPE_REG:
        try:
            if inode['ino'].nlink > 1:
                if 'hlink' not in inode:
                    inode['hlink'] = dent_path
                    buf = _process_reg_file(ubifs, inode, dent_path)
                    _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)
                _write_reg_file(dent_path, buf)

            if perms:
                _set_file_perms(dent_path, inode)

        except Exception, e:
            error(extract_dents, 'Warn', 'FILE Fail: %s' % e)

    elif dent_node.type == UBIFS_ITYPE_LNK:
        try:
            # probably will need to decompress ino data if > UBIFS_MIN_COMPR_LEN
            os.symlink('%s' % inode['ino'].data, dent_path)
            log(extract_dents,
예제 #24
0
 def __init__(self, vol_id, vol_rec, block_list):
     self._vol_id = vol_id
     self._vol_rec = vol_rec
     self._name = self._vol_rec.name
     self._block_list = block_list
     log(description, 'Create Volume: %s, ID: %s, Block Cnt: %s' % (self.name, self.vol_id, len(self.block_list)))
예제 #25
0
파일: __init__.py 프로젝트: blueguy/bat
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))
예제 #26
0
        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', 'buf read, %s' % (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)