Author Topic: ARM assembly, efficient jump hook help?  (Read 853 times)

names_are_hard

  • Contributor
  • Senior
  • *****
  • Posts: 283
  • 200D idiot
ARM assembly, efficient jump hook help?
« on: December 08, 2019, 04:38:41 AM »
I'm trying to patch in some jump hooks for debugging.  I'm finding it hard to work out efficient ARM assembly for this (I'm an ARM noob).  In x86 I'd JMP 0x12345678 and it would be 5 bytes with no register side effects.  ARM I can't set a dword constant in one go.  I'm also in Thumb mode.  Best I have so far is this, which kind of sucks:

        PUSH {R3, R4}
        MOV R4, 0x1234
        MOV R3, 0x5678
        LSL R4, R4, #16
        ADD R4, R3
        BX R4

Which is 18 bytes, feels bad to me.  Some functions I'm interested in are the same size!  Any better way to jump to an arbitrary offset?  Maybe I'd win by swapping out of Thumb first?

Alternatively, any ideas on how to accomplish the same idea efficiently in ARM would be appreciated - patch in a transfer to my own code to do arbitrary stuff, then cleanup register & stack changes and transfer back.

names_are_hard

  • Contributor
  • Senior
  • *****
  • Posts: 283
  • 200D idiot
Re: ARM assembly, efficient jump hook help?
« Reply #1 on: December 08, 2019, 04:47:42 AM »
Aaand, of course I managed to find a good example immediately after posting that.  In theory, I can do this:

    LDR PC,[PC,-4]
    #0x12345678

It compiles in Thumb, shall try it soon.  8 bytes, not bad.  I'm not used to PC being a thing I can set directly!

srsa

  • Contributor
  • New to the forum
  • *****
  • Posts: 44
Re: ARM assembly, efficient jump hook help?
« Reply #2 on: December 08, 2019, 11:23:09 AM »
Aaand, of course I managed to find a good example immediately after posting that.  In theory, I can do this:

    LDR PC,[PC,-4]
    #0x12345678

It compiles in Thumb, shall try it soon.
The offset used in that instruction depends on several factors. Your example is valid in ARM state. In thumb state, the offset is 0 if your LDR PC instruction is on a word aligned address, and 2 if it isn't word aligned. See the ARM literature about the value of PC. There's also this, although I don't think I've encountered problems with that.

edit:
Of course, you also need to use the the correct thumb bit in the destination address (bit0 is zero for an ARM target, 1 for Thumb target).

a1ex

  • Administrator
  • Hero Member
  • *****
  • Posts: 12461
Re: ARM assembly, efficient jump hook help?
« Reply #3 on: December 08, 2019, 11:34:36 AM »
Right. Here's the code I've used for overriding DebugMsg on DIGIC 6/7 (and 8, but there you'd also have to reconfigure the MMU).

names_are_hard

  • Contributor
  • Senior
  • *****
  • Posts: 283
  • 200D idiot
Re: ARM assembly, efficient jump hook help?
« Reply #4 on: December 08, 2019, 05:30:59 PM »
Thanks both, that will save me lots of debugging time!  Particularly strange to me how the PC offset is negative!  I guess to do with pipelining.