コード例 #1
0
 def __init__(self, vdev, os_bptr, dvas=(0,1)):
     self._vdev = vdev
     # Load the object set dnode
     self._dnode = self._load_os_dnode(os_bptr, dvas)
     if self._dnode is None:
         print("[-] Object set dnode is unreachable")
         self._broken = True
         return
     # Compute intermediate properties
     self._indblksize = 1 << self._dnode.indblkshift
     self._datablksize = self._dnode.datablksize
     self._dnodes_per_block = self._datablksize // 512
     self._maxdnodeid = (self._dnode.maxblkid+1)*self._dnodes_per_block - 1
     print("[+] Object set information:")
     print("[+]  dnode", self._dnode)
     print("[+]  block size: indirect {} / data {}".format(self._indblksize, self._datablksize))
     print("[+]  {} blocks / {} dnodes per block".format(self._dnode.maxblkid+1, self._dnodes_per_block))
     self._blocktree = BlockTree(self._dnode.levels, self._vdev, self._dnode.blkptrs[0])
     if self._blocktree is None:
         print("[-]  Object set block tree is broken")
         self._broken = True
         return
     # print("[+] Block pointer 0 is", self._blocktree[0])
     # print("[+] Block pointer {} is {}".format(self._dnode.maxblkid, self._blocktree[self._dnode.maxblkid]))
     self._block_cache = {}
     self._broken = False
コード例 #2
0
 def __init__(self, vdev, dnode, bad_as_zeros=False):
     self._vdev = vdev
     self._bt = BlockTree(dnode.levels, self._vdev, dnode.blkptrs[0])
     self._next_blkid = 0
     self._max_blkid = dnode.maxblkid
     self._datablksize = dnode.datablksize
     self._size = dnode.bonus.zp_size
     self._filepos = 0
     self._blkpos = 0
     self._buf = bytearray()
     self._corrupted = False
     self._bad_as_zeros = bad_as_zeros
コード例 #3
0
    def extract_file(self, file_node_id, target_path, _abspath='undef'):
        print("[+]  Extracting object {} to {}".format(file_node_id,
                                                       target_path))
        file_dnode = self[file_node_id]
        f = open(target_path, "wb")
        f.close()

        if file_dnode.blkptrs[0].empty and file_dnode.bonus.size() > 0:
            f = open("problemfiles.txt", "a")
            f.write("%s\n" % (_abspath))
            f.close()
            print("[+] Cannot extract %s : %s : sz:%d" %
                  (_abspath, str(file_dnode), file_dnode.bonus.size()))
            return False

        bt = BlockTree(file_dnode.levels, self._vdev, file_dnode.blkptrs[0])
        num_blocks = file_dnode.maxblkid + 1
        f = open(target_path, "wb")
        total_len = 0
        corrupted = False
        tt = -time.time()
        if file_dnode.bonus.size() > 0:
            for n in range(num_blocks):
                bp = bt[n]
                bad_block = False
                if bp is None:
                    print("[-]  Broken block tree")
                    bad_block = True
                else:
                    block_data, c = self._vdev.read_block(bp, dva=0)
                    if block_data is None:
                        print("[-]  Unreadable block")
                        bad_block = True
                if bad_block:
                    block_data = b'\x00' * file_dnode.datablksize
                    corrupted = True
                f.write(block_data)
                total_len += len(block_data)
                if n % 16 == 0:
                    print("[+]  Block {:>3}/{} total {:>7} bytes".format(
                        n, num_blocks, total_len))
        tt += time.time()
        if tt == 0.0:
            tt = 1.0  # Prevent division by zero for 0-length files
        data_size = min(total_len, file_dnode.bonus.size())
        f.truncate(data_size)
        f.close()
        print("[+]  {} bytes in {:.3f} s ({:.1f} KiB/s)".format(
            total_len, tt, total_len / (1024 * tt)))
        return not corrupted