def _dump_tree(addr, base): if type(addr) == int: block = raiddev.read(addr, 4096) input_size, = struct.unpack_from(">I", block) block = raiddev.read(addr, 4 + input_size) block = lz4_decompress(block) else: if addr.endian == 0: return try: block = pool.read_raw(addr) except: print("Read this ptr failed:") print(util.shift(str(addr), 1)) traceback.print_exc(file=sys.stdout) return for j in range(len(block) // BlkPtr.SIZE): try: ptr = BlkPtr.frombytes(block[j * BlkPtr.SIZE:(j + 1) * BlkPtr.SIZE]) if ptr.embedded and ptr.etype == BlkPtr.ETYPE_DATA: print(" [%d]: EMBEDDED" % (j, )) elif ptr.birth == 0: continue elif ptr.lvl == 0: addr = ptr.dva[0].offset nblock = pool.read_raw(ptr) if nblock == None: continue _dump_dnode_block(addr, nblock, base * 1024 + j) else: _dump_tree(ptr, base * 1024 + j) except: pass
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 dump_0(): line = input("Root block addr: ") while line != '': line = line.strip() addr = int(line, 16) print("Root 0x%x" % (addr, )) block = raiddev.read(addr, 4096) input_size, = struct.unpack_from(">I", block) block = raiddev.read(addr, 4 + input_size) block = lz4_decompress(block) ptr = BlkPtr.frombytes(block[0:BlkPtr.SIZE]) print(util.shift(str(ptr), 1)) line = input("Root block addr: ")
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 dump_birth(): inf = open(sys.argv[1], 'r') outf = open(sys.argv[2], 'w') line = inf.readline() while line != None and line != '': line = line.strip() addr = int(line, 16) block = raiddev.read(addr, 4096) input_size, = struct.unpack_from(">I", block) block = raiddev.read(addr, 4 + input_size) block = lz4_decompress(block) 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 print("0x%x: @%d" % (addr, birth), file=outf) line = inf.readline() outf.close() inf.close()
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 scan_log(): f = open(sys.argv[1], 'r') line = f.readline() while line != None and line != "": if line.startswith('Found at '): line = line.strip() try: addr = int(line[9:], 16) except: pass line = f.readline() elif line.startswith(' [') and line.endswith(':\n'): line = f.readline() block = raiddev.read(addr, 4096) input_size, = struct.unpack_from(">I", block) block = raiddev.read(addr, 4 + input_size) block = lz4_decompress(block) try: 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: pass 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: if ptr.type == 20 and ptr.nlevel != 0: print("%x[%d]:" % ( addr, j, )) except: pass while line != None and line.startswith(' '): line = f.readline() else: line = f.readline()