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
|
import sys, os, importlib.util
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
import unicorn
from unicorn import UC_HOOK_MEM_WRITE, UC_HOOK_CODE, UC_HOOK_BLOCK
from unicorn.arm_const import UC_ARM_REG_PC, UC_ARM_REG_SP
_s = importlib.util.spec_from_file_location("tasmod", os.path.join(os.path.dirname(__file__),"boot_sos_and_tas.py"))
T = importlib.util.module_from_spec(_s); _s.loader.exec_module(T)
GPTR=0x81B8
def boot():
c,ccp,exc=T.build(); T.stage_all(c,verbose=False); return c
def run(c, done, extra_hooks=None):
if extra_hooks: extra_hooks(c)
c.uc.reg_write(UC_ARM_REG_SP,0x3F000)
T.run_system(c, seconds=float(os.environ.get("RUN_SECONDS","120")), done=done, verbose=False)
# ---- phase 1: reach TA load, resolve G and A=G+0xC and the cookie value ----
c=boot(); loads=[]
c.uc.hook_add(UC_HOOK_CODE, lambda uc,a,s,u: loads.append(T.LOAD_RETS[a]) if a in T.LOAD_RETS else None,
begin=0x204000, end=0x205000)
run(c, done=lambda: len(loads)>=4)
G=int.from_bytes(c.uc.mem_read(GPTR,4),"little")
print("phase1: loads=%d G=*0x81B8=%#x"%(len(loads),G))
if not G:
print("G still 0 -> boot did not set it; abort"); sys.exit()
A=G+0xC; cookie=int.from_bytes(c.uc.mem_read(A,4),"little")
print("phase1: A=G+0xC=%#x cookie(value SVC0xA2 reads)=%#010x"%(A,cookie))
# ---- phase 2: targeted write hook on [A,A+4), log every writer ----
c2=boot(); writers=[]; loads2=[]
def hooks(c):
c.uc.hook_add(UC_HOOK_MEM_WRITE,
lambda uc,acc,addr,sz,val,u: writers.append((uc.reg_read(UC_ARM_REG_PC),addr,sz,val)),
begin=A, end=A+3)
c.uc.hook_add(UC_HOOK_CODE, lambda uc,a,s,u: loads2.append(T.LOAD_RETS[a]) if a in T.LOAD_RETS else None,
begin=0x204000, end=0x205000)
run(c2, done=lambda: len(loads2)>=4, extra_hooks=hooks)
print("phase2: writes to A=%#x : %d"%(A,len(writers)))
for pc,addr,sz,val in writers[-20:]:
print(" PC=%#010x addr=%#x sz=%d value=%#010x"%(pc,addr,sz,val))
|