Permalink
Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.
Sign up
Fetching contributors…
Cannot retrieve contributors at this time.
Cannot retrieve contributors at this time
| #!/usr/bin/env python3 | |
| # Demonstartion of using PANDA to run shellcode. Example modified from Unicorn Engine | |
| # https://github.com/unicorn-engine/unicorn/blob/master/bindings/python/sample_arm.py | |
| import capstone | |
| import os | |
| from panda import Panda, ffi | |
| from panda.arm.helper import dump_regs, registers | |
| ARM_CODE = b"\x37\x00\xa0\xe3\x03\x10\x42\xe0" # mov r0, #0x37; sub r1, r2, r3 | |
| ADDRESS = 0x1000 | |
| stop_addr = ADDRESS + len(ARM_CODE) | |
| # Create a machine of type 'configurable' but with just a CPU specified (no peripherals or memory maps) | |
| panda = Panda("arm", extra_args=["-M", "configurable", "-nographic"]) | |
| @panda.cb_after_machine_init | |
| def setup(cpu): | |
| ''' | |
| After our CPU has been created, allocate memory and set starting state | |
| ''' | |
| # map 2MB memory for this emulation | |
| panda.map_memory("mymem", 2 * 1024 * 1024, ADDRESS) | |
| # Write code into memory | |
| panda.physical_memory_write(ADDRESS, ARM_CODE) | |
| # Set up registers | |
| cpu.env_ptr.regs[registers['R0']] = 0x1234 | |
| cpu.env_ptr.regs[registers['R2']] = 0x6789 | |
| cpu.env_ptr.regs[registers['R3']] = 0x3333 | |
| # Set starting_pc | |
| cpu.env_ptr.regs[registers['IP']] = ADDRESS | |
| # Apply taint label to r2 | |
| panda.taint_label_reg(registers['R2'], 10) # Taint R2 with label 10. Should prop into R1 | |
| @panda.cb_insn_translate | |
| def should_run_on_insn(env, pc): | |
| ''' | |
| At each basic block, decide if we run on_insn for each contained | |
| instruction. For now, always return True unless we're past stop_addr | |
| Alternatively could be implemented as | |
| panda.cb_insn_translate(lambda x,y: True) | |
| ''' | |
| return True | |
| md = capstone.Cs(capstone.CS_ARCH_ARM, capstone.CS_MODE_ARM) | |
| @panda.cb_insn_exec | |
| def on_insn(cpu, pc): | |
| ''' | |
| At each instruction, print capstone disassembly. | |
| When we reach stop_addr, dump registers and shutdown | |
| ''' | |
| if pc == stop_addr: | |
| print("Finished execution. CPU registers are:") | |
| dump_regs(panda, cpu) | |
| print("Taint results\n") | |
| if panda.taint_check_reg(registers['R1']): | |
| for idx, byte_taint in enumerate(panda.taint_get_reg(registers['R1'])): | |
| labels = byte_taint.get_labels() | |
| print(f"Register R1 byte {idx} tainted by {labels}") | |
| # TODO: we need a better way to stop execution in the middle of a basic block | |
| os._exit(0) | |
| code = panda.virtual_memory_read(cpu, pc, 12) | |
| for i in md.disasm(code, pc): | |
| print("0x%x:\t%s\t%s" %(i.address, i.mnemonic, i.op_str)) | |
| break | |
| return 0 | |
| # Start PANDA running. Callback functions will be called as necessary | |
| panda.run() |