diff options
| author | Galen Williamson <galen@vector35.com> | 2025-06-09 19:30:13 -0400 |
|---|---|---|
| committer | Galen Williamson <galen@vector35.com> | 2025-06-09 19:30:13 -0400 |
| commit | 35c2a4cf35589e1c3046ecbe2c480a57b6d10360 (patch) | |
| tree | 9c95fc3d75c0c376c82e4fbe7e197ec5352260f8 /arch | |
| parent | 9373cab26ee2e7b2febab7674360d54d6fb8adc6 (diff) | |
[thumb2] Converted MSR system registers into enum
Diffstat (limited to 'arch')
| -rw-r--r-- | arch/armv7/arch_armv7.cpp | 26 | ||||
| -rw-r--r-- | arch/armv7/armv7_disasm/armv7.c | 24 | ||||
| -rw-r--r-- | arch/armv7/armv7_disasm/armv7.h | 14 | ||||
| -rw-r--r-- | arch/armv7/thumb2_disasm/arch_thumb2.cpp | 142 | ||||
| -rw-r--r-- | arch/armv7/thumb2_disasm/il_thumb2.cpp | 136 | ||||
| -rwxr-xr-x | arch/armv7/thumb2_disasm/test.py | 41 |
6 files changed, 315 insertions, 68 deletions
diff --git a/arch/armv7/arch_armv7.cpp b/arch/armv7/arch_armv7.cpp index 08191de5..5739a8bd 100644 --- a/arch/armv7/arch_armv7.cpp +++ b/arch/armv7/arch_armv7.cpp @@ -1895,19 +1895,21 @@ vector<uint32_t> ArmCommonArchitecture::GetAllRegisters() REG_Q8, REG_Q9, REG_Q10, REG_Q11, REG_Q12, REG_Q13, REG_Q14, REG_Q15, /* special registers */ - REGS_APSR, REGS_APSR_G, REGS_APSR_NZCVQ, REGS_APSR_NZCVQG, - REGS_CPSR, REGS_CPSR_C, REGS_CPSR_X, REGS_CPSR_XC, - REGS_CPSR_S, REGS_CPSR_SC, REGS_CPSR_SX, REGS_CPSR_SXC, - REGS_CPSR_F, REGS_CPSR_FC, REGS_CPSR_FX, REGS_CPSR_FXC, - REGS_CPSR_FS, REGS_CPSR_FSC, REGS_CPSR_FSX, REGS_CPSR_FSXC, - REGS_SPSR, REGS_SPSR_C, REGS_SPSR_X, REGS_SPSR_XC, - REGS_SPSR_S, REGS_SPSR_SC, REGS_SPSR_SX, REGS_SPSR_SXC, - REGS_SPSR_F, REGS_SPSR_FC, REGS_SPSR_FX, REGS_SPSR_FXC, - REGS_SPSR_FS, REGS_SPSR_FSC, REGS_SPSR_FSX, REGS_SPSR_FSXC, - REGS_APSR_NZCV, REGS_FPSID, REGS_FPSCR, REGS_MVFR2, + // REGS_APSR, REGS_APSR_G, REGS_APSR_NZCVQ, REGS_APSR_NZCVQG, + // REGS_CPSR, REGS_CPSR_C, REGS_CPSR_X, REGS_CPSR_XC, + // REGS_CPSR_S, REGS_CPSR_SC, REGS_CPSR_SX, REGS_CPSR_SXC, + // REGS_CPSR_F, REGS_CPSR_FC, REGS_CPSR_FX, REGS_CPSR_FXC, + // REGS_CPSR_FS, REGS_CPSR_FSC, REGS_CPSR_FSX, REGS_CPSR_FSXC, + // REGS_SPSR, REGS_SPSR_C, REGS_SPSR_X, REGS_SPSR_XC, + // REGS_SPSR_S, REGS_SPSR_SC, REGS_SPSR_SX, REGS_SPSR_SXC, + // REGS_SPSR_F, REGS_SPSR_FC, REGS_SPSR_FX, REGS_SPSR_FXC, + // REGS_SPSR_FS, REGS_SPSR_FSC, REGS_SPSR_FSX, REGS_SPSR_FSXC, + // REGS_APSR_NZCV, + REGS_FPSID, REGS_FPSCR, REGS_MVFR2, REGS_MVFR1, REGS_MVFR0, REGS_FPEXC, REGS_FPINST, - REGS_FPINST2, REGS_MSP, REGS_PSP, REGS_PRIMASK, - REGS_BASEPRI, REGS_FAULTMASK, REGS_CONTROL, + REGS_FPINST2, + // REGS_MSP, REGS_PSP, REGS_PRIMASK, + // REGS_BASEPRI, REGS_FAULTMASK, REGS_CONTROL, /* fake registers */ FAKEREG_SYSCALL_INFO diff --git a/arch/armv7/armv7_disasm/armv7.c b/arch/armv7/armv7_disasm/armv7.c index 69ce44fb..2a5e5c6f 100644 --- a/arch/armv7/armv7_disasm/armv7.c +++ b/arch/armv7/armv7_disasm/armv7.c @@ -498,14 +498,14 @@ static const char* registerString[] = { "r6", "r7", "r8", - "r9", - "r10", - "r11", - "r12", // "sb", + "r9", // "sl", + "r10", // "fp", + "r11", // "ip", + "r12", "sp", "lr", "pc", @@ -677,7 +677,23 @@ static const char* registerString[] = { "basepri", "faultmask", "control", + "basepri_max", + "ipsr", + "epsr", + "iepsr", + "iapsr", + "iapsr_g", + "iapsr_nzcvq", + "iapsr_nzcvqg", + "eapsr", + "eapsr_g", + "eapsr_nzcvq", + "eapsr_nzcvqg", + "xpsr", + "xpsr_g", + "xpsr_nzcvq", + "xpsr_nzcvqg", /* invalid */ "" }; diff --git a/arch/armv7/armv7_disasm/armv7.h b/arch/armv7/armv7_disasm/armv7.h index d91d75ca..14ff191a 100644 --- a/arch/armv7/armv7_disasm/armv7.h +++ b/arch/armv7/armv7_disasm/armv7.h @@ -712,6 +712,20 @@ enum Register REGS_EPSR, REGS_IEPSR, + REGS_IAPSR, + REGS_IAPSR_G, + REGS_IAPSR_NZCVQ, + REGS_IAPSR_NZCVQG, + REGS_EAPSR, + REGS_EAPSR_G, + REGS_EAPSR_NZCVQ, + REGS_EAPSR_NZCVQG, + REGS_XPSR, + REGS_XPSR_G, + REGS_XPSR_NZCVQ, + REGS_XPSR_NZCVQG, + + REG_INVALID, }; diff --git a/arch/armv7/thumb2_disasm/arch_thumb2.cpp b/arch/armv7/thumb2_disasm/arch_thumb2.cpp index a4a3c1cc..873b9b27 100644 --- a/arch/armv7/thumb2_disasm/arch_thumb2.cpp +++ b/arch/armv7/thumb2_disasm/arch_thumb2.cpp @@ -20,6 +20,72 @@ using namespace std; #define snprintf _snprintf #endif +static Ref<Enumeration> get_msr_op_enum() +{ + EnumerationBuilder builder; + builder.AddMemberWithValue("msp", REGS_MSP); + builder.AddMemberWithValue("psp", REGS_PSP); + builder.AddMemberWithValue("basepri", REGS_BASEPRI); + builder.AddMemberWithValue("basepri_max", REGS_BASEPRI_MAX); + builder.AddMemberWithValue("primask", REGS_PRIMASK); + builder.AddMemberWithValue("faultmask", REGS_FAULTMASK); + builder.AddMemberWithValue("control", REGS_CONTROL); + builder.AddMemberWithValue("ipsr", REGS_IPSR); + builder.AddMemberWithValue("epsr", REGS_EPSR); + builder.AddMemberWithValue("iepsr", REGS_IEPSR); + builder.AddMemberWithValue("apsr", REGS_APSR); + builder.AddMemberWithValue("apsr_g", REGS_APSR_G); + builder.AddMemberWithValue("apsr_nzcvq", REGS_APSR_NZCVQ); + builder.AddMemberWithValue("apsr_nzcvqg", REGS_APSR_NZCVQG); + builder.AddMemberWithValue("iapsr", REGS_IAPSR); + builder.AddMemberWithValue("iapsr_g", REGS_IAPSR_G); + builder.AddMemberWithValue("iapsr_nzcvq", REGS_IAPSR_NZCVQ); + builder.AddMemberWithValue("iapsr_nzcvqg", REGS_IAPSR_NZCVQG); + builder.AddMemberWithValue("eapsr", REGS_EAPSR); + builder.AddMemberWithValue("eapsr_g", REGS_EAPSR_G); + builder.AddMemberWithValue("eapsr_nzcvq", REGS_EAPSR_NZCVQ); + builder.AddMemberWithValue("eapsr_nzcvqg", REGS_EAPSR_NZCVQG); + builder.AddMemberWithValue("xpsr", REGS_XPSR); + builder.AddMemberWithValue("xpsr_g", REGS_XPSR_G); + builder.AddMemberWithValue("xpsr_nzcvq", REGS_XPSR_NZCVQ); + builder.AddMemberWithValue("xpsr_nzcvqg", REGS_XPSR_NZCVQG); + builder.AddMemberWithValue("cpsr", REGS_CPSR); + builder.AddMemberWithValue("cpsr_c", REGS_CPSR_C); + builder.AddMemberWithValue("cpsr_x", REGS_CPSR_X); + builder.AddMemberWithValue("cpsr_xc", REGS_CPSR_XC); + builder.AddMemberWithValue("cpsr_s", REGS_CPSR_S); + builder.AddMemberWithValue("cpsr_sc", REGS_CPSR_SC); + builder.AddMemberWithValue("cpsr_sx", REGS_CPSR_SX); + builder.AddMemberWithValue("cpsr_sxc", REGS_CPSR_SXC); + builder.AddMemberWithValue("cpsr_f", REGS_CPSR_F); + builder.AddMemberWithValue("cpsr_fc", REGS_CPSR_FC); + builder.AddMemberWithValue("cpsr_fx", REGS_CPSR_FX); + builder.AddMemberWithValue("cpsr_fxc", REGS_CPSR_FXC); + builder.AddMemberWithValue("cpsr_fs", REGS_CPSR_FS); + builder.AddMemberWithValue("cpsr_fsc", REGS_CPSR_FSC); + builder.AddMemberWithValue("cpsr_fsx", REGS_CPSR_FSX); + builder.AddMemberWithValue("cpsr_fsxc", REGS_CPSR_FSXC); + builder.AddMemberWithValue("spsr", REGS_SPSR); + builder.AddMemberWithValue("spsr_c", REGS_SPSR_C); + builder.AddMemberWithValue("spsr_x", REGS_SPSR_X); + builder.AddMemberWithValue("spsr_xc", REGS_SPSR_XC); + builder.AddMemberWithValue("spsr_s", REGS_SPSR_S); + builder.AddMemberWithValue("spsr_sc", REGS_SPSR_SC); + builder.AddMemberWithValue("spsr_sx", REGS_SPSR_SX); + builder.AddMemberWithValue("spsr_sxc", REGS_SPSR_SXC); + builder.AddMemberWithValue("spsr_f", REGS_SPSR_F); + builder.AddMemberWithValue("spsr_fc", REGS_SPSR_FC); + builder.AddMemberWithValue("spsr_fx", REGS_SPSR_FX); + builder.AddMemberWithValue("spsr_fxc", REGS_SPSR_FXC); + builder.AddMemberWithValue("spsr_fs", REGS_SPSR_FS); + builder.AddMemberWithValue("spsr_fsc", REGS_SPSR_FSC); + builder.AddMemberWithValue("spsr_fsx", REGS_SPSR_FSX); + builder.AddMemberWithValue("spsr_fsxc", REGS_SPSR_FSXC); + builder.AddMemberWithValue("apsr_nzcv", REGS_APSR_NZCV); + Ref<Enumeration> _enum = builder.Finalize(); + return _enum; +} + /* class Architecture from binaryninjaapi.h */ class Thumb2Architecture: public ArmCommonArchitecture { @@ -1217,13 +1283,16 @@ public: } /* application level form */ else { - uint32_t tmp = (decomp.fields[FIELD_write_nzcvq] << 1) | decomp.fields[FIELD_write_g]; + uint32_t mask = (decomp.fields[FIELD_write_nzcvq] << 1) | decomp.fields[FIELD_write_g]; uint8_t sysm = decomp.fields[FIELD_SYSm]; bool xPSR = ((sysm >> 2) & 1) == 1; switch (sysm >> 3) { case 0: /* xPSR access */ + { + string reg_name = ""; + string reg_bits = ""; if (xPSR) - switch (sysm) { + switch (sysm & 7) { case 5: // '101' == IPSR result.emplace_back(RegisterToken, "ipsr"); break; @@ -1235,23 +1304,41 @@ public: break; } else - switch(tmp) { + { + switch (sysm & 3) + { + case 0: + reg_name = "apsr"; + break; + case 1: + reg_name = "iapsr"; + break; + case 2: + reg_name = "eapsr"; + break; + case 3: + reg_name = "xpsr"; + break; + } + switch(mask) { case 0: // unpredictable break; case 1: // '01' == write_g /* aka CPSR_f */ - result.emplace_back(RegisterToken, "apsr_g"); + result.emplace_back(RegisterToken, reg_name + "_g"); break; case 2: // '10' == write_nzcvq /* aka CPSR_s */ - result.emplace_back(RegisterToken, "apsr_nzcvq"); + result.emplace_back(RegisterToken, reg_name + "_nzcvq"); break; case 3: // '11' == write_nzcvq | write_g /* aka CPSR_fs */ - result.emplace_back(RegisterToken, "apsr_nzcvqg"); + result.emplace_back(RegisterToken, reg_name + "_nzcvqg"); break; + } } break; + } case 1: /* SP access */ switch (sysm & 7) { case 0: @@ -1269,9 +1356,11 @@ public: result.emplace_back(RegisterToken, "primask"); break; case 1: - case 2: result.emplace_back(RegisterToken, "basepri"); break; + case 2: + result.emplace_back(RegisterToken, "basepri_max"); + break; case 3: result.emplace_back(RegisterToken, "faultmask"); break; @@ -1292,7 +1381,30 @@ public: uint8_t sysm = decomp.fields[FIELD_SYSm]; switch (sysm >> 3) { case 0: /* xPSR access */ - result.emplace_back(RegisterToken, "apsr"); + switch (sysm & 7) + { + case 0: + result.emplace_back(RegisterToken, "apsr"); + break; + case 1: + result.emplace_back(RegisterToken, "iapsr"); + break; + case 2: + result.emplace_back(RegisterToken, "eapsr"); + break; + case 3: + result.emplace_back(RegisterToken, "xpsr"); + break; + case 5: // '101' == IPSR + result.emplace_back(RegisterToken, "ipsr"); + break; + case 6: // '110' == EPSR + result.emplace_back(RegisterToken, "epsr"); + break; + case 7: // '111' == IEPSR + result.emplace_back(RegisterToken, "iepsr"); + break; + } break; case 1: /* SP access */ switch (sysm & 7) { @@ -1495,9 +1607,16 @@ public: NameAndType("m", Type::IntegerType(1, false)), }; case ARMV7_INTRIN_MRS: - return {NameAndType(Type::IntegerType(4, false))}; + // return {NameAndType(Type::IntegerType(4, false))}; + return { + NameAndType("msr", Confidence<Ref<Type>>(Type::EnumerationType(this, get_msr_op_enum(), 4, false), BN_FULL_CONFIDENCE)) + }; case ARMV7_INTRIN_MSR: - return {NameAndType(Type::IntegerType(4, false))}; + // return {NameAndType(Type::IntegerType(4, false))}; + return { + NameAndType("msr", Confidence<Ref<Type>>(Type::EnumerationType(this, get_msr_op_enum(), 4, false), BN_FULL_CONFIDENCE)), + NameAndType(Type::IntegerType(4, false)) + }; case ARMV7_INTRIN_DBG: return {NameAndType(Type::IntegerType(1, false))}; default: @@ -1516,7 +1635,8 @@ public: case ARMV7_INTRIN_MRS: return {Type::IntegerType(4, false)}; case ARMV7_INTRIN_MSR: - return {Type::IntegerType(4, false)}; + // return {Type::IntegerType(4, false)}; + return {}; default: return vector<Confidence<Ref<Type>>>(); } diff --git a/arch/armv7/thumb2_disasm/il_thumb2.cpp b/arch/armv7/thumb2_disasm/il_thumb2.cpp index 05a9f16f..f46a8641 100644 --- a/arch/armv7/thumb2_disasm/il_thumb2.cpp +++ b/arch/armv7/thumb2_disasm/il_thumb2.cpp @@ -59,11 +59,56 @@ static int GetSpecialRegister(LowLevelILFunction& il, decomp_result* instr, size switch (sysm >> 3) { case 0: - switch(tmp) + switch (sysm & 7) { - case 1: return REGS_APSR_G; - case 2: return REGS_APSR_NZCVQ; - case 3: return REGS_APSR_NZCVQG; + case 0: + switch(tmp) + { + case 1: return REGS_APSR_G; + case 2: return REGS_APSR_NZCVQ; + case 3: return REGS_APSR_NZCVQG; + case 0: + default: + return REGS_APSR; + } + case 1: + switch(tmp) + { + case 1: return REGS_IAPSR_G; + case 2: return REGS_IAPSR_NZCVQ; + case 3: return REGS_IAPSR_NZCVQG; + case 0: + default: + return REGS_IAPSR; + } + case 2: + switch(tmp) + { + case 1: return REGS_EAPSR_G; + case 2: return REGS_EAPSR_NZCVQ; + case 3: return REGS_EAPSR_NZCVQG; + case 0: + default: + return REGS_EAPSR; + } + case 3: + switch(tmp) + { + case 1: return REGS_XPSR_G; + case 2: return REGS_XPSR_NZCVQ; + case 3: return REGS_XPSR_NZCVQG; + case 0: + default: + return REGS_XPSR; + } + case 5: + return REGS_IPSR; + case 6: + return REGS_EPSR; + case 7: + return REGS_IEPSR; + default: + return REG_INVALID; } break; case 1: @@ -77,8 +122,8 @@ static int GetSpecialRegister(LowLevelILFunction& il, decomp_result* instr, size switch (sysm & 7) { case 0: return REGS_PRIMASK; - case 1: - case 2: return REGS_BASEPRI; + case 1: return REGS_BASEPRI; + case 2: return REGS_BASEPRI_MAX; case 3: return REGS_FAULTMASK; case 4: return REGS_CONTROL; } @@ -1131,7 +1176,8 @@ bool GetLowLevelILForThumbInstruction(Architecture* arch, LowLevelILFunction& il il.Intrinsic( {RegisterOrFlag::Register(dest_reg)}, /* outputs */ intrinsic_id, - {il.Register(4, GetSpecialRegister(il, instr, 1))} /* inputs */ + // {il.Register(4, GetSpecialRegister(il, instr, 1))} /* inputs */ + {il.Const(4, GetSpecialRegister(il, instr, 1))} /* inputs */ ) ); break; @@ -1141,40 +1187,54 @@ bool GetLowLevelILForThumbInstruction(Architecture* arch, LowLevelILFunction& il int dest_reg = GetSpecialRegister(il, instr, 0); int intrinsic_id = ARMV7_INTRIN_MSR; + il.AddInstruction( + il.Intrinsic( + {}, /* outputs */ + intrinsic_id, + { + // il.Register(4, dest_reg), + il.Const(4, dest_reg), + ReadILOperand(il, instr, 1) + } /* inputs */ + ) + ); + + /* certain MSR scenarios earn a specialized intrinsic */ // if (dest_reg == REGS_BASEPRI) // intrinsic_id = ARM_M_INTRIN_SET_BASEPRI; - switch (dest_reg) { - case REGS_MSP: - case REGS_PSP: - case REGS_BASEPRI: - case REGS_BASEPRI_MAX: - case REGS_PRIMASK: - case REGS_FAULTMASK: - case REGS_CONTROL: - case REGS_IPSR: - case REGS_EPSR: - case REGS_IEPSR: - il.AddInstruction( - il.Intrinsic( - {}, /* outputs */ - intrinsic_id, - { - il.Register(4, dest_reg), - ReadILOperand(il, instr, 1) - } /* inputs */ - ) - ); - break; - default: - il.AddInstruction( - il.Intrinsic( - {RegisterOrFlag::Register(dest_reg)}, /* outputs */ - intrinsic_id, - {ReadILOperand(il, instr, 1)} /* inputs */ - ) - ); - } + // switch (dest_reg) { + // case REGS_MSP: + // case REGS_PSP: + // case REGS_BASEPRI: + // case REGS_BASEPRI_MAX: + // case REGS_PRIMASK: + // case REGS_FAULTMASK: + // case REGS_CONTROL: + // case REGS_IPSR: + // case REGS_EPSR: + // case REGS_IEPSR: + // il.AddInstruction( + // il.Intrinsic( + // {}, /* outputs */ + // intrinsic_id, + // { + // // il.Register(4, dest_reg), + // il.Const(4, dest_reg), + // ReadILOperand(il, instr, 1) + // } /* inputs */ + // ) + // ); + // break; + // default: + // il.AddInstruction( + // il.Intrinsic( + // {RegisterOrFlag::Register(dest_reg)}, /* outputs */ + // intrinsic_id, + // {ReadILOperand(il, instr, 1)} /* inputs */ + // ) + // ); + // } break; } diff --git a/arch/armv7/thumb2_disasm/test.py b/arch/armv7/thumb2_disasm/test.py index 65e4bd22..3a811e18 100755 --- a/arch/armv7/thumb2_disasm/test.py +++ b/arch/armv7/thumb2_disasm/test.py @@ -3,22 +3,57 @@ # (bytes, expected_disassembly, options) test_cases = ( (b'\x00\xbf', 'nop', {}), + (b'\xef\xf3\x00\x80', 'mrs r0, apsr', {}), + (b'\xef\xf3\x01\x80', 'mrs r0, iapsr', {}), + (b'\xef\xf3\x02\x80', 'mrs r0, eapsr', {}), + (b'\xef\xf3\x03\x80', 'mrs r0, xpsr', {}), + (b'\xef\xf3\x05\x80', 'mrs r0, ipsr', {}), + (b'\xef\xf3\x06\x80', 'mrs r0, epsr', {}), + (b'\xef\xf3\x07\x80', 'mrs r0, iepsr', {}), + (b'\xef\xf3\x09\x80', 'mrs r0, psp', {}), - (b'\x80\xf3\x09\x88', 'msr psp, r0', {}), (b'\xef\xf3\x08\x80', 'mrs r0, msp', {}), - (b'\x80\xf3\x08\x88', 'msr msp, r0', {}), - (b'\xef\xf3\x00\x80', 'mrs r0, apsr', {}), + (b'\xef\xf3\x10\x80', 'mrs r0, primask', {}), (b'\xef\xf3\x11\x80', 'mrs r0, basepri', {}), + (b'\xef\xf3\x12\x80', 'mrs r0, basepri', {}), (b'\xef\xf3\x13\x80', 'mrs r0, faultmask', {}), (b'\xef\xf3\x14\x80', 'mrs r0, control', {}), + + (b'\x80\xf3\x00\x84', 'msr apsr_g, r0', {}), (b'\x80\xf3\x00\x88', 'msr apsr_nzcvq, r0', {}), + (b'\x80\xf3\x00\x8c', 'msr apsr_nzcvqg, r0', {}), + (b'\x80\xf3\x01\x84', 'msr iapsr_g, r0', {}), + (b'\x80\xf3\x01\x88', 'msr iapsr_nzcvq, r0', {}), + (b'\x80\xf3\x01\x8c', 'msr iapsr_nzcvqg, r0', {}), + (b'\x80\xf3\x02\x84', 'msr eapsr_g, r0', {}), + (b'\x80\xf3\x02\x88', 'msr eapsr_nzcvq, r0', {}), + (b'\x80\xf3\x02\x8c', 'msr eapsr_nzcvqg, r0', {}), + (b'\x80\xf3\x03\x84', 'msr xpsr_g, r0', {}), + (b'\x80\xf3\x03\x88', 'msr xpsr_nzcvq, r0', {}), + (b'\x80\xf3\x03\x8c', 'msr xpsr_nzcvqg, r0', {}), + + (b'\x80\xf3\x09\x88', 'msr psp, r0', {}), + (b'\x80\xf3\x08\x88', 'msr msp, r0', {}), + (b'\x80\xf3\x10\x88', 'msr primask, r0', {}), (b'\x80\xf3\x11\x88', 'msr basepri, r0', {}), + (b'\x80\xf3\x12\x88', 'msr basepri_max, r0', {}), (b'\x80\xf3\x13\x88', 'msr faultmask, r0', {}), (b'\x80\xf3\x14\x88', 'msr control, r0', {}), ) +''' +msr r0, apsr +mrs apsr, r0 +msr r0, apsr_g +mrs apsr_g, r0 +msr r0, apsr_nzcvq +mrs apsr_nzcvq, r0 +msr r0, apsr_nzcvqg +mrs apsr_nzcvqg, r0 +''' + import sys, re import binaryninja |
