Exemplo n.º 1
0
    def read_rels_extract(self):
        # extract rels from 'RELs.arc'
        print(f"{self.step_count:2} Read RELs from '{self.rels_archive_path}'")
        self.step_count += 1

        found_rel_count = 0
        with self.rels_archive_path.open('rb') as file:
            rarc = libarc.read(file.read())
            for depth, file in rarc.files_and_folders:
                if not isinstance(file, libarc.File):
                    continue

                if file.name.endswith(".rel"):
                    if not file.name.lower() in settings.SHA1:
                        error(
                            f"unknown REL file: '{file.name}' ({file.name.lower()})"
                        )
                        fatal_exit()

                    sha1_check(file.name, file.data,
                               settings.SHA1[file.name.lower()])

                    rel = librel.read(file.data)
                    rel.path = Path(file.name)
                    rel.map = self.MAPS[file.name.lower().replace(
                        ".rel", ".map")]
                    self.RELS[rel.index] = rel
                    found_rel_count += 1

        info(f"found {found_rel_count} RELs in '{self.rels_archive_path}'")
Exemplo n.º 2
0
    def read_rels(self):
        # loads rels
        print(f"{self.step_count:2} Read RELs at '{self._rel_path}'")
        self.step_count += 1

        self.MAPS = {}
        for map_filepath in self.maps_path:
            self.MAPS[map_filepath.name.lower()] = map_filepath

        self.RELS = {}
        for rel_filepath in self.rels_path:
            with rel_filepath.open('rb') as file:
                if not rel_filepath.name.lower() in settings.SHA1:
                    error(
                        f"unknown REL file: '{rel_filepath}' ({rel_filepath.name.lower()})"
                    )
                    fatal_exit()

                data = bytearray(file.read())
                sha1_check(rel_filepath, data,
                           settings.SHA1[rel_filepath.name.lower()])

                rel = librel.read(data)
                rel.path = rel_filepath
                rel.map = self.MAPS[rel_filepath.name.lower().replace(
                    ".rel", ".map")]
                self.RELS[rel.index] = rel
