4

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
RyanB
  • 1,287
  • 1
  • 9
  • 28
  • Why not single-step through the code in your debugger and see what's actually going on ? – Paul R Jul 08 '16 at 08:10
  • @PaulR I did, as you can see my comment on each instruction. After `bx r5`, everything looks ok to me. But next 2 movw & movt set nothing to r1, and after that the process felt to `EXC_BAD_INSTRUCTION`. – RyanB Jul 08 '16 at 08:25
  • 2
    Are you sure about the value `0x1a`? If you were off by +/- 1byte, I could see the debugger being confused about where you are in the code (so it *looks* like you are tracing over the code you expect), but since you wouldn't be executing the instructions you think you are... Just a thought. – David Wohlferd Jul 08 '16 at 10:15
  • what processor/core is this? you are using bx to switch from thumb to arm mode. does your processor support arm mode? – old_timer Jul 09 '16 at 21:17

1 Answers1

2

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).

Notlikethat
  • 20,095
  • 3
  • 40
  • 77