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

53 lines
2.8 KiB
Python

"""ADVERSARIAL verify of Seasons Findings 2 & 4 + getter offsets.
HYPOTHESIS UNDER ATTACK:
F2: model+0x5c68 season vector written ONLY by FUN_1801683f0 (/season deser).
F4: SEASONLIST descriptor @0x1802cb718 and URL 'ut/%s/season' @0x18021e598 have no code xref.
Getters: vtable+0x898 -> lea rax,[rcx+0x5c68]; vtable+0x588 -> lea rax,[rcx+0x7138].
CONTROL: resolve a KNOWN getter/xref form the same way (disp32 immediate scan) and
confirm the scanner actually finds multi-hit patterns (not silently zero).
"""
import traceback
try:
MODEL_VT=0x18021c2a0
# 1. getter slots
for slot in (0x898,0x588,0x988,0x990):
t=qword(MODEL_VT+slot)
print("vtable +%#x -> %#x %s" % (slot,t,fname(t)))
print(" dec head:", " | ".join(dec(t).splitlines()[:6]))
# 2. disp32 immediate scan in .text for 0x5c68 (le 4-byte) and 0x7138
for off_name,val in (("0x5c68",0x5c68),("0x7138",0x7138),("0x1fd3a",0x1fd3a)):
pat=val.to_bytes(4,'little')
hits=find_all(pat, blocks=(".text",))
print("\ndisp32 scan .text for %s (%s): %d hits" % (off_name, pat.hex(), len(hits)))
for h in hits[:12]:
f=func(h); print(" @%#x in %s" % (h, f.getName() if f else '?'))
# 3. call sites of [reg+0x898] -- scan .text for the modrm/disp32 forms of call [r+0x898]
# common encodings: FF 90 98 08 00 00 (call [rax+0x898]); reg varies in modrm middle bits.
print("\n--- call [reg+0x898] sites (FF /2 disp32 = 98 08 00 00) ---")
disp=(0x898).to_bytes(4,'little')
for pat_desc,pat in [("call [rax+d]",b"\xff\x90"+disp),("call [rcx+d]",b"\xff\x91"+disp),
("call [rdx+d]",b"\xff\x92"+disp),("call [rbx+d]",b"\xff\x93"+disp),
("call [rsi+d]",b"\xff\x96"+disp),("call [rdi+d]",b"\xff\x97"+disp),
("call [r8+d]",b"\x41\xff\x90"+disp),("call [r9+d]",b"\x41\xff\x91"+disp),
("call [r10+d]",b"\x41\xff\x92"+disp),("call [r11+d]",b"\x41\xff\x93"+disp)]:
hits=find_all(pat, blocks=(".text",))
for h in hits:
f=func(h); print(" %s @%#x in %s" % (pat_desc,h,f.getName() if f else '?'))
# 4. Finding 4: descriptor + url xrefs
print("\n--- F4: SEASONLIST descriptor / url xrefs ---")
print("xrefs_to(0x1802cb718):", xrefs_to(0x1802cb718))
print("xrefs_to(0x18021e598) url ut/%s/season:", xrefs_to(0x18021e598))
print("string @0x18021e598:", repr(rd_str(0x18021e598)))
# SEASONLIST literal locate
sl=find_all(b"SEASONLIST\x00")
print("SEASONLIST literal at:", [hex(x) for x in sl])
for a in sl:
print(" xrefs_to(%#x):"%a, xrefs_to(a))
# url literal locate
us=find_all(b"ut/%s/season\x00")
print("'ut/%s/season' literal at:", [hex(x) for x in us])
for a in us:
print(" xrefs_to(%#x):"%a, xrefs_to(a))
except Exception:
traceback.print_exc()