def main() -> None: parser = argparse.ArgumentParser("Print AI class decompilation progress.") parser.add_argument("-t", "--type", help="AI class type", choices=_TYPES) args = parser.parse_args() filter_type: Optional[str] = args.type data_path = utils.get_repo_root() / "data" for class_type in _TYPES: if filter_type is not None and class_type != filter_type: continue with (data_path / f"status_{class_type}.yml").open() as f: fns: Dict[str, dict] = yaml.load(f, Loader=yaml.CSafeLoader) for name, info in fns.items(): status = info["status"] if status == "done": color = Fore.GREEN elif status == "wip": color = Fore.YELLOW elif status == "pending": color = "" else: assert False, f"unexpected status {status}" print(f"{color}{name:<50} {color}{info['status']}{Fore.RESET}")
def load_data_for_project(self) -> None: self.decompiled_fns = { func.addr: func.decomp_name for func in utils.get_functions() if func.decomp_name } self.get_data_symtab().load_from_csv(utils.get_repo_root() / "data" / "data_symbols.csv")
def dump_fn(name: str) -> None: expected_dir = utils.get_repo_root() / "expected" try: fn = util.elf.get_fn_from_my_elf(name) path = expected_dir / f"{name}.bin" path.parent.mkdir(exist_ok=True) path.write_bytes(fn.data) except KeyError: utils.fail("could not find function")
def main() -> None: failed = False nonmatching_fns_with_dump = { p.stem: util.elf.Function(p.read_bytes(), 0) for p in (utils.get_repo_root() / "expected").glob("*.bin") } checker = util.checker.FunctionChecker(log_mismatch_cause=True) for func in utils.get_functions(): if not func.decomp_name: continue try: util.elf.get_fn_from_my_elf(func.decomp_name) except KeyError: utils.warn( f"couldn't find {utils.format_symbol_name_for_msg(func.decomp_name)}" ) continue if func.status == utils.FunctionStatus.Matching: if not check_function(checker, func.addr, func.size, func.decomp_name): utils.print_error( f"function {utils.format_symbol_name_for_msg(func.decomp_name)} is marked as matching but does not match" ) a1, a2, reason = checker.get_mismatch() if a1 != -1: sys.stderr.write( f" at {a1 | 0x7100000000:#x} : {Fore.CYAN}{reason}{Fore.RESET}\n" ) failed = True elif func.status == utils.FunctionStatus.Equivalent or func.status == utils.FunctionStatus.NonMatching: if check_function(checker, func.addr, func.size, func.decomp_name): utils.print_note( f"function {utils.format_symbol_name_for_msg(func.decomp_name)} is marked as non-matching but matches" ) fn_dump = nonmatching_fns_with_dump.get(func.decomp_name, None) if fn_dump is not None and not check_function( checker, func.addr, len(fn_dump), func.decomp_name, fn_dump): utils.print_error( f"function {utils.format_symbol_name_for_msg(func.decomp_name)} does not match expected output" ) failed = True if failed: sys.exit(1)
def get_ai_vtable_names() -> Dict[int, str]: with (utils.get_repo_root() / "data" / "aidef_ai_vtables.yml").open(encoding="utf-8") as f: names = yaml.load(f, Loader=yaml.CSafeLoader) check_vtable_name_dict(names) return names
def get_ai_params() -> Dict[str, List[dict]]: with (utils.get_repo_root() / "data" / "aidef_ai_params.yml").open(encoding="utf-8") as f: return yaml.load(f, Loader=yaml.CSafeLoader)
def get_vtables() -> Dict[str, Dict[str, List[int]]]: with (utils.get_repo_root() / "data" / "aidef_vtables.yml").open(encoding="utf-8") as f: return yaml.load(f, Loader=yaml.CSafeLoader)
import io import struct from typing import Any, Dict, NamedTuple, Tuple from elftools.elf.elffile import ELFFile from elftools.elf.relocation import RelocationSection from elftools.elf.sections import Section import diff_settings from util import utils _config: Dict[str, Any] = {} diff_settings.apply(_config, {}) _root = utils.get_repo_root() base_elf_data = io.BytesIO((_root / _config["baseimg"]).read_bytes()) my_elf_data = io.BytesIO((_root / _config["myimg"]).read_bytes()) base_elf = ELFFile(base_elf_data) my_elf = ELFFile(my_elf_data) my_symtab = my_elf.get_section_by_name(".symtab") if not my_symtab: utils.fail(f'{_config["myimg"]} has no symbol table') class Symbol(NamedTuple): addr: int name: str size: int