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
|
"""Emitter scan that handles BOTH `str rX,[sp]` and `stm sp,{rX,...}` opcode stores.
The earlier version only matched `str [sp]` and therefore MISSED every stub that
uses STM -- which is how several HDCP disp_* stubs write frame[0]. Any previous
"no module emits X" conclusion produced by the old scanner is unsound.
"""
import struct, os, sys
from capstone import *
md=Cs(CS_ARCH_ARM,CS_MODE_THUMB)
MODS=(('sos','handover/elf/sos2.elf'),('sys_drv','handover/elf/sys_drv2.elf'),
('asd','handover/elf/asd2.elf'),('hdcp','handover/elf/hdcp2.elf'),
('dtm','handover/elf/dtm2.elf'),('ras','handover/elf/ras2.elf'))
def load(p):
raw=open(p,'rb').read(); ph=struct.unpack('<I',raw[28:32])[0]
o,v,pa,f=struct.unpack('<IIII',raw[ph+4:ph+20]); return raw[o:o+f],v
def emitted(body,v):
out={}
sites=[v+a for a in range(0,len(body)-1,2) if body[a]==0xF2 and body[a+1]==0xDF]
for s in sites:
lo=max(v,s-0x60); regs={}; svc_r0=None
for i in md.disasm(body[lo-v:s-v+2], lo):
m=i.mnemonic; op=i.op_str
if m in ('movs','mov.w','movw','mov') and ',' in op:
d,src=[x.strip() for x in op.split(',',1)]
if src.startswith('#'):
try: regs[d]=int(src[1:],0)
except: pass
elif src in regs: regs[d]=regs[src]
else: regs.pop(d,None)
elif m.startswith('str') and '[sp]' in op:
r=op.split(',')[0].strip()
if r in regs: out.setdefault(regs[r],[]).append(hex(s))
elif m.startswith('stm') and 'sp' in op.split('{')[0]:
inner=op.split('{')[1].split('}')[0]
first=inner.split(',')[0].strip() # STM writes the FIRST reg to [sp]
if first in regs: out.setdefault(regs[first],[]).append(hex(s))
return out
targets=[int(x,0) for x in sys.argv[1:]] or None
for name,p in MODS:
if not os.path.exists(p): continue
body,v=load(p); e=emitted(body,v)
if targets:
hit={k:v2 for k,v2 in e.items() if k in targets}
print(" %-8s emits %s"%(name, {hex(k):v2[:2] for k,v2 in sorted(hit.items())} or 'NONE'))
else:
print(" %-8s %d distinct opcodes: %s"%(name, len(e), sorted(hex(k) for k in e)[:24]))
|