"""Q23: callers of the manager setter FUN_18011d780 -> the manager's vtable. CONTROL: the vtable found must have real functions at slots 0xa08 and 0xa40. """ import traceback try: for frm, typ, fn, ent in xrefs_to(0x18011D780): print("caller %s(%#x) via %#x %s" % (fn, ent, frm, typ)) ents = {ent for _f, _t, _n, ent in xrefs_to(0x18011D780) if ent} for ent in ents: src = dec(ent) print("=" * 70) print("FUN_%x len=%d" % (ent, len(src))) print(src if len(src) < 7000 else src[:7000] + "\n...[cut]") f = func(ent) cands = set() for ad in f.getBody().getAddresses(True): ins = listing.getInstructionAt(ad) if ins is None: continue for r in ins.getReferencesFrom(): t = int(r.getToAddress().getOffset()) if 0x1801E5000 <= t <= 0x1802891FF: cands.add(t) print("--- .rdata refs, checked for vtable shape ---") for t in sorted(cands): try: v0, v1 = qword(t), qword(t + 8) s90, s98 = qword(t + 0x490), qword(t + 0x498) a08, a40 = qword(t + 0xA08), qword(t + 0xA40) except Exception: continue ok = all(fm.getFunctionAt(addr(x)) is not None for x in (v0, v1) if 0x180000000 <= x < 0x181000000) print(" %#x v0=%s v1=%s | +0x490=%s +0x498=%s +0xa08=%s +0xa40=%s%s" % (t, fname(v0), fname(v1), fname(s90), fname(s98), fname(a08), fname(a40), " <== VTABLE?" if ok else "")) except Exception: traceback.print_exc()