Implement coprocessor register read/write for python bindings
This commit is contained in:
parent
89a1da9a33
commit
15f3b58d9b
|
@ -98,8 +98,29 @@ def test_thumb():
|
|||
except UcError as e:
|
||||
print("ERROR: %s" % e)
|
||||
|
||||
def test_read_sctlr():
|
||||
print("Read SCTLR")
|
||||
try:
|
||||
# Initialize emulator in thumb mode
|
||||
mu = Uc(UC_ARCH_ARM, UC_MODE_ARM)
|
||||
|
||||
# Read SCTLR
|
||||
# cp = 15
|
||||
# is64 = 0
|
||||
# sec = 0
|
||||
# crn = 1
|
||||
# crm = 0
|
||||
# opc1 = 0
|
||||
# opc2 = 0
|
||||
val = mu.reg_read(UC_ARM_REG_CP_REG, (15, 0, 0, 1, 0, 0, 0))
|
||||
print(">>> SCTLR = 0x%x" % val)
|
||||
|
||||
except UcError as e:
|
||||
print("ERROR: %s" % e)
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_arm()
|
||||
print("=" * 26)
|
||||
test_thumb()
|
||||
print("=" * 26)
|
||||
test_read_sctlr()
|
||||
|
|
|
@ -64,5 +64,25 @@ def test_arm64():
|
|||
print("ERROR: %s" % e)
|
||||
|
||||
|
||||
def test_arm64_read_sctlr():
|
||||
print("Read SCTLR_EL1")
|
||||
try:
|
||||
# Initialize emulator in ARM mode
|
||||
mu = Uc(UC_ARCH_ARM64, UC_MODE_ARM)
|
||||
|
||||
# Read SCTLR_EL1
|
||||
# crn = 1;
|
||||
# crm = 0;
|
||||
# op0 = 3;
|
||||
# op1 = 0;
|
||||
# op2 = 0;
|
||||
val = mu.reg_read(UC_ARM64_REG_CP_REG, (1, 0, 3, 0, 0))
|
||||
print(">>> SCTLR_EL1 = 0x%x" % val)
|
||||
|
||||
except UcError as e:
|
||||
print("ERROR: %s" % e)
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_arm64()
|
||||
print("=" * 26)
|
||||
test_arm64_read_sctlr()
|
||||
|
|
|
@ -11,7 +11,7 @@ import sys
|
|||
import weakref
|
||||
import functools
|
||||
|
||||
from . import x86_const, arm64_const, unicorn_const as uc
|
||||
from . import x86_const, arm_const, arm64_const, unicorn_const as uc
|
||||
|
||||
if not hasattr(sys.modules[__name__], "__file__"):
|
||||
__file__ = inspect.getfile(inspect.currentframe())
|
||||
|
@ -261,8 +261,29 @@ def reg_read(reg_read_func, arch, reg_id, opt=None):
|
|||
raise UcError(status)
|
||||
return reg.value
|
||||
|
||||
if arch == uc.UC_ARCH_ARM:
|
||||
if reg_id == arm_const.UC_ARM_REG_CP_REG:
|
||||
reg = uc_arm_cp_reg()
|
||||
if not isinstance(opt, tuple) or len(opt) != 7:
|
||||
raise UcError(uc.UC_ERR_ARG)
|
||||
reg.cp, reg.is64, reg.sec, reg.crn, reg.crm, reg.opc1, reg.opc2 = opt
|
||||
status = reg_read_func(reg_id, ctypes.byref(reg))
|
||||
if status != uc.UC_ERR_OK:
|
||||
raise UcError(status)
|
||||
return reg.val
|
||||
|
||||
if arch == uc.UC_ARCH_ARM64:
|
||||
if reg_id in range(arm64_const.UC_ARM64_REG_Q0, arm64_const.UC_ARM64_REG_Q31+1) or range(arm64_const.UC_ARM64_REG_V0, arm64_const.UC_ARM64_REG_V31+1):
|
||||
if reg_id == arm64_const.UC_ARM64_REG_CP_REG:
|
||||
reg = uc_arm64_cp_reg()
|
||||
if not isinstance(opt, tuple) or len(opt) != 5:
|
||||
raise UcError(uc.UC_ERR_ARG)
|
||||
reg.crn, reg.crm, reg.op0, reg.op1, reg.op2 = opt
|
||||
status = reg_read_func(reg_id, ctypes.byref(reg))
|
||||
if status != uc.UC_ERR_OK:
|
||||
raise UcError(status)
|
||||
return reg.val
|
||||
|
||||
elif reg_id in range(arm64_const.UC_ARM64_REG_Q0, arm64_const.UC_ARM64_REG_Q31+1) or range(arm64_const.UC_ARM64_REG_V0, arm64_const.UC_ARM64_REG_V31+1):
|
||||
reg = uc_arm64_neon128()
|
||||
status = reg_read_func(reg_id, ctypes.byref(reg))
|
||||
if status != uc.UC_ERR_OK:
|
||||
|
@ -312,6 +333,19 @@ def reg_write(reg_write_func, arch, reg_id, value):
|
|||
reg.low_qword = value & 0xffffffffffffffff
|
||||
reg.high_qword = value >> 64
|
||||
|
||||
if arch == uc.UC_ARCH_ARM:
|
||||
if reg_id == arm64_const.UC_ARM64_REG_CP_REG:
|
||||
reg = uc_arm64_cp_reg()
|
||||
if not isinstance(value, tuple) or len(value) != 6:
|
||||
raise UcError(uc.UC_ERR_ARG)
|
||||
reg.crn, reg.crm, reg.op0, reg.op1, reg.op2, reg.val = value
|
||||
|
||||
elif reg_id == arm_const.UC_ARM_REG_CP_REG:
|
||||
reg = uc_arm_cp_reg()
|
||||
if not isinstance(value, tuple) or len(value) != 8:
|
||||
raise UcError(uc.UC_ERR_ARG)
|
||||
reg.cp, reg.is64, reg.sec, reg.crn, reg.crm, reg.opc1, reg.opc2, reg.val = value
|
||||
|
||||
if reg is None:
|
||||
# convert to 64bit number to be safe
|
||||
reg = ctypes.c_uint64(value)
|
||||
|
@ -342,6 +376,29 @@ def _catch_hook_exception(func):
|
|||
return wrapper
|
||||
|
||||
|
||||
class uc_arm_cp_reg(ctypes.Structure):
|
||||
"""ARM coprocessors registers for instructions MRC, MCR, MRRC, MCRR"""
|
||||
_fields_ = [
|
||||
("cp", ctypes.c_uint32),
|
||||
("is64", ctypes.c_uint32),
|
||||
("sec", ctypes.c_uint32),
|
||||
("crn", ctypes.c_uint32),
|
||||
("crm", ctypes.c_uint32),
|
||||
("opc1", ctypes.c_uint32),
|
||||
("opc2", ctypes.c_uint32),
|
||||
("val", ctypes.c_uint64)
|
||||
]
|
||||
|
||||
class uc_arm64_cp_reg(ctypes.Structure):
|
||||
"""ARM64 coprocessors registers for instructions MRS, MSR"""
|
||||
_fields_ = [
|
||||
("crn", ctypes.c_uint32),
|
||||
("crm", ctypes.c_uint32),
|
||||
("op0", ctypes.c_uint32),
|
||||
("op1", ctypes.c_uint32),
|
||||
("op2", ctypes.c_uint32),
|
||||
("val", ctypes.c_uint64)
|
||||
]
|
||||
|
||||
class uc_x86_mmr(ctypes.Structure):
|
||||
"""Memory-Management Register for instructions IDTR, GDTR, LDTR, TR."""
|
||||
|
|
Loading…
Reference in New Issue