65 lines
2.5 KiB
Python
65 lines
2.5 KiB
Python
"""ADVERSARIAL VERIFY Dimension 1: userInfo.feature restriction vocabulary.
|
|
|
|
Attacks:
|
|
D1.1 feature loop recognises EXACTLY one sub-key (trade 0x330), all else value-SKIP.
|
|
D1.2 trade uses INT getter FUN_1801c79d0, writes +0xa4 only when ==1.
|
|
D1.3 massinfo root FUN_180174630: at END_OBJECT the SOLE `cmp byte[reg+disp],0` site
|
|
is +0x17c -> zero [reg+0x50]; nothing else zeroes a settings field from a feature byte.
|
|
|
|
Control: 0x330 MUST appear in the feature loop and map to +0xa4 (param_1+0x29). If the
|
|
massinfo case that calls the feature parser is not +0xd8, the +0x17c arithmetic is wrong.
|
|
"""
|
|
import traceback
|
|
try:
|
|
FEAT = 0x18013ec10
|
|
MASS = 0x180174630
|
|
|
|
src = dec(FEAT, 300)
|
|
print("=== FEATURE FUN_18013ec10 decompile=%d chars ===" % len(src))
|
|
print(src)
|
|
|
|
# enumerate every integer constant compared in the loop (dispatch forms)
|
|
print("\n=== raw instructions in feature parser: CMP/immediates + calls ===")
|
|
f = func(FEAT)
|
|
it = listing.getInstructions(f.getBody(), True)
|
|
cnt = 0
|
|
while it.hasNext():
|
|
ins = it.next()
|
|
m = ins.getMnemonicString()
|
|
s = str(ins)
|
|
if m in ("CMP", "SUB", "LEA") and ("0x330" in s or "0x11c" in s):
|
|
print(" %#x %s" % (ins.getAddress().getOffset(), s))
|
|
if m == "CALL":
|
|
print(" %#x %s" % (ins.getAddress().getOffset(), s))
|
|
cnt += 1
|
|
print(" (total insns=%d)" % cnt)
|
|
|
|
print("\n=== MASSINFO root FUN_180174630: scan for cmp byte[reg+disp],0x0 ===")
|
|
fm2 = func(MASS)
|
|
it = listing.getInstructions(fm2.getBody(), True)
|
|
hits = []
|
|
n = 0
|
|
prev = []
|
|
while it.hasNext():
|
|
ins = it.next()
|
|
n += 1
|
|
m = ins.getMnemonicString()
|
|
s = str(ins)
|
|
# cmp byte ptr [reg + disp], 0
|
|
if m == "CMP" and "byte ptr" in s and s.rstrip().endswith(",0x0"):
|
|
hits.append((ins.getAddress().getOffset(), s))
|
|
# any MOV of 0 into [reg+0x50]
|
|
if m == "MOV" and "dword ptr" in s and "0x50]" in s and s.rstrip().endswith(",0x0"):
|
|
print(" ZERO-WRITE %#x %s" % (ins.getAddress().getOffset(), s))
|
|
print(" cmp byte[reg+disp],0 sites: %d" % len(hits))
|
|
for a, s in hits:
|
|
print(" %#x %s" % (a, s))
|
|
print(" (massinfo total insns=%d)" % n)
|
|
|
|
# confirm which case calls the feature parser and at what struct offset
|
|
print("\n=== calls to FUN_18013ec10 (feature) from anywhere ===")
|
|
for frm, typ, fn, ent in xrefs_to(FEAT):
|
|
print(" %#x %s in %s" % (frm, typ, fn))
|
|
except Exception:
|
|
traceback.print_exc()
|