8cba70dc90
- Add 8 files present in docker/fifa17-python/tools but missing from the top-level tree: fut_accounts.py + 7 test_*.py contracts (all committed in the server's docker tree; byte-identical to the running image). - Preserve newer responder work already matching the running container: utas_server.py (offlineSeason), lsx_responder_v2.py (OPENFUT_BIND), blaze_responder_v3b.py, autopatch.py, pow_server.py, fut_store.py, test_fut_contract.py, fifa17-hook-m1.sh. - Add 30 newer ghidra_queries (draft purchase/state, SBC 9-26, runtime registries). Local tree is now a strict superset of B with all shared files byte-identical.
51 lines
1.9 KiB
Python
51 lines
1.9 KiB
Python
"""Resolve the concrete owner behind request+0x08 for the SBC category request.
|
|
|
|
q_md_sbc_9 proved generic slot +0x88 (0x1801631e0) invokes:
|
|
owner = *(request + 8)
|
|
owner.vtable[+0x18](owner, parsed_response, 0)
|
|
|
|
Work backwards from the category request constructor and its callers to identify who
|
|
supplies request+8, then map candidate owner vtables and their +0x18 consumers.
|
|
"""
|
|
import traceback
|
|
|
|
try:
|
|
def show(a, label):
|
|
f = func(a)
|
|
print("\n=== %s %#x %s ===" % (label, a, f.getName() if f else "?"))
|
|
print(dec(a))
|
|
|
|
ctor = 0x18017a7c0
|
|
show(ctor, "category request constructor")
|
|
print("\n=== ctor callers ===")
|
|
for ent, name in callers(ctor):
|
|
print(" %#x %s" % (ent, name))
|
|
show(ent, "ctor caller")
|
|
print("\n=== ctor xrefs ===")
|
|
for frm, typ, name, ent in xrefs_to(ctor):
|
|
print(" from=%#x type=%s fn=%s entry=%#x" % (frm, typ, name, ent))
|
|
|
|
# The request base constructor is usually visible as the first direct call in
|
|
# the category constructor. Dump every direct callee so request+8 initialization
|
|
# can be distinguished from URI/tag setup.
|
|
print("\n=== constructor direct callees ===")
|
|
for target, name in callees(ctor):
|
|
print(" %#x %s" % (target, name))
|
|
show(target, "ctor callee")
|
|
|
|
# Ghidra did not create a function at the traced +0x90 thunk. Print its raw
|
|
# instructions and nearby containing-function identity without assuming a body.
|
|
print("\n=== raw callback thunk at 0x180154830 ===")
|
|
ad = addr(0x180154830)
|
|
for _ in range(48):
|
|
ins = listing.getInstructionAt(ad)
|
|
if ins is None:
|
|
print(" %s <not disassembled>" % ad)
|
|
ad = ad.add(1)
|
|
continue
|
|
print(" %s %s" % (ad, ins))
|
|
ad = ins.getNext().getAddress() if ins.getNext() else ad.add(ins.getLength())
|
|
|
|
except Exception:
|
|
traceback.print_exc()
|