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.63k stars 1.35k forks source link

Broken python bindings - Cant reg_write to UC_ARM64_REG_CP_REG #1664

Closed pellsson closed 2 years ago

pellsson commented 2 years ago

It is impossible to reg_write to UC_ARM64_REG_CP_REG because it is incorrectly executed under UC_ARCH_ARM (as opposed to UC_ARCH_ARM64 where it should be executed.)

In unicorn.py!reg_write():

    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 reg_id in range(arm64_const.UC_ARM64_REG_V0, arm64_const.UC_ARM64_REG_V31+1):
            reg = uc_arm64_neon128()
            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

Change to:

    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 reg_id in range(arm64_const.UC_ARM64_REG_V0, arm64_const.UC_ARM64_REG_V31+1):
            reg = uc_arm64_neon128()
            reg.low_qword = value & 0xffffffffffffffff
            reg.high_qword = value >> 64
        elif 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

    if arch == uc.UC_ARCH_ARM:
        if 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
wtdcode commented 2 years ago

Fixed in 5b5905695d4d9759c0d7f6665673ddeb7ea8beef