"""Q22: resolve the manager object's vtable through the global DAT_1802e6398. FUN_18011a830 just returns DAT_1802e6398, so the vtable is installed wherever that global is written. Find the writers, decompile the smallest, and read the vtable it stores. Then dump slots 0x490 / 0x498 / 0xa08 / 0xa38 / 0xa40. CONTROL: the recovered vtable's slot 0xa08 and 0xa40 must both be real functions (the item deserializer calls 0xa08 to file an item; FUN_18011e3c0 calls 0xa40 with a resourceId). If either is not a function, the vtable is wrong. """ import traceback try: print("=== writers/readers of DAT_1802e6398 ===") ents = {} for frm, typ, fn, ent in xrefs_to(0x1802E6398): ents.setdefault(ent, []).append((frm, typ, fn)) for ent, lst in sorted(ents.items()): print(" %s(%#x) n=%d types=%s" % (lst[0][2], ent, len(lst), sorted({t for _f, t, _n in lst}))) # the constructor is a function that WRITES it writers = [e for e, lst in ents.items() if any(t == "WRITE" for _f, t, _n in lst)] print("writers: %s" % ["%#x" % w for w in writers]) for w in writers: src = dec(w) print("=" * 70) print("writer FUN_%x len=%d" % (w, len(src))) print(src if len(src) < 6000 else src[:6000] + "\n...[cut]") except Exception: traceback.print_exc()