"""DIMENSION 4, pass 11: decode the request on the not-duplicate branch.

From FUN_18016c730 (the generic dispatcher) the payload object's vtable slots
are: +0x08 = header/url contributor, +0x10 = body serializer. For the object
built in FUN_18009bc40 the vtable is 0x1801f3158, so
    body serializer = 0x180127cc0
    header/url      = 0x180122420
Decompile both. The body serializer's FUN_180180cd0(<atom>) calls name the
request's keys, which is exactly what dimension 4 needs.

Also decompile the five OTHER builders that instantiate the same vtable
(FUN_1800db920, FUN_1800dbb90, FUN_1800dcad0, FUN_1800363e0, FUN_1800366f0):
comparing the int they store at record+0x08 (our site stores 7) decodes that
enum.

CONTROL: FUN_180126440 is the already-established PurchaseItems request
serializer; decompile it too so the "what a request serializer looks like"
reading is anchored on a known case.
"""
import traceback

OUT = "/tmp/claude-1000/-home-alex-Documents-OpenFUT/8e521ca1-ca3e-4138-bb96-df1744dd1d30/scratchpad/store/dup11_out.txt"

def w(fh, s=""):
    fh.write(str(s) + "\n")

def dump(fh, a, label):
    s = dec(a)
    w(fh, "")
    w(fh, "#" * 70)
    w(fh, "# %s  %#x  len(src)=%d  FULL" % (label, a, len(s)))
    w(fh, "#" * 70)
    w(fh, s)

try:
    fh = open(OUT, "w")
    dump(fh, 0x180127CC0, "BODY SERIALIZER vt+0x10 of the not-duplicate request")
    dump(fh, 0x180122420, "header/url contributor vt+0x08")
    dump(fh, 0x180129200, "vt+0x38 of the same vtable")
    for a in (0x1800DB920, 0x1800DBB90, 0x1800DCAD0, 0x1800363E0, 0x1800366F0):
        dump(fh, a, "sibling builder using vtable 0x1801f3158")
    dump(fh, 0x180126440, "CONTROL: PurchaseItems request serializer")

    w(fh, "")
    w(fh, "=== raw disassembly of FUN_1801180a0 (manager vt+0xc0) ===")
    try:
        flat.disassemble(addr(0x1801180A0))
        flat.createFunction(addr(0x1801180A0), None)
    except Exception as e:
        w(fh, "createFunction: %s" % e)
    f = func(0x1801180A0)
    it = listing.getInstructions(f.getBody(), True)
    while it.hasNext():
        i = it.next()
        w(fh, "   %s  %s" % (i.getAddress(), i))

    fh.close()
    print("WROTE", OUT)
except Exception:
    traceback.print_exc()
