Files
OpenFUT/fifa17-recon/tools/ghidra_queries/q_md_seasons_7.py
T

51 lines
2.5 KiB
Python

"""DIMENSION 3 SEASONS q7.
(a) Is the +0x7138 season-struct writer (model vtable slot +0x990 = FUN_18011c2e0)
reached from the massinfo/settings RESPONSE path (a boot server lever), like the
settings applier at +0x988? Find call sites of slot +0x990.
(b) Does userInfo.feature parser FUN_18013ec10 have a season-related restriction key?
List its atom compares.
(c) Confirm FUN_1801683f0 is the FutSeasonList RESPONSE deser (RS4 name -> vtable +8).
(d) Does the massinfo body deser (FUN_180174xxx region) or its completion touch the
season vector / +0x7138 (i.e. can boot populate seasons)?
CONTROL: for the RS4 resolution, also resolve a KNOWN class RS4:FutSquadSave ->
must give 0x180171a60 (per class_deser docstring) as a passing control.
"""
import traceback, struct
try:
# (a) find call sites of model vtable slot +0x990 (0x990 disp on a call through rax/rcx)
# The applier +0x988 was called from 0x180173f0b and 0x18011e21a. Search .text for
# the byte pattern of a call [reg+0x990]: ff 90 90 09 00 00 (call [rax+0x990]) and
# ff 91 90 09 00 00 (call [rcx+0x990]) and other regs.
print("### call [reg+0x990] sites (season struct writer) ###")
for modrm in (0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97):
pat = bytes([0xff, modrm]) + struct.pack("<i", 0x990)
for h in find_all(pat, blocks=(".text",)):
f = fm.getFunctionContaining(addr(h))
print(" +0x990 call", hex(h), "in", f.getName() if f else "?", "modrm", hex(modrm))
print("### control: call [reg+0x988] sites (settings applier) ###")
for modrm in (0x90, 0x91, 0x92, 0x93):
pat = bytes([0xff, modrm]) + struct.pack("<i", 0x988)
for h in find_all(pat, blocks=(".text",)):
f = fm.getFunctionContaining(addr(h))
print(" +0x988 call", hex(h), "in", f.getName() if f else "?")
# (b) feature parser atom compares
print("\n### FUN_18013ec10 (userInfo.feature parser) decompile ###")
d = dec(0x18013ec10); print("LEN", len(d)); print(d)
# (c) RS4:FutSeasonList resolution + control
print("\n### RS4 resolution ###")
for cls in (b"RS4:FutSeasonListServerResponse", b"RS4:FutSquadSaveServerResponse"):
for a in find_all(cls, blocks=(".rdata",)):
print(" class", cls, "@", hex(a))
for x in xrefs_to(a):
fn = x[2]
print(" factory xref", hex(x[0]), fn, hex(x[3]))
sys.stdout.flush()
os._exit(0)
except Exception:
traceback.print_exc()
sys.stdout.flush()
os._exit(0)