Exemplo n.º 3
0
Arquivo: tp.py Projeto: notyourav/tp
def check_sha1(game_path, build_path):

    #dol_path = game_path.joinpath("main.dol")
    #if not dol_path.exists():
    #    raise CheckException(f"File not found: '{dol_path}'")

    rel_path = game_path.joinpath("rel/Final/Release")
    if not rel_path.exists():
        raise CheckException(f"Path not found: '{rel_path}'")

    rels_path = get_files_with_ext(rel_path, ".rel")
    rels_archive_path = game_path.joinpath("RELS.arc")
    if not rels_archive_path.exists():
        raise CheckException(f"File not found: '{rels_archive_path}'")

    #LOG.debug(f"DOL Path: '{dol_path}'")
    LOG.debug(f"RELs Path: '{rel_path}' (found {len(rels_path)} RELs)")
    LOG.debug(f"RELs Archive Path: '{rels_archive_path}'")

    EXPECTED = {}
    #with dol_path.open('rb') as file:
    #    data = file.read()
    #    EXPECTED[0] = (str(dol_path), sha1_from_data(data),sha1_from_data(data),)
    EXPECTED[0] = (
        "",
        "4997D93B9692620C40E90374A0F1DBF0E4889395",
        "4997D93B9692620C40E90374A0F1DBF0E4889395",
    )

    for rel_filepath in rels_path:
        with rel_filepath.open('rb') as file:
            data = bytearray(file.read())
            yaz0_data = data
            if struct.unpack('>I', data[:4])[0] == 0x59617A30:
                data = yaz0.decompress(io.BytesIO(data))

            rel = librel.read(data)
            EXPECTED[rel.index] = (
                str(rel_filepath),
                sha1_from_data(yaz0_data),
                sha1_from_data(data),
            )

    with rels_archive_path.open('rb') as file:
        rarc = libarc.read(file.read())
        for depth, file in rarc.files_and_folders:
            if not isinstance(file, libarc.File):
                continue

            if file.name.endswith(".rel"):
                data = file.data
                yaz0_data = data
                if struct.unpack('>I', data[:4])[0] == 0x59617A30:
                    data = yaz0.decompress(io.BytesIO(data))

                xxx_path = Path('build').joinpath(file.name)
                with xxx_path.open('wb') as write_file:
                    write_file.write(data)

                rel = librel.read(data)
                EXPECTED[rel.index] = (
                    file.name,
                    sha1_from_data(yaz0_data),
                    sha1_from_data(data),
                )

    if not build_path.exists():
        raise CheckException(f"Path not found: '{build_path}'")

    build_dol_path = build_path.joinpath("main.dol")
    if not build_dol_path.exists():
        raise CheckException(f"File not found: '{build_dol_path}'")

    build_rels_path = get_files_with_ext(build_path, ".rel")

    CURRENT = {}
    with build_dol_path.open('rb') as file:
        data = file.read()
        CURRENT[0] = (
            str(build_dol_path),
            sha1_from_data(data),
            sha1_from_data(data),
        )

    for rel_filepath in build_rels_path:
        with rel_filepath.open('rb') as file:
            data = bytearray(file.read())
            yaz0_data = data
            if struct.unpack('>I', data[:4])[0] == 0x59617A30:
                data = yaz0.decompress(io.BytesIO(data))

            rel = librel.read(data)
            CURRENT[rel.index] = (
                str(rel_filepath),
                sha1_from_data(yaz0_data),
                sha1_from_data(data),
            )

    expected_keys = set(EXPECTED.keys())
    current_keys = set(CURRENT.keys())
    match = expected_keys - current_keys
    if len(match) > 0:
        raise CheckException(
            f"Missing RELs (expected: {len(expected_keys)}, found: {len(current_keys)})"
        )

    errors = 0
    for key in expected_keys:
        if key in current_keys:
            expected = EXPECTED[key]
            current = CURRENT[key]
            if current[2] != expected[2]:
                errors += 1
                LOG.error(
                    f"{current[2]} {expected[2]} {current[0]} ({expected[0]})")

    if errors > 0:
        raise CheckException("NO MATCH!")

    return True
