"""Find the concrete settings service class, so its constructor defaults can be read.

FUN_180009c80 resolves the object through a service locator keyed by 0x0ed84b11
(service) / 0x0ed84b12 (interface), so the vtable is not reachable by following
pointers statically. But the class that REGISTERS itself under 0x0ed84b11 must
name the constant too, and its registration sits next to its construction.

Also decompile the two callers of the settings deser: the GET /settings path
(0x18014e590) and the massinfo path (0x180174630), to see where the filled
struct is handed off, since the publisher reads the SERVICE, not the response.
"""
import struct

for cid in (0x0ED84B11, 0x0ED84B12):
    pat = struct.pack("<I", cid)
    print("=" * 78)
    print("references to %#x" % cid)
    print("=" * 78)
    seen = {}
    for h in find_all(pat, blocks=(".text", ".rdata", ".data")):
        f = fm.getFunctionContaining(addr(h))
        if f:
            seen.setdefault(int(f.getEntryPoint().getOffset()), f.getName())
        else:
            print("   %#x  (not in a function)" % h)
    for a, n in sorted(seen.items()):
        print("   %#x  %s" % (a, n))

print("\n" + "=" * 78)
print("0x18014e590 -- GET /settings caller of the deser")
print("=" * 78)
print(dec(0x18014E590))
