#!/usr/bin/env python3 import struct from typing import Dict, Set import capstone as cs import cxxfilt from colorama import Fore from util import utils, elf def main() -> None: new_matches: Dict[int, str] = dict() functions_by_addr: Dict[int, utils.FunctionInfo] = {fn.addr: fn for fn in utils.get_functions()} md = cs.Cs(cs.CS_ARCH_ARM64, cs.CS_MODE_ARM) md.detail = True decomp_addr_to_symbol = elf.build_addr_to_symbol_table(elf.my_symtab) decomp_glob_data_table = elf.build_glob_data_table(elf.my_elf) processed: Set[int] = set() for fn in functions_by_addr.values(): if fn.status != utils.FunctionStatus.Matching: continue if fn.size != 0x5C or (not fn.decomp_name.endswith("8getRuntimeTypeInfoEv") and not fn.name.endswith("rtti2")): continue base_fn = elf.get_fn_from_base_elf(fn.addr, fn.size) try: my_fn = elf.get_fn_from_my_elf(fn.decomp_name) except KeyError: utils.warn(f"could not find function {fn.decomp_name}") continue assert len(base_fn.data) == len(my_fn.data) vtable_ptr1 = 0 vtable_ptr2 = 0 for j, (i1, i2) in enumerate(zip(md.disasm(base_fn.data, base_fn.addr), md.disasm(my_fn.data, my_fn.addr))): assert i1.mnemonic == i2.mnemonic if j == 10: assert i1.mnemonic == "adrp" assert i1.operands[0].reg == i2.operands[0].reg vtable_ptr1 = i1.operands[1].imm vtable_ptr2 = i2.operands[1].imm elif j == 11: assert i1.mnemonic == "ldr" assert i1.operands[0].reg == i2.operands[0].reg assert i1.operands[1].value.mem.base == i2.operands[1].value.mem.base vtable_ptr1 += i1.operands[1].value.mem.disp vtable_ptr2 += i2.operands[1].value.mem.disp break assert vtable_ptr1 != 0 and vtable_ptr2 != 0 if vtable_ptr1 in processed: continue processed.add(vtable_ptr1) ptr1, = struct.unpack("