"""D3 Q12: close the last gap -- is FUN_1800e2a40 the thing FUN_18003e370 calls? Its only 8-byte pointer slot is at +0xd0 of one table, not +0x40, so either the call goes through a thunk or the attribution is wrong. Print all callers, and print the service constructor FUN_180018bd0 so the interface can be named. CONTROL: the semantic anchor is independent of the vtable -- byte[2] of the output array is computed as (isPlayer && squadHasRoom && !alreadyInSquad), which can only be TO_ACTIVE_SQUAD, the 3rd of the eight names. If callers show a thunk, both lines of evidence agree; if not, the semantic anchor still stands alone.""" import traceback try: print("### callers of FUN_1800e2a40") for c in callers(0x1800e2a40): print(" ", c) for frm, typ, fn, ent in xrefs_to(0x1800e2a40): print(" xref %#x %s in %s (%#x)" % (frm, typ, fn, ent)) print() print("### FUN_180018bd0 (the service FUN_18003e370 asks for)") print(dec(0x180018bd0)) print("### FUN_18003cbf0 (CARD_ID extraction, 2nd arg to slot 0x40)") print(dec(0x18003cbf0)) except Exception: traceback.print_exc()