Example #1
0
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}")
Example #2
0
 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")
Example #3
0
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")
Example #4
0
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)
Example #5
0
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
Example #6
0
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)
Example #7
0
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)
Example #8
0
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