Last active
April 10, 2022 23:39
-
-
Save DavidBuchanan314/37c3f55bd4d5f9f66d952e38c71ecbba to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# based on https://github.com/unicorn-engine/unicorn/blob/master/bindings/python/sample_arm.py | |
from __future__ import print_function | |
from unicorn import * | |
from unicorn.arm_const import * | |
# https://github.com/raspberrypi/pico-bootrom/blob/ef22cd8ede5bc007f81d7f2416b48db90f313434/bootrom/bootrom_rt0.S#L441-L445 | |
CODE = bytes.fromhex(""" | |
.byte 0x11, 0x38, 0xc0, 0x7a, 0x00, 0xbd, 0x00, 0xb5 | |
.byte 0x42, 0x40, 0x00, 0x2a, 0x00, 0xf0, 0x02, 0xf8 | |
.byte 0xf6, 0xd2, 0x8e, 0x46, 0x70, 0x46, 0x00, 0x47 | |
""".replace(".byte", "").replace("0x", "").replace(",", "")) | |
""" | |
Disassembly: | |
00: 11 38 subs r0, #0x11 | |
02: C0 7A ldrb r0, [r0, #0xb] | |
04: 00 BD pop {pc} | |
06: 00 B5 push {lr} <--- entrypoint | |
08: 42 40 eors r2, r0 | |
0a: 00 2A cmp r2, #0 | |
0c: 00 F0 02 F8 bl #0x14 | |
10: F6 D2 bhs #0 | |
12: 8E 46 mov lr, r1 | |
14: 70 46 mov r0, lr | |
16: 00 47 bx r0 | |
""" | |
# memory address where emulation starts | |
ADDRESS = 0x100000 | |
# callback for tracing basic blocks | |
def hook_block(uc, address, size, user_data): | |
print(">>> Tracing basic block at 0x%x, block size = 0x%x" %(address, size)) | |
# callback for tracing instructions | |
def hook_code(uc, address, size, user_data): | |
print(">>> Tracing instruction at 0x%x, instruction size = 0x%x" %(address, size)) | |
def test_thumb(): | |
print("Emulate THUMB code") | |
try: | |
# Initialize emulator in thumb mode | |
mu = Uc(UC_ARCH_ARM, UC_MODE_THUMB) | |
# map 2MB memory for this emulation | |
mu.mem_map(ADDRESS, 2 * 1024 * 1024) | |
# write machine code to be emulated to memory | |
mu.mem_write(ADDRESS, CODE) | |
# initialize machine registers | |
mu.reg_write(UC_ARM_REG_SP, ADDRESS + 0x1000) | |
# tracing all basic blocks with customized callback | |
mu.hook_add(UC_HOOK_BLOCK, hook_block) | |
# tracing all instructions with customized callback | |
mu.hook_add(UC_HOOK_CODE, hook_code) | |
# emulate machine code in infinite time | |
# Note we start at ADDRESS | 1 to indicate THUMB mode. | |
try: | |
mu.emu_start((ADDRESS + 6) | 1, ADDRESS + len(CODE)) | |
except: | |
# we'll get a segfault when the function tries to return to a nonexistent address | |
# (could be solved by pushing a real address onto the stack first) | |
pass | |
# now print out some registers | |
print(">>> Emulation done. Below is the CPU context") | |
r0 = mu.reg_read(UC_ARM_REG_R0) | |
print(">>> r0 = %u" % r0) | |
except UcError as e: | |
print("ERROR: %s" % e) | |
if __name__ == '__main__': | |
test_thumb() | |
""" | |
Output: | |
Emulate THUMB code | |
>>> Tracing basic block at 0x100006, block size = 0xa | |
>>> Tracing instruction at 0x100006, instruction size = 0x2 | |
>>> Tracing instruction at 0x100008, instruction size = 0x2 | |
>>> Tracing instruction at 0x10000a, instruction size = 0x2 | |
>>> Tracing instruction at 0x10000c, instruction size = 0x4 | |
>>> Tracing basic block at 0x100014, block size = 0x4 | |
>>> Tracing instruction at 0x100014, instruction size = 0x2 | |
>>> Tracing instruction at 0x100016, instruction size = 0x2 | |
>>> Tracing basic block at 0x100010, block size = 0x2 | |
>>> Tracing instruction at 0x100010, instruction size = 0x2 | |
>>> Tracing basic block at 0x100000, block size = 0x6 | |
>>> Tracing instruction at 0x100000, instruction size = 0x2 | |
>>> Tracing instruction at 0x100002, instruction size = 0x2 | |
>>> Tracing instruction at 0x100004, instruction size = 0x2 | |
>>> Emulation done. Below is the CPU context | |
>>> r0 = 42 | |
""" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment