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
|
#!/usr/bin/env python3
"""Check if signed 0x10A2 reaches input-label strlen after natural crypto gate.
No crypto result bytes are printed. Early return is a useful negative control.
"""
from pathlib import Path
import sys
from unicorn import UC_HOOK_CODE
from unicorn.arm_const import UC_ARM_REG_R0,UC_ARM_REG_R1,UC_ARM_REG_R2,UC_ARM_REG_SP,UC_ARM_REG_LR
sys.path.insert(0,str(Path(__file__).resolve().parents[1]))
from pspemu import sysdrv_env
from pspemu.component import Fault
SIGNED=Path(__file__).resolve().parents[2]/'psp_out/elf/sys_drv_0.49.0.54_18bd9d26.elf'
STRLEN=0xE01864
def main():
sd=sysdrv_env.make()
assert Path(sd.image_path).read_bytes()==SIGNED.read_bytes()
r,f,_=sysdrv_env.run_init(sd)
assert r==0 and not f and sysdrv_env.init_flag(sd)==1
req,cfg,label,salt,out=[sd.alloc(n) for n in (0x100,0x400,0x40,0x40,0x40)]
sd.write(cfg,bytes(0x400));sd.write(label,b'NAME_XYZ\0'+bytes(0x37))
sd.write(salt,b'ABCD'+bytes(0x3C));sd.write(out,bytes(0x40))
seen=[];suspicious_copies=[]
sd.uc.hook_add(UC_HOOK_CODE,lambda uc,ea,size,data:seen.append(uc.reg_read(UC_ARM_REG_R0)),
begin=STRLEN,end=STRLEN+1)
def copy_entry(uc,ea,size,data):
dest=uc.reg_read(UC_ARM_REG_R0)
if dest<0x10000:
suspicious_copies.append((dest,uc.reg_read(UC_ARM_REG_R1),
uc.reg_read(UC_ARM_REG_R2),uc.reg_read(UC_ARM_REG_LR)))
sd.uc.hook_add(UC_HOOK_CODE,copy_entry,begin=0xE0192C,end=0xE0192D)
sd.write(req,bytes(0x100))
for i,v in ((0,0x10A2),(1,2),(2,label),(3,4),(4,salt),(5,4),(6,out),(7,32),
(sysdrv_env.REQ_CONFIG_DWORD,cfg)):
sd.wr32(req+4*i,v)
try:
rv=sd.run_function(0xE087E4,(req,2,0,0),count=4_000_000,timeout=4_000_000)
print(f'signed 0x10A2 natural emulator: status={rv:#x}, label_strlen_seen={label in seen}, strlen_calls={len(seen)}')
except Fault as exc:
assert exc.pc==0xE01940 and exc.addr==0x680 and label not in seen,(exc.pc,exc.addr,len(seen))
assert suspicious_copies==[(0x680,0xE23050,32,0xE146E5)],suspicious_copies
print('signed 0x10A2 emulator stopped before label strlen: '
f'copy_caller={suspicious_copies[0][3]:#x}, FAR={exc.addr:#x}, '
'zero synthetic crypto base; no key material printed')
if __name__=='__main__':main()
|