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
|
"""Phase 5: triage SEMANTIC deltas, prioritising LITERAL changes.
A security fix most often shows as a changed constant (bound tightened, mask
narrowed, size corrected) or a NEW comparison. Those are exactly what the old
mnemonic-only diff could not see, so they are ranked first.
"""
import json, glob, os, re, sys, collections
LIT=re.compile(r"\b(?:0[xX][0-9A-Fa-f]+|\d+)\b")
CMP=re.compile(r"(?:<=|>=|==|!=|<|>)")
def lits(t): return collections.Counter(LIT.findall(t))
def classify(o, n):
lo, ln = lits(o), lits(n)
gained = sorted((ln-lo).elements()); lost = sorted((lo-ln).elements())
dcmp = len(CMP.findall(n)) - len(CMP.findall(o))
dlen = len(n) - len(o)
score = 0
if gained or lost: score += 3
if dcmp > 0: score += 3 # a comparison was ADDED -> candidate guard
if abs(dlen) > 200: score += 1
return dict(gained=gained[:8], lost=lost[:8], dcmp=dcmp, dlen=dlen, score=score)
if __name__=='__main__':
diffs=json.load(open('phase4_diffs.json'))
corp={os.path.basename(p)[:-5]: json.load(open(p)) for p in glob.glob('phase3/*.json')}
fams=sys.argv[1:] or ['sos','hdcp','sys_drv','asd']
rows=[]
for pair, r in diffs.items():
o,n = pair.split(' -> ')
if not any(o.startswith(f+'_') for f in fams): continue
for fn in r['changed']:
if fn not in corp[o] or fn not in corp[n]: continue
c=classify(corp[o][fn], corp[n][fn])
if c['score']>0: rows.append((c['score'], pair, fn, c))
rows.sort(key=lambda t:(-t[0], t[1]))
print("SEMANTIC deltas with literal or comparison changes: %d\n"%len(rows))
for sc,pair,fn,c in rows[:40]:
po=pair.split(' -> ')[0].rsplit('_',1)[0].replace('sys_drv_','').replace('sos_','').replace('asd_','').replace('hdcp_','')
pn=pair.split(' -> ')[1].rsplit('_',1)[0].replace('sys_drv_','').replace('sos_','').replace('asd_','').replace('hdcp_','')
print("score=%d %-11s->%-11s %-44s +cmp=%-3d dlen=%-6d"%(sc,po,pn,fn[:44],c['dcmp'],c['dlen']))
if c['gained']: print(" gained literals: %s"%c['gained'])
if c['lost']: print(" lost literals: %s"%c['lost'])
|