unicorn-engine / unicorn

Unicorn CPU emulator framework (ARM, AArch64, M68K, Mips, Sparc, PowerPC, RiscV, S390x, TriCore, X86)
http://www.unicorn-engine.org
GNU General Public License v2.0
7.34k stars 1.31k forks source link

UC_ERR_INSN_INVALID while emulating the mrc arm32 instruction. #1860

Open F1o0T opened 11 months ago

F1o0T commented 11 months ago

Although, there is already an implementation for the mrc instruction in this commit

The following code doesn't work, although capstone is able to disassemble that instuction

#!/usr/bin/env python

from __future__ import print_function
from unicorn import *
from unicorn.arm_const import *
from capstone import *

# code to be emulated
ARM_CODE   = b"\x31\x0f\x19\xee"
ADDRESS    = 0x10000

# 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))

# Test ARM
def test_arm():
    print("Emulate ARM code")
    # Initialize emulator in ARM mode
    mu = Uc(UC_ARCH_ARM, UC_MODE_ARM)

    # 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, ARM_CODE)

    # tracing all basic blocks with customized callback
    mu.hook_add(UC_HOOK_BLOCK, hook_block)

    # tracing one instruction at ADDRESS with customized callback
    mu.hook_add(UC_HOOK_CODE, hook_code, begin=ADDRESS, end=ADDRESS)

    md = Cs(CS_ARCH_ARM, CS_MODE_ARM)
    for insn in md.disasm(ARM_CODE, ADDRESS):
        print("0x%x:\t%s\t%s" % (insn.address, insn.mnemonic, insn.op_str))

    # emulate machine code in infinite time
    mu.emu_start(ADDRESS, ADDRESS + len(ARM_CODE))

if __name__ == '__main__':
    test_arm()

Here is the output.

python3 testMRC.py
Emulate ARM code
0x10000:    mrc p15, #0, r0, c9, c1, #1
>>> Tracing basic block at 0x10000, block size = 0x4
Traceback (most recent call last):
  File "/home/f1o0t/projects/testUnicorn/bindings/python/testMRC.py", line 50, in <module>
    test_arm()
  File "/home/f1o0t/projects/testUnicorn/bindings/python/testMRC.py", line 46, in test_arm
    mu.emu_start(ADDRESS, ADDRESS + len(ARM_CODE))
  File "/home/f1o0t/projects/testUnicorn/bindings/python/unicorn/unicorn.py", line 547, in emu_start
    raise UcError(status)
unicorn.unicorn.UcError: Invalid instruction (UC_ERR_INSN_INVALID)

Any idea how can I let unicron intepret this instruction successfully?

wtdcode commented 11 months ago

Did you try dev branch? I have pushed a possible related fix.

F1o0T commented 11 months ago

I have just tried the dev branch, and it did'nt work. Still I see the same error.

wtdcode commented 11 months ago

I checked a bit. The coprocessor register you are accessing doesn't exist. Please try another CPU model and refer to ARM documents for further information.