1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
"""Full corrected added-guard sweep across every module's version chain.
High-signal filter: only COMPARISON instructions (cmp/cmn/tst), and only
constants that go 0 -> N (newly introduced), which is the strongest evidence of
an added check. Alignment-aware decode (linear sweep misaligns Thumb).
Validated against ground truth: must rediscover the sOS CCP guard
(cmp #0xcb00000, 0 -> 1, at .51 -> .52).
"""
from capstone import *
import glob,os,collections,sys
md=Cs(CS_ARCH_ARM,CS_MODE_THUMB)
CMPS={'cmp','cmp.w','cmn','cmn.w','tst','tst.w'}
def census(path):
d=open(path,'rb').read()
c=collections.Counter()
for off in range(0,len(d)-4,2):
ins=list(md.disasm(d[off:off+4],off))
if not ins: continue
i=ins[0]
if i.mnemonic not in CMPS or '#' not in i.op_str: continue
try: v=int(i.op_str.rsplit('#',1)[1],0)
except Exception: continue
if v<0x40: continue # skip small loop/flag constants
c[v]+=1
return c
def chain_report(name, ordered):
print("="*84); print("%s (%d builds)"%(name,len(ordered))); print("="*84)
prev=None; prevlbl=None
for lbl,p in ordered:
cur=census(p)
if prev is not None:
new=[(v,cur[v]) for v in cur if prev.get(v,0)==0 and cur[v]>0]
new.sort(key=lambda t:-t[0])
if new:
print(" %s -> %s : %d newly-introduced comparison constant(s)"%(prevlbl,lbl,len(new)))
for v,n in new[:10]:
star=" <<<" if v>=0x10000 else ""
print(" cmp #%-12s x%d%s"%(hex(v),n,star))
else:
print(" %s -> %s : none"%(prevlbl,lbl))
prev=cur; prevlbl=lbl
print()
# sOS chain (includes the newly recovered .52)
sos=[('.37','versions/sos_0.49.0.37_b4f5f2ea.bin'),('.41','versions/sos_0.49.0.41_6504d3cc.bin'),
('.47','versions/sos_0.49.0.47_3be1d3af.bin'),('.48','versions/sos_0.49.0.48_d725e285.bin'),
('.49','versions/sos_0.49.0.49_fc2d5fa0.bin'),('.50','versions/sos_0.49.0.50_e4bc4b17.bin'),
('.51','versions/sos_0.49.0.51_14039a1f.bin'),
('.52*','versions_lfw/sos_3fd1d56b0467c5ea_98944.bin'),('.54','versions/sos_0.49.0.54_3dcb63e8.bin')]
chain_report("sOS", sos)
|