Exemplo n.º 4
0
Arquivo: rel.py Projeto: magcius/tp
def rel_info(
    debug,
    rel_path,
    dump_header,
    dump_sections,
    dump_data,
    dump_relocation,
    dump_imp,
    dump_all,
):
    if debug:
        LOG.setLevel(logging.DEBUG)

    path = Path(rel_path)
    if not path.exists():
        LOG.error(f"File not found: '{path}'")
        sys.exit(1)

    with open(path, "rb") as file:
        buffer = file.read()
        rel = librel.read(buffer)

    if dump_all:
        dump_header = True
        dump_sections = True
        dump_data = True
        dump_relocation = True
        dump_imp = True

    if not (dump_header or dump_sections or dump_data or dump_relocation
            or dump_imp):
        CONSOLE.print("no dump options specified")

    if dump_header:
        CONSOLE.print(f"Header:")
        CONSOLE.print(f"\tindex:   {rel.index}")
        CONSOLE.print(f"\tversion: {rel.version}")
        CONSOLE.print(f"\tsection count: {rel.numSections}")
        CONSOLE.print(f"\tsection offset: 0x{rel.sectionInfoOffset:04X}")
        CONSOLE.print(f"")
        CONSOLE.print(f"\tname offset: 0x{rel.nameOffset:04X}")
        CONSOLE.print(f"\tname size:   {rel.nameSize}")
        CONSOLE.print(f"\talign:       0x{rel.align:02X}")
        CONSOLE.print(f"\tfix size:    0x{rel.fixSize:04X}")
        CONSOLE.print(f"\tbss size:    0x{rel.bssSection:X}")
        CONSOLE.print(f"\tbss align:   0x{rel.bssAlign:02X}")
        CONSOLE.print(f"\tbss section: 0x{rel.bssSize:04X}")
        CONSOLE.print(f"\trel offset:  0x{rel.relOffset:04X}")
        CONSOLE.print(f"\timp offset:  0x{rel.impOffset:04X}")
        CONSOLE.print(f"\timp size:    0x{rel.impSize:04X}")
        CONSOLE.print(
            f"\t_prolog:     0x{rel.prolog:04X} (section: 0x{rel.prologSection:X})"
        )
        CONSOLE.print(
            f"\t_epilog:     0x{rel.epilog:04X} (section: 0x{rel.epilogSection:X})"
        )
        CONSOLE.print(
            f"\t_unresolved: 0x{rel.unresolved:04X} (section: 0x{rel.unresolvedSection:X})"
        )

    if dump_sections:
        CONSOLE.print(f"Sections:")

        for i, section in enumerate(rel.sections):
            CONSOLE.print(
                f"\t#{i:<2} offset: 0x{section.offset:08X}, length: 0x{section.length:04X}, unknown flag: {section.unknown_flag}, executable flag: {section.executable_flag}"
            )

    if dump_imp:
        CONSOLE.print(f"Imp Table:")

        imp_buffer = rel.data[rel.impOffset:]
        for i in range(rel.impSize // 8):
            imp_offset = 0x8 * i
            module_id, rel_offset = struct.unpack(
                ">II", imp_buffer[imp_offset:][:0x8])
            CONSOLE.print(
                f"\t#{i:<2} module: {module_id:>4}, offset: 0x{rel_offset:04X}"
            )

    if dump_relocation:
        CONSOLE.print(f"Relocations:")

        imp_buffer = rel.data[rel.impOffset:]
        for i in range(rel.impSize // 8):
            imp_offset = 0x8 * i
            module_id, rel_offset = struct.unpack(
                ">II", imp_buffer[imp_offset:][:0x8])

            CONSOLE.print(f"\t[ module: {module_id:>4} ]")
            section = None
            offset = 0
            rel_index = 0
            while True:
                relocation = librel.read_relocation(module_id,
                                                    rel.data[rel_offset:])
                rel_offset += 0x8
                rel_index += 1

                extra = ""
                if section and path.name in settings.REL_TEMP_LOCATION:
                    base = settings.REL_TEMP_LOCATION[path.name]
                    base += section.offset - rel.sections[1].offset
                    extra = f" | {base:08X} {base+relocation.offset + offset:08X}"

                CONSOLE.print(
                    f"\t#{rel_index:<3} {librel.RELOCATION_NAMES[relocation.type]:<20} {relocation.section:>4} 0x{relocation.offset+offset:08X} 0x{relocation.addend:08X}{extra}"
                )

                if relocation.type == librel.R_PPC_NONE:
                    continue
                if relocation.type == librel.R_DOLPHIN_NOP:
                    # NOP is used to simulate long offset values, this is because
                    # the offset field is limited to 2^16-1 values. Thus, any offsets
                    # above 2^16 will be divided into a NOP + original relocation type.
                    offset += relocation.offset
                    continue
                if relocation.type == librel.R_DOLPHIN_SECTION:
                    section = rel.sections[relocation.section]
                    offset = 0
                    continue

                assert section
                relocation.parent = section
                relocation.relative_offset = relocation.offset
                relocation.offset += offset
                offset = relocation.offset

                assert relocation.type != librel.R_DOLPHIN_MRKREF
                if relocation.type == librel.R_DOLPHIN_END:
                    break

    if dump_data:
        CONSOLE.print(f"Sections:")

        for i, section in enumerate(rel.sections):
            if section.data:
                CONSOLE.print(f"\t#{i:<2}")
                hexdata = hexdump.hexdump(section.data, result="return")
                CONSOLE.print(hexdata)