53 lines
2.8 KiB
Python
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()
|