Пример #1
0
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
Пример #2
0
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
Пример #3
0
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: ")
Пример #4
0
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)
Пример #5
0
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, ))
Пример #6
0
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()
Пример #7
0
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()
Пример #8
0
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()