diff options
| author | Galen Williamson <galen@vector35.com> | 2024-03-12 13:26:16 -0400 |
|---|---|---|
| committer | galenbwill <galenbwill@users.noreply.github.com> | 2024-03-12 13:49:08 -0400 |
| commit | 45a674447579e350cf380dbacba5c5f6360c5ac1 (patch) | |
| tree | bc6daa4644a5c78caa7d834740b70f3bf3550230 /arch/armv7 | |
| parent | c924e7f746f7f81fab1f35d8adc936dfba706b58 (diff) | |
moved over from https://github.com/Vector35/arch-armv7/pull/81
Diffstat (limited to 'arch/armv7')
| -rw-r--r-- | arch/armv7/il.cpp | 16 | ||||
| -rwxr-xr-x | arch/armv7/test_lift.py | 26 |
2 files changed, 39 insertions, 3 deletions
diff --git a/arch/armv7/il.cpp b/arch/armv7/il.cpp index d946e77c..5fbbb729 100644 --- a/arch/armv7/il.cpp +++ b/arch/armv7/il.cpp @@ -312,8 +312,20 @@ static void Load( memValue = il.ZeroExtend(dstSize, memValue); } - il.AddInstruction(SetRegisterOrBranch(il, dst.reg, memValue)); - il.AddInstruction(SetRegisterOrBranch(il, src.reg, value)); + if (dst.reg == REG_PC) + { + // don't update Rd, update Rs, jump to pre-updated Rs + il.AddInstruction(il.SetRegister(4, LLIL_TEMP(0), memValue)); + il.AddInstruction(SetRegisterOrBranch(il, src.reg, value)); + il.AddInstruction(il.Jump(il.Register(4, LLIL_TEMP(0)))); + } + else + { + // set Rd, update Rs, don't jump + il.AddInstruction(il.SetRegister(get_register_size(dst.reg), dst.reg, memValue)); + il.AddInstruction(SetRegisterOrBranch(il, src.reg, value)); + } + break; case MEM_IMM: case LABEL: diff --git a/arch/armv7/test_lift.py b/arch/armv7/test_lift.py index 2e12dbe4..ab97d1d9 100755 --- a/arch/armv7/test_lift.py +++ b/arch/armv7/test_lift.py @@ -2,6 +2,27 @@ test_cases = \ [ + # Post-Indexed addressing (normal) + # with register offset + # ldr r0, [r1], r2 + ('A', b'\x02\x00\x91\xe6', 'LLIL_SET_REG.d(r0,LLIL_LOAD.d(LLIL_REG.d(r1))); LLIL_SET_REG.d(r1,LLIL_ADD.d(LLIL_REG.d(r1),LLIL_REG.d(r2)))'), + # with immediate offset + # ldr r0, [r1], #4 + ('A', b'\x04\x00\x91\xe4', 'LLIL_SET_REG.d(r0,LLIL_LOAD.d(LLIL_REG.d(r1))); LLIL_SET_REG.d(r1,LLIL_ADD.d(LLIL_REG.d(r1),LLIL_CONST.d(0x4)))'), + # with register and shift + # ldr r0, [r1], r2, lsl #2 + ('A', b'\x02\x01\x91\xe6', 'LLIL_SET_REG.d(r0,LLIL_LOAD.d(LLIL_REG.d(r1))); LLIL_SET_REG.d(r1,LLIL_ADD.d(LLIL_REG.d(r1),LLIL_LSL.d(LLIL_REG.d(r2),LLIL_CONST.b(0x2))))'), + + # Post-Indexed addressing (to pc) + # ldr pc, [r1], r2 + ('A', b'\x02\xf0\x91\xe6', 'LLIL_SET_REG.d(temp0,LLIL_LOAD.d(LLIL_REG.d(r1))); LLIL_SET_REG.d(r1,LLIL_ADD.d(LLIL_REG.d(r1),LLIL_REG.d(r2))); LLIL_JUMP(LLIL_REG.d(temp0))'), + # ldr pc, [r1], #4 + ('A', b'\x04\xf0\x91\xe4', 'LLIL_SET_REG.d(temp0,LLIL_LOAD.d(LLIL_REG.d(r1))); LLIL_SET_REG.d(r1,LLIL_ADD.d(LLIL_REG.d(r1),LLIL_CONST.d(0x4))); LLIL_JUMP(LLIL_REG.d(temp0))'), + # ldr pc, [r1], r2, lsl #2 + ('A', b'\x02\xf1\x91\xe6', 'LLIL_SET_REG.d(temp0,LLIL_LOAD.d(LLIL_REG.d(r1))); LLIL_SET_REG.d(r1,LLIL_ADD.d(LLIL_REG.d(r1),LLIL_LSL.d(LLIL_REG.d(r2),LLIL_CONST.b(0x2)))); LLIL_JUMP(LLIL_REG.d(temp0))'), + # from " Armv7: POP(PC) lifted as LDR without writeback #3982" + ('A', b'\x04\xf0\x9d\xe4', 'LLIL_SET_REG.d(temp0,LLIL_LOAD.d(LLIL_REG.d(sp))); LLIL_SET_REG.d(sp,LLIL_ADD.d(LLIL_REG.d(sp),LLIL_CONST.d(0x4))); LLIL_JUMP(LLIL_REG.d(temp0))'), + # umaal r0, r1, r2, r3 ('A', b'\x92\x03\x41\xe0', 'LLIL_SET_REG_SPLIT.d(r1,r0,LLIL_ADD.q(LLIL_MULU_DP.d(LLIL_REG.d(r3),LLIL_REG.d(r2)),LLIL_ADD.q(LLIL_REG.d(r1),LLIL_REG.d(r0))))'), # umlal r0, r1, r2, r3 @@ -100,7 +121,8 @@ test_cases = \ # sbfx r0, r1, 1, 2 (starting at b1, width 2, so extract b2b1) ('T', b'\x41\xf3\x41\x00', 'LLIL_SET_REG.d(r0,LLIL_ASR.d(LLIL_LSL.d(LLIL_REG.d(r1),LLIL_CONST.b(0x1D)),LLIL_CONST.b(0x1E)))'), # sbfx r0, r1, 20, 30 (starting at b20, width 30... gets clamped, so b31b30...b20 - ('T', b'\x41\xf3\x1d\x50', 'LLIL_SET_REG.d(r0,LLIL_ASR.d(LLIL_LSL.d(LLIL_REG.d(r1),LLIL_CONST.b(0x0)),LLIL_CONST.b(0x14)))') + # just r0 = r1 >> 20, no left shift required + ('T', b'\x41\xf3\x1d\x50', 'LLIL_SET_REG.d(r0,LLIL_ASR.d(LLIL_REG.d(r1),LLIL_CONST.b(0x14)))') ] import re @@ -126,6 +148,8 @@ def il2str(il): return '%s%s%s(%s)' % (il.operation.name, size_code, flags_code, ','.join([il2str(o) for o in il.operands])) elif isinstance(il, list): return '[' + ','.join([il2str(x) for x in il]) + ']' + elif type(il) == lowlevelil.LowLevelILFlagCondition: + return f'LowLevelILFlagCondition.{il.name}' else: return str(il) |
