51 lines
2.5 KiB
Python
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)
|