Skip to content

Instantly share code, notes, and snippets.

@four0four
Last active Feb 12, 2022
Embed
What would you like to do?
Unicorn Engine - based Zynq bootrom emulation harness
#!/usr/bin/env python
import sys
from colors import *
from unicorn import *
from unicorn.arm_const import *
from capstone import Cs, CS_ARCH_ARM, CS_MODE_ARM, CsError
# hooks:
f_cov = open('coverage.txt', 'wb')
def hook_block(uc, address, size, user_data):
#print(">>> Tracing basic block at 0x%x, block size = 0x%x" %(address, size))
global f_cov
f_cov.write(b"ROM_bigger.bin+0x%x\n"%address)
def start_tracing_blocks(u, address, size, user_data):
u.hook_add(UC_HOOK_BLOCK, hook_block)
def dump_mem(u, address, size, user_data):
(addr, nbytes, outf) = user_data
d = u.mem_read(addr, nbytes)
with open(outf, 'wb') as f:
f.write(d)
print("dumped %d bytes from 0x%x to %s"%(nbytes, addr, outf))
def sha_hook(u, address, size, user_data):
src = u.reg_read(UC_ARM_REG_R0)
n = u.reg_read(UC_ARM_REG_R1)
dst = u.reg_read(UC_ARM_REG_R2)
print(green("sha(src: 0x%x, n: %x, dst: 0x%x)"%(src, n, dst)))
def sdio_read(u, address, size, user_data):
unk = u.reg_read(UC_ARM_REG_R0)
dest = u.reg_read(UC_ARM_REG_R1)
sdio_src = u.reg_read(UC_ARM_REG_R2) << 9
n_blocks = u.reg_read(UC_ARM_REG_R3)
lr = u.reg_read(UC_ARM_REG_LR);
print(green("sdio_read(drive: 0x%x, dst: 0x%x, sdio_src: 0x%x, nblock: 0x%x), lr == 0x%x"%(unk, dest, sdio_src>>9, n_blocks, lr)))
# with open("sd-old.bin", 'rb') as f:
with open("/dev/sdd1", 'rb') as f:
f.seek(sdio_src)
d = f.read(n_blocks << 9)
u.mem_write(dest, d)
# don't need the rest of the func, for now...hopefully ok?
u.reg_write(UC_ARM_REG_R0, 0)
u.reg_write(UC_ARM_REG_PC, u.reg_read(UC_ARM_REG_LR))
def fake_dma(u, address, size, user_data):
dst = 0x007021C
with open("payload_full.bin", "rb") as f:
b = f.read()
u.mem_write(dst, b)
print(yellow("faking %d bytes of DMA @ 0x%x"%(len(b), dst)))
break_temp = dict()
def print_retval(u, address, size, user_data):
global break_temp
def rval_cb(u, a, s, ud):
global break_temp
r0 = u.reg_read(UC_ARM_REG_R0)
print("%s() = 0x%x"%(ud, r0))
if a in break_temp:
u.hook_del(break_temp[a])
lr = u.reg_read(UC_ARM_REG_LR)
print("%s from 0x%x"%(user_data, lr))
h = u.hook_add(UC_HOOK_CODE, rval_cb, begin=lr, end=lr, user_data=user_data)
break_temp[lr] = h
def boot_fn_hook(u, address, size, user_data):
global break_temp
def print_bootdat(u, address, size, user_data):
global break_temp
dat = u.mem_read(user_data[0], user_data[1])
#print("read:\n"+"="*20+"\n%s\n"%dat.hex())
# this segfaults, lol.
# if address in break_temp:
# u.hook_del(break_temp[address])
offset = u.reg_read(UC_ARM_REG_R0)
dest = u.reg_read(UC_ARM_REG_R1)
nbytes = u.reg_read(UC_ARM_REG_R2)
print(green("run_boot_alg(%x, %x, %d)"%(offset, dest, nbytes)))
lr = u.reg_read(UC_ARM_REG_LR)
h = u.hook_add(UC_HOOK_CODE, print_bootdat, begin=lr, end=lr, user_data=(dest, nbytes))
break_temp[lr] = h
def f_open_hook(u, address, size, user_data):
fp = u.reg_read(UC_ARM_REG_R0)
path = u.reg_read(UC_ARM_REG_R1)
mode = u.reg_read(UC_ARM_REG_R2)
ptr = path
path_str = b""
while path_str[-1:] != b'\x00':
path_str += u.mem_read(ptr, 1)
ptr += 1
print("f_open(%x, %s, %x)"%(fp, path_str, mode))
def f_seek_hook(u, address, size, user_data):
fp = u.reg_read(UC_ARM_REG_R0)
offset = u.reg_read(UC_ARM_REG_R1)
print("f_seek(0x%x, 0x%x)"%(fp, offset))
def f_read_hook(u, address, size, user_data):
fd = u.reg_read(UC_ARM_REG_R0)
dest = u.reg_read(UC_ARM_REG_R1)
nbytes = u.reg_read(UC_ARM_REG_R2)
nbytes_out = u.reg_read(UC_ARM_REG_R3)
print("f_read(fp: 0x%x, dst: 0x%x, n: %d, n_out: 0x%x)"%(fd, dest, nbytes, nbytes_out))
def dmb_read_hook(u, address, size, user_data):
r0 = u.reg_read(UC_ARM_REG_R0)
lr = u.reg_read(UC_ARM_REG_LR)
"""
if r0 in DMB_READ_HOOKS:
r0r = DMB_READ_HOOKS[r0]
u.reg_write(UC_ARM_REG_R0, r0r)
u.reg_write(UC_ARM_REG_PC, u.reg_read(UC_ARM_REG_LR))
# print("dmb_read(0x%08x) = 0x%08x\n\t[LR = 0x%08x]"%(r0, r0r, lr))
return
"""
#print("dmb_read(0x%08x)\n\t[LR = 0x%08x]"%(r0, lr))
def dmb_writeb_hook(u, address, size, user_data):
r0 = u.reg_read(UC_ARM_REG_R0)
r1 = u.reg_read(UC_ARM_REG_R1)
lr = u.reg_read(UC_ARM_REG_LR)
# print("dmb_writeb(dst: 0x%08x, val: 0x%02x)\n\t[LR = 0x%08x]"%(r0, r1&0xff, lr))
def dmb_writew_hook(u, address, size, user_data):
r0 = u.reg_read(UC_ARM_REG_R0)
r1 = u.reg_read(UC_ARM_REG_R1)
lr = u.reg_read(UC_ARM_REG_LR)
# print("dmb_writew(dst: 0x%08x, val: 0x%08x)\n\t[LR = 0x%08x]"%(r0, r1, lr))
def skip_fn(u, address, size, user_data):
print(yellow("skipping %s"%user_data))
u.reg_write(UC_ARM_REG_PC, u.reg_read(UC_ARM_REG_LR))
def skip_fn_ret0(u, address, size, user_data):
print(yellow("skipping (r0=0) %s"%user_data))
u.reg_write(UC_ARM_REG_R0, 0)
u.reg_write(UC_ARM_REG_PC, u.reg_read(UC_ARM_REG_LR))
def skip_fn_ret1(u, address, size, user_data):
print(yellow("skipping (r0=1) %s"%user_data))
u.reg_write(UC_ARM_REG_R0, 1)
u.reg_write(UC_ARM_REG_PC, u.reg_read(UC_ARM_REG_LR))
def catch_wfe_loop(u, address, size, user_data):
r0 = u.reg_read(UC_ARM_REG_R0)
lr = u.reg_read(UC_ARM_REG_LR)
print(red("caught panic. reason: 0x%04x, lr: 0x%08x"%(r0,lr)))
u.emu_stop()
# memory callbacks
def always_val(u, access, address, size, value, user_data):
u.mem_write(address, user_data.to_bytes(4, 'little'))
def dump_writes(u, access, address, size, value, user_data):
print("writing 0x%08x to 0x%08x"%( value, address))
def setup_mem(u):
# load the rom
with open("bootrom.bin", 'rb') as f:
u.mem_map(0, 0x20000)
u.mem_write(0, f.read())
# setup some OCM
u.mem_map(0x40000, 0x40000)
# I/O peripherals
u.mem_map(0xe0000000, 0x300000)
# slcr peripherals
u.mem_map(0xf8000000, 0xc00)
# "ps system" registers
u.mem_map(0xf8001000, 0x80f000)
# cpu control
u.mem_map(0xf8900000, 0x603000)
# now populate some shit
def disas_one(u, addr):
global cd
insn = next(cd.disasm(u.mem_read(addr, 4), 4))
return insn.mnemonic + " " + insn.op_str
def dump_regs(u):
print("[R0]: 0x%08x, [R1]: 0x%08x, [R2]: 0x%08x"%(
u.reg_read(UC_ARM_REG_R0),
u.reg_read(UC_ARM_REG_R1),
u.reg_read(UC_ARM_REG_R2))
)
print("[R3]: 0x%08x, [R4]: 0x%08x, [R5]: 0x%08x"%(
u.reg_read(UC_ARM_REG_R3),
u.reg_read(UC_ARM_REG_R4),
u.reg_read(UC_ARM_REG_R5))
)
print("[R6]: 0x%08x, [R7]: 0x%08x, [R8]: 0x%08x"%(
u.reg_read(UC_ARM_REG_R6),
u.reg_read(UC_ARM_REG_R7),
u.reg_read(UC_ARM_REG_R8))
)
print("[R9]: 0x%08x, [R10]: 0x%08x, [R11]: 0x%08x"%(
u.reg_read(UC_ARM_REG_R9),
u.reg_read(UC_ARM_REG_R10),
u.reg_read(UC_ARM_REG_R11))
)
print("[R12]: 0x%08x, [SP]: 0x%08x, [PC]: 0x%08x"%(
u.reg_read(UC_ARM_REG_R12),
u.reg_read(UC_ARM_REG_SP),
u.reg_read(UC_ARM_REG_PC))
)
print("[LR]: 0x%08x"%(
u.reg_read(UC_ARM_REG_LR))
)
cpsr = u.reg_read(UC_ARM_REG_CPSR)
cpsr_str = \
(green("N") if (cpsr & 1<<31) else red("N")) + \
(green("Z") if (cpsr & 1<<30) else red("Z")) + \
(green("C") if (cpsr & 1<<29) else red("C")) + \
(green("V") if (cpsr & 1<<28) else red("V")) + \
(green("Q") if (cpsr & 1<<27) else red("Q")) + \
(green("J") if (cpsr & 1<<24) else red("J")) + \
(green("E") if (cpsr & 1<<9) else red("E")) + \
(green("A") if (cpsr & 1<<8) else red("A")) + \
(green("I") if (cpsr & 1<<7) else red("I")) + \
(green("F") if (cpsr & 1<<6) else red("F")) + \
(green("T") if (cpsr & 1<<5) else red("T")) + \
""
print("[CPSR]: %s (0x%08x)"%(cpsr_str, cpsr))
ROM_HOOKS = [\
# (0xAFB4, "dmb_read", dmb_read_hook),
(0xAFE8, "dmb_writeb", dmb_writeb_hook),
(0xB000, "dmb_writew", dmb_writew_hook),
(0x00D4, "invalidate_caches", skip_fn),
(0x102C, "save_rst_reason", skip_fn),
(0x0378, "set_gpios_bias_slew", skip_fn),
(0x02A8, "do_crcs", skip_fn),
(0xAF68, "timer_wait", skip_fn_ret1),
(0x07a4, "wfe_loop_securemode", catch_wfe_loop),
(0x1E28, "wfe_loop_securemode2", catch_wfe_loop),
(0x0C04, "halt_with_error", catch_wfe_loop),
(0x9AD8, red("fatfs_disk_status_mb"), print_retval),
(0x9AF4, red("fatfs_disk_initialize"), skip_fn_ret0),
# (0x59EC, red("check_header_chksum"), skip_fn_ret0),
(0x009EA8, "sdio_read", sdio_read),
(0x59AC, "check_hdr_magic", print_retval),
(0x0848C , "mount_vol", print_retval),
(0x083D8 , "check_fs", print_retval),
(0x8AB8 , "follow_path", print_retval),
(0x595C, "run_boot_alg", boot_fn_hook),
(0x008F7C, "f_read", f_read_hook),
(0x0091E0, "f_seek", f_seek_hook),
(0x008E7C, "f_open", f_open_hook),
(0x3238, "do_sha", sha_hook),
#(0x1960, "fake_dma", fake_dma),
(0x1980, (0x070220, 0x284, "fatfs_state.bin"), dump_mem),
# (0xA104 , red("asdf"), skip_fn),
]
MEM_HOOKS = [\
(0xE010002F, UC_HOOK_MEM_READ, always_val, 0),
(0xE010002C, UC_HOOK_MEM_READ, always_val, 2),
(0xF800702C, UC_HOOK_MEM_READ, always_val, 0),
(0xF800010C, UC_HOOK_MEM_READ, always_val, 0x15), # pll status
(0xF800025C, UC_HOOK_MEM_READ, always_val, 5), # bootmode == sdio
(0xE0100004, UC_HOOK_MEM_WRITE, dump_writes, 0),
(0xE0100008, UC_HOOK_MEM_WRITE, dump_writes, 0),
(0xE010000C, UC_HOOK_MEM_WRITE, dump_writes, 0),
# ( 0x07049C, UC_HOOK_MEM_READ, always_val, 0),
# (0xF800D010, UC_HOOK_MEM_READ, always_val, 0x400) # efuses - enable secureboot
# (0x70220, UC_HOOK_MEM_READ, always_val, 1),
]
def setup_hooks(u):
for (a, d, f) in ROM_HOOKS:
u.hook_add(UC_HOOK_CODE, f, begin=a, end=a, user_data = d)
for (a, t, f, v) in MEM_HOOKS:
u.hook_add(t, f, begin=a, end=a, user_data = v)
def dump_pc(u, before=3, after=3):
pc = u.reg_read(UC_ARM_REG_PC)
# print before
for i in range(pc-(before*4), pc, 4):
print("%08x %08x %s"%(i, int.from_bytes(u.mem_read(i, 4), 'big'), disas_one(u, i)))
print(green("===PC=== %08x %s"%(int.from_bytes(u.mem_read(pc, 4), 'big'), disas_one(u, pc))))
for i in range(pc+4, pc+(after*4)+4, 4):
print("%08x %08x %s"%(i, int.from_bytes(u.mem_read(i, 4), 'big'), disas_one(u, i)))
def dump_stack(u, before=3, after=3):
sp = u.reg_read(UC_ARM_REG_SP)
for i in range(sp-(before*4), sp, 4):
print("%08x %08x"%(i, int.from_bytes(u.mem_read(i, 4), 'little')))
print(green("===SP=== %08x"%(int.from_bytes(u.mem_read(sp, 4), 'little'))))
for i in range(sp+4, sp+(after*4)+4, 4):
print("%08x %08x"%(i, int.from_bytes(u.mem_read(i, 4), 'little')))
if __name__ == '__main__':
cd = Cs(CS_ARCH_ARM, CS_MODE_ARM)
u = Uc(UC_ARCH_ARM, UC_MODE_ARM)
setup_mem(u)
setup_hooks(u)
# fuck it, trace it all
u.hook_add(UC_HOOK_BLOCK, hook_block)
try:
u.emu_start(0, 0xfffffff, timeout=1000000, count=0)
except UcError as e:
print(red("ERROR: %s\n" % e))
dump_regs(u)
print("-"*20)
dump_stack(u)
print("-"*20)
dump_pc(u)
#print(u.mem_read(0x070490, 4).hex())
#print(u.mem_read(0x0070EB8, 4).hex())
f_cov.close()
#!/usr/bin/env python
import cmd
import sys
from colors import *
from unicorn import *
from unicorn.arm_const import *
from capstone import Cs, CS_ARCH_ARM, CS_MODE_ARM, CsError
# hooks:
f_cov = open('coverage.txt', 'wb')
def hook_block(uc, address, size, user_data):
#print(">>> Tracing basic block at 0x%x, block size = 0x%x" %(address, size))
global f_cov
f_cov.write(b"ROM_bigger.bin+0x%x\n"%address)
def start_tracing_blocks(u, address, size, user_data):
u.hook_add(UC_HOOK_BLOCK, hook_block)
break_temp = dict()
def print_retval(u, address, size, user_data):
global break_temp
def rval_cb(u, a, s, ud):
global break_temp
r0 = u.reg_read(UC_ARM_REG_R0)
print("%s() = 0x%x"%(ud, r0))
"""
if a in break_temp:
u.hook_del(break_temp[a])
"""
lr = u.reg_read(UC_ARM_REG_LR)
h = u.hook_add(UC_HOOK_CODE, rval_cb, begin=lr, end=lr, user_data=user_data)
break_temp[lr] = h
def boot_fn_hook(u, address, size, user_data):
global break_temp
def print_bootdat(u, address, size, user_data):
global break_temp
dat = u.mem_read(user_data[0], user_data[1])
#print("read:\n"+"="*20+"\n%s\n"%dat.hex())
# THIS SEGFAULT??
# if address in break_temp:
# u.hook_del(break_temp[address])
offset = u.reg_read(UC_ARM_REG_R0)
dest = u.reg_read(UC_ARM_REG_R1)
nbytes = u.reg_read(UC_ARM_REG_R2)
print(green("run_boot_alg(%x, %x, %d)"%(offset, dest, nbytes)))
lr = u.reg_read(UC_ARM_REG_LR)
h = u.hook_add(UC_HOOK_CODE, print_bootdat, begin=lr, end=lr, user_data=(dest, nbytes))
break_temp[lr] = h
def dmb_read_hook(u, address, size, user_data):
r0 = u.reg_read(UC_ARM_REG_R0)
lr = u.reg_read(UC_ARM_REG_LR)
"""
if r0 in DMB_READ_HOOKS:
r0r = DMB_READ_HOOKS[r0]
u.reg_write(UC_ARM_REG_R0, r0r)
u.reg_write(UC_ARM_REG_PC, u.reg_read(UC_ARM_REG_LR))
# print("dmb_read(0x%08x) = 0x%08x\n\t[LR = 0x%08x]"%(r0, r0r, lr))
return
"""
#print("dmb_read(0x%08x)\n\t[LR = 0x%08x]"%(r0, lr))
win = False
def log_success(u, address, size, user_data):
global win
win = True
u.emu_stop()
def dmb_writeb_hook(u, address, size, user_data):
r0 = u.reg_read(UC_ARM_REG_R0)
r1 = u.reg_read(UC_ARM_REG_R1)
lr = u.reg_read(UC_ARM_REG_LR)
# print("dmb_writeb(dst: 0x%08x, val: 0x%02x)\n\t[LR = 0x%08x]"%(r0, r1&0xff, lr))
def dmb_writew_hook(u, address, size, user_data):
r0 = u.reg_read(UC_ARM_REG_R0)
r1 = u.reg_read(UC_ARM_REG_R1)
lr = u.reg_read(UC_ARM_REG_LR)
# print("dmb_writew(dst: 0x%08x, val: 0x%08x)\n\t[LR = 0x%08x]"%(r0, r1, lr))
def skip_fn(u, address, size, user_data):
print(yellow("skipping %s"%user_data))
u.reg_write(UC_ARM_REG_PC, u.reg_read(UC_ARM_REG_LR))
def skip_fn_ret0(u, address, size, user_data):
print(yellow("skipping (r0=0) %s"%user_data))
u.reg_write(UC_ARM_REG_R0, 0)
u.reg_write(UC_ARM_REG_PC, u.reg_read(UC_ARM_REG_LR))
def skip_fn_ret1(u, address, size, user_data):
print(yellow("skipping (r0=1) %s"%user_data))
u.reg_write(UC_ARM_REG_R0, 1)
u.reg_write(UC_ARM_REG_PC, u.reg_read(UC_ARM_REG_LR))
def catch_wfe_loop(u, address, size, user_data):
r0 = u.reg_read(UC_ARM_REG_R0)
lr = u.reg_read(UC_ARM_REG_LR)
#print(red("caught panic. reason: 0x%04x, lr: 0x%08x"%(r0,lr)))
u.emu_stop()
# memory callbacks
def always_val(u, access, address, size, value, user_data):
u.mem_write(address, user_data.to_bytes(4, 'little'))
def setup_mem(u):
# load the rom
with open("bootrom.bin", 'rb') as f:
u.mem_map(0, 0x20000)
u.mem_write(0, f.read())
# setup some OCM
u.mem_map(0x40000, 0x40000)
# I/O peripherals
u.mem_map(0xe0000000, 0x300000)
# slcr peripherals
u.mem_map(0xf8000000, 0xc00)
# "ps system" registers
u.mem_map(0xf8001000, 0x80f000)
# cpu control
u.mem_map(0xf8900000, 0x603000)
# now populate some shit
def disas_one(u, addr):
global cd
insn = next(cd.disasm(u.mem_read(addr, 4), 4))
return insn.mnemonic + " " + insn.op_str
def dump_regs(u):
print("[R0]: 0x%08x, [R1]: 0x%08x, [R2]: 0x%08x"%(
u.reg_read(UC_ARM_REG_R0),
u.reg_read(UC_ARM_REG_R1),
u.reg_read(UC_ARM_REG_R2))
)
print("[R3]: 0x%08x, [R4]: 0x%08x, [R5]: 0x%08x"%(
u.reg_read(UC_ARM_REG_R3),
u.reg_read(UC_ARM_REG_R4),
u.reg_read(UC_ARM_REG_R5))
)
print("[R6]: 0x%08x, [R7]: 0x%08x, [R8]: 0x%08x"%(
u.reg_read(UC_ARM_REG_R6),
u.reg_read(UC_ARM_REG_R7),
u.reg_read(UC_ARM_REG_R8))
)
print("[R9]: 0x%08x, [R10]: 0x%08x, [R11]: 0x%08x"%(
u.reg_read(UC_ARM_REG_R9),
u.reg_read(UC_ARM_REG_R10),
u.reg_read(UC_ARM_REG_R11))
)
print("[R12]: 0x%08x, [SP]: 0x%08x, [PC]: 0x%08x"%(
u.reg_read(UC_ARM_REG_R12),
u.reg_read(UC_ARM_REG_SP),
u.reg_read(UC_ARM_REG_PC))
)
print("[LR]: 0x%08x"%(
u.reg_read(UC_ARM_REG_LR))
)
cpsr = u.reg_read(UC_ARM_REG_CPSR)
cpsr_str = \
(green("N") if (cpsr & 1<<31) else red("N")) + \
(green("Z") if (cpsr & 1<<30) else red("Z")) + \
(green("C") if (cpsr & 1<<29) else red("C")) + \
(green("V") if (cpsr & 1<<28) else red("V")) + \
(green("Q") if (cpsr & 1<<27) else red("Q")) + \
(green("J") if (cpsr & 1<<24) else red("J")) + \
(green("E") if (cpsr & 1<<9) else red("E")) + \
(green("A") if (cpsr & 1<<8) else red("A")) + \
(green("I") if (cpsr & 1<<7) else red("I")) + \
(green("F") if (cpsr & 1<<6) else red("F")) + \
(green("T") if (cpsr & 1<<5) else red("T")) + \
""
print("[CPSR]: %s (0x%08x)"%(cpsr_str, cpsr))
ROM_HOOKS = [\
(0x07a4, "wfe_loop_securemode", catch_wfe_loop),
(0x1E28, "wfe_loop_securemode2", catch_wfe_loop),
(0x0C04, "halt_with_error", catch_wfe_loop),
(0x595C, "run_boot_alg", boot_fn_hook),
(0x5F8C, "success", log_success),
]
MEM_HOOKS = [\
(0xE010002F, UC_HOOK_MEM_READ, always_val, 0),
(0xE010002C, UC_HOOK_MEM_READ, always_val, 2),
(0xF800702C, UC_HOOK_MEM_READ, always_val, 0),
(0xF800010C, UC_HOOK_MEM_READ, always_val, 0x15), # pll status
(0xF800025C, UC_HOOK_MEM_READ, always_val, 5), # bootmode == sdio
(0xF800D010, UC_HOOK_MEM_READ, always_val, 0x400) # efuses - enable secureboot
# (0x70220, UC_HOOK_MEM_READ, always_val, 1),
]
def setup_hooks(u):
for (a, d, f) in ROM_HOOKS:
u.hook_add(UC_HOOK_CODE, f, begin=a, end=a, user_data = d)
for (a, t, f, v) in MEM_HOOKS:
u.hook_add(t, f, begin=a, end=a, user_data = v)
def dump_pc(u, before=3, after=3):
pc = u.reg_read(UC_ARM_REG_PC)
# print before
for i in range(pc-(before*4), pc, 4):
print("%08x %08x %s"%(i, int.from_bytes(u.mem_read(i, 4), 'big'), disas_one(u, i)))
print(green("===PC=== %08x %s"%(int.from_bytes(u.mem_read(pc, 4), 'big'), disas_one(u, pc))))
for i in range(pc+4, pc+(after*4)+4, 4):
print("%08x %08x %s"%(i, int.from_bytes(u.mem_read(i, 4), 'big'), disas_one(u, i)))
if __name__ == '__main__':
cd = Cs(CS_ARCH_ARM, CS_MODE_ARM)
u = Uc(UC_ARCH_ARM, UC_MODE_ARM)
setup_mem(u)
setup_hooks(u)
# fuck it, trace it all
u.hook_add(UC_HOOK_BLOCK, hook_block)
if "--secure" in sys.argv:
# secure boot range:
u.reg_write(UC_ARM_REG_R5, 0xF8000100)
u.reg_write(UC_ARM_REG_R6, 0xF80001AC)
else:
# standard range:
u.reg_write(UC_ARM_REG_R5, 0xE0001000)
u.reg_write(UC_ARM_REG_R6, 0xF8006FFC)
u.reg_write(UC_ARM_REG_SP, 0x7D4A0)
u.reg_write(UC_ARM_REG_PC, 0x05C6C)
if sys.argv[1] == "all":
# for testing
reg_first = 0xE0001000
#reg_first = 0xf8000000-0x10
reg_last = 0xF8007000
base = u.context_save()
reg_test = reg_first
f_ok = open("allowed.txt", 'wb+')
f_blocked = open("blocked.txt", 'wb+')
ranges = [\
(0xE0001000, 0xE0010000),
(0xE0100000, 0xE0102000),
(0xF8000000, 0xF8010000),
# (0xF8898000, 0xF889D000),
# (0xF8800000, 0xF880B000),
# (0xf8f00000, 0xf8f08000),
]
for (reg_test, reg_last) in ranges:
while reg_test != reg_last:
u.context_restore(base)
u.reg_write(UC_ARM_REG_R0, reg_test)
try:
u.emu_start(0x05C6C, 0xfffffff, timeout=1000000, count=0)
except UcError as e:
print(red("ERROR: %s\n" % e))
dump_regs(u)
print("-"*20)
dump_pc(u)
if win:
#print(green("OK: 0x%x"%reg_test))
f_ok.write(b"0x%x\n"%reg_test)
else:
f_blocked.write(b"0x%x\n"%reg_test)
#print(red("No: 0x%x"%reg_test))
win = False
reg_test += 4
if reg_test & 0xfffff000 == reg_test:
print("0x%x"%reg_test)
f_cov.close()
f_ok.close()
f_blocked.close()
else:
reg_test = int(sys.argv[1], 0)
print("testing RIL access to 0x%x..."%reg_test)
u.reg_write(UC_ARM_REG_R0, reg_test)
try:
u.emu_start(0x05C6C, 0xfffffff, timeout=1000000, count=0)
except UcError as e:
print(red("ERROR: %s\n" % e))
dump_regs(u)
print("-"*20)
dump_pc(u)
if win:
print(green("OK: 0x%x"%reg_test))
else:
print(red("No: 0x%x"%reg_test))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment