def inherit(self, parent): Dnode.inherit(self, parent) try: data = self.pool.read_block(self, 0) self.zap_type, = struct.unpack("<Q", data[:8]) if self.zap_type == ZAPObj.ZBT_HEADER: self.fatzap = FatZAP.frombytes(data) self.fatzap.pool = self.pool self.fatzap.obj = self elif self.zap_type == ZAPObj.ZBT_MICRO: self.microzap = MicroZAP.frombytes(data) self.microzap.pool = self.pool else: print("Unknown zap type " + str(self.zap_type)) except: print("Read zap header failed") self.zap_type = 0
def read_object(self, objid): blkid = objid * Dnode.SIZE // (self.metadnode.datablkszsec * 512) dnode = self.pool.read_block(self.metadnode, blkid) dnode = dnode[objid * Dnode.SIZE % (self.metadnode.datablkszsec * 512):] dnode = dnode[:Dnode.SIZE] dnode = Dnode.frombytes(dnode, self.pool) return dnode
def scan(): ashift = raiddev.ashift i = 0 while i < 9 * 1024 * 1024 * 1024 * 1024 >> ashift: if (i << ashift) % (1024 * 1024 * 1024) == 0: print("Scanned %d GB" % ((i << ashift) // (1024 * 1024 * 1024))) print("Hit rate 1: %f%%" % v1.get_hit_rate()) print("Hit rate 2: %f%%" % v2.get_hit_rate()) print("Hit rate 3: %f%%" % v3.get_hit_rate()) v1.clear_hit_rate() v2.clear_hit_rate() v3.clear_hit_rate() block = raiddev.read(i << ashift, 1 << ashift) input_size, = struct.unpack_from(">I", block) if input_size > 128 * 1024: i += 1 continue block = raiddev.read(i << ashift, 4 + input_size) try: block = lz4_decompress(block) except: i += 1 continue try: print("Found at 0x%x" % (i << ashift)) for j in range(len(block) // Dnode.SIZE): dnode = Dnode.frombytes( block[j * Dnode.SIZE:(j + 1) * Dnode.SIZE], pool) if dnode.type != 0 and dnode.type < len( dmu_constant.TYPES) and dmu_constant.TYPES[ dnode.type] != None: print(" [%d]: %s" % (j, dmu_constant.TYPES[dnode.type])) if dnode.type == 20: print(dnode.list()) elif dnode.type == 19: print(" filelen: %d" % (dnode.secphys if (dnode.flags & 1 != 0) else (dnode.secphys * 512))) for j in range(len(block) // BlkPtr.SIZE): ptr = BlkPtr.frombytes(block[j * BlkPtr.SIZE:(j + 1) * BlkPtr.SIZE]) if ptr.embedded and ptr.etype == BlkPtr.ETYPE_DATA: print(" [%d]: %s" % (j, dmu_constant.TYPES[dnode.type])) elif not ptr.embedded and ptr.dva[0].vdev == 0 and ptr.dva[ 0].offset & 0x1ff == 0 and ptr.dva[ 0].asize & 0xfff == 0 and ( ptr.comp == 15 or ptr.comp == 2) and ptr.type == 20: print(" [%d]:" % (j, )) print(util.shift(str(ptr), 2)) except Exception as e: pass print("Bad at 0x%x" % (i << ashift)) traceback.print_exc(file=sys.stdout) i += raiddev.get_asize(4 + input_size) >> ashift
def frombytes(s): objset = ObjSet() objset.metadnode = Dnode.frombytes(s) objset.zil_header = ZilHeader.frombytes(s[Dnode.SIZE:]) objset.type, objset.flags, objset.portable_mac, objset.local_mac = struct.unpack_from( "<QQ32s32s", s[Dnode.SIZE + ZilHeader.SIZE:]) #if objset.type == ObjSet.OS_TYPE_ZFS: # return ObjSet.ZFS.promote(objset, s) #else: # return objset return objset
def __str__(self): s = Dnode.__str__(self) + "\n" if self.zap_type == ZAPObj.ZBT_MICRO: s += "TYPE: MICRO" elif self.zap_type == ZAPObj.ZBT_HEADER: s += "TYPE: HEADER" elif self.zap_type == ZAPObj.ZBT_LEAF: s += "TYPE: LEAF" else: s += "TYPE: UNKNOWN" if self.zap_type == ZAPObj.ZBT_HEADER: s += "\n" + str(self.fatzap) return s
def dump_dnode(): line = sys.stdin.readline() line = line.strip() addr, j = line.split(':') addr = int(addr, 16) j = int(j) block = raiddev.read(addr, 4096) input_size, = struct.unpack_from(">I", block) if input_size > 128 * 1024: return print("Guessed psize=0x%x" % (4 + input_size, )) block = raiddev.read(addr, 4 + input_size) block = lz4_decompress(block) dnode = Dnode.frombytes(block[j * Dnode.SIZE:(j + 1) * Dnode.SIZE], pool) print(dnode)
def dump_block(): line = sys.stdin.readline() line = line.strip() addr = int(line, 16) block = raiddev.read(addr, 4096) input_size, = struct.unpack_from(">I", block) if input_size > 128 * 1024: return print("Guessed psize=0x%x" % (4 + input_size, )) block = raiddev.read(addr, 4 + input_size) block = lz4_decompress(block) is_ptr = input("Is ptr block? (y/n)") if is_ptr == 'n': birth = 0 for j in range(len(block) // Dnode.SIZE): dnode = Dnode.frombytes(block[j * Dnode.SIZE:(j + 1) * Dnode.SIZE], pool) if dnode.get_birth() > birth: birth = dnode.get_birth() if dnode.type != 0 and dnode.type < len( dmu_constant.TYPES) and dmu_constant.TYPES[ dnode.type] != None: print(" [%d]: %s (@%d)" % (j, dmu_constant.TYPES[dnode.type], dnode.get_birth())) if dnode.type == 20: print(dnode.list()) elif dnode.type == 19: print(" filelen: %d" % (dnode.secphys if (dnode.flags & 1 != 0) else (dnode.secphys * 512))) print("Birth: %d" % (birth, )) else: birth = 0 for j in range(len(block) // BlkPtr.SIZE): ptr = BlkPtr.frombytes(block[j * BlkPtr.SIZE:(j + 1) * BlkPtr.SIZE]) if ptr.birth > birth: birth = ptr.birth if ptr.embedded and ptr.etype == BlkPtr.ETYPE_DATA: print(" [%d]: EMBEDDED" % (j, )) else: print(" [%d]:" % (j, )) print(util.shift(str(ptr), 2)) print("Birth: %d" % (birth, ))
def recover_file(): line = sys.stdin.readline() line = line.strip() addr, j, size = line.split(':') addr = int(addr, 16) j = int(j) block = raiddev.read(addr, 4096) input_size, = struct.unpack_from(">I", block) block = raiddev.read(addr, 4 + input_size) block = lz4_decompress(block) dnode = Dnode.frombytes(block[j * Dnode.SIZE:(j + 1) * Dnode.SIZE], pool) outf = open('test.mp4', 'wb') i = 0 while i < dnode.secphys: if i + 1024 * 1024 > dnode.secphys: outf.write(dnode.read(i, dnode.secphys - i)) i += 1024 * 1024 else: outf.write(dnode.read(i, 1024 * 1024)) i += 1024 * 1024 outf.close()
def _dump_dnode_block(addr, block, base): for j in range(len(block) // Dnode.SIZE): try: dnode = Dnode.frombytes(block[j * Dnode.SIZE:(j + 1) * Dnode.SIZE], pool) if dnode.type != 0 and dnode.type < len( dmu_constant.TYPES) and dmu_constant.TYPES[ dnode.type] != None: print("[%d] (0x%x[%d]): %s (@%d)" % (base * 32 + j, addr, j, dmu_constant.TYPES[dnode.type], dnode.get_birth())) if dnode.type == 20: lst = dnode.list() for name in lst: if type(lst[name]) == list: lst[name] = lst[name][0] lst[name] = lst[name] & 0x00ffffffffffffff print(" " + str(lst)) elif dnode.type == 19: print(" filelen: %d" % (dnode.secphys if (dnode.flags & 1 != 0) else (dnode.secphys * 512))) except: traceback.print_exc(file=sys.stdout)
def __str__(self): return Dnode.__str__(self) + "\n" + """CREATE: %x ACTIVE DATASET: %d""" % (self.bonus.creation_time, self.bonus.head_datset_obj)