예제 #1
0
class BonusDataset:
    def __init__(self, data):
        (self.ds_dir_obj, self.ds_prev_snap_obj, self.ds_prev_snap_txg,
         self.ds_prev_next_obj, self.ds_snapnames_zapobj, self.ds_num_children,
         self.ds_creation_time, self.ds_creation_txg, self.ds_deadlist_obj,
         self.ds_used_bytes, self.ds_compressed_bytes,
         self.ds_uncompressed_bytes, self.ds_unique_bytes, self.ds_fsid_guid,
         self.ds_guid,
         self.ds_restoring) = struct.unpack("=16Q", data[:16 * 8])
        self.bptr = BlockPtr()
        self.bptr.parse(data[16 * 8:16 * 8 + 128])

    def __str__(self):
        fields = [
            'ds_dir_obj', 'ds_prev_snap_obj', 'ds_prev_snap_txg',
            'ds_prev_next_obj', 'ds_snapnames_zapobj', 'ds_num_children',
            'ds_creation_time', 'ds_creation_txg', 'ds_deadlist_obj',
            'ds_used_bytes', 'ds_compressed_bytes', 'ds_uncompressed_bytes',
            'ds_unique_bytes', 'ds_fsid_guid', 'ds_guid', 'ds_restoring',
            'ds_bp'
        ]
        fmt = ' '.join([f + '={}' for f in fields])
        return fmt.format(self.ds_dir_obj, self.ds_prev_snap_obj,
                          self.ds_prev_snap_txg, self.ds_prev_next_obj,
                          self.ds_snapnames_zapobj, self.ds_num_children,
                          self.ds_creation_time, self.ds_creation_txg,
                          self.ds_deadlist_obj, self.ds_used_bytes,
                          self.ds_compressed_bytes, self.ds_uncompressed_bytes,
                          self.ds_unique_bytes, self.ds_fsid_guid,
                          self.ds_guid, self.ds_restoring, self.bptr)
예제 #2
0
 def __init__(self, data):
     (self.ds_dir_obj, self.ds_prev_snap_obj, self.ds_prev_snap_txg, self.ds_prev_next_obj, self.ds_snapnames_zapobj,
      self.ds_num_children, self.ds_creation_time, self.ds_creation_txg, self.ds_deadlist_obj, self.ds_used_bytes,
      self.ds_compressed_bytes, self.ds_uncompressed_bytes, self.ds_unique_bytes, self.ds_fsid_guid, self.ds_guid,
      self.ds_restoring) = struct.unpack("=16Q", data[:16*8])
     self.bptr = BlockPtr()
     self.bptr.parse(data[16*8:16*8+128])
예제 #3
0
 def parse(self, data):
     if len(data) < 512:
         raise ValueError("Data is too small")
     # Save data for dumping purposes
     self._data = data[:]
     (self._type, self._indblkshift, self._nlevels, self._nblkptr,
      self._bonustype, self._checksum, self._compress, self._datablkszsec,
      self._bonuslen, self._maxblkid,
      self._secphys) = struct.unpack("=7Bx2H4xQQ32x", data[:BLKPTR_OFFSET])
     if self._type == 0:
         return
     # Object type > 100 (or even 53) is probably due to data error
     elif self._type > 100:
         self._invalidate()
         return
     self._blkptr = []
     if self._nblkptr > 3:
         # More than three block pointers is a sign of data error
         self._invalidate()
         return
     self._datablksize = self._datablkszsec << 9
     ptr = BLKPTR_OFFSET
     for bn in range(self._nblkptr):
         b = BlockPtr(data=data[ptr:ptr + 128])
         self._blkptr.append(b)
         ptr += 128
     bonus_data = data[ptr:ptr + self._bonuslen]
     if self._bonuslen and self._bonustype == 12:
         self._bonus = BonusDirectory(bonus_data)
     elif self._bonuslen and self._bonustype == 16:
         self._bonus = BonusDataset(bonus_data)
     elif self._bonuslen and self._bonustype == 17:
         self._bonus = BonusZnode(bonus_data)
     else:
         self._bonus = bonus_data
예제 #4
0
 def parse(self, data):
     if len(data) < 512:
         raise ValueError("Data is too small")
     # Save data for dumping purposes
     self._data = data[:]
     (self._type, self._indblkshift, self._nlevels, self._nblkptr,
      self._bonustype, self._checksum, self._compress, self._flags,
      self._datablkszsec, self._bonuslen, self._extra_slots, self._maxblkid,
      self._used) = struct.unpack("=8B2HB3xQQ32x", data[:BLKPTR_OFFSET])
     if self._type == 0:
         return
     # Object type > 100 (or even 53) is probably due to data error
     elif self._type > 100:
         # on linux 196 is "zap with bonustype dataset"
         if self._type==196:
             pass
         else:
             self._invalidate()
             return
     self._blkptr = []
     if self._nblkptr > 3:
         # More than three block pointers is a sign of data error
         self._invalidate()
         return
     self._used = self._used << 9 if not self._flags & DNODE_FLAG_USED_BYTES else self._used;
     self._datablksize = self._datablkszsec << 9
     ptr = BLKPTR_OFFSET
     for bn in range(self._nblkptr):
         b = BlockPtr(data=data[ptr:ptr+128])
         self._blkptr.append(b)
         ptr += 128
     bonus_data = data[ptr:ptr+self._bonuslen]
     if self._bonuslen and self._bonustype == 12:
         self._bonus = BonusDirectory(bonus_data)
     elif self._bonuslen and self._bonustype == 16:
         self._bonus = BonusDataset(bonus_data)
         print("[+] DSL dataset: %s (DSL directory: %d)" %(str(self._bonus), self._bonus.ds_dir_obj))
     elif self._bonuslen and self._bonustype == 17:
         self._bonus = BonusZnode(bonus_data)
     elif self._bonuslen and self._bonustype == 0x2c:
         self._bonus = BonusSysAttr(self._objset, bonus_data)
     else:
         self._bonus = bonus_data
예제 #5
0
 def parse(self, data):
     self._data = bytearray(data)
     (self._magic, self._version, self._txg, self._guid_sum,
      self._timestamp) = struct.unpack("=QQQQQ", data[:5 * 8])
     self._rootbp = BlockPtr(data=data[40:40 + 128])
     self._valid = (self._magic == UBLOCK_MAGIC)