I have no idea why the following code hits a BAD_INSTRUCTION
error, anyone?
mov r4, r0
movw r0, #0xc70 ; injected code start here
movt r0, #0x8bb3
movw r3, #0x576
ldr r1, [r7]
movs r5, #0x1a
add r5, pc ; next instruction will jump over 9 instructions
bx r5 ; injected code end here
ldr r1, [r0]
ldr r0, [r2]
blx 0x26e11c
movw r1, #0x6442
movt r1, #0x18
add r1, pc
ldr r1, [r1]
blx 0x26e11c
mov r3, r1
movw r1, #0x66a4 ; r1 has not been loaded
movt r1, #0x15 ; with new value. Why?
mov r2, r0
add r1, pc ; This instruction isn't getting called
mov r0, r4 ; EXC_BAD_INSTRUCTION here
blx __sprintf
Between the 26 byte offset (i.e. no multiple of 4-byte ARM instructions) and the immediate generation being flag-setting (movs r5, #0x1a
), I sense this is Thumb code. However, bx r5
is an interworking branch, and since bit 0 of r5 isn't being set, it's going to interwork to ARM state into the middle of some Thumb instructions and get very unhappy. Since I believe EXC_BAD_INSTRUCTION
is iOS's reporting of an undefined instruction exception, that all looks to add up.
If you're in Thumb state and want to stay in Thumb state, either use a non-interworking branch (i.e. mov pc, r5
), or ensure bit 0 of the bx
target is set (i.e. make the offset 0x1b).