Neil.L
Neil.L

Reputation: 113

arm instruction is 'UNDEFINED'?

I am debugging an ARM program(android) and make some modify for it. I want to jmp 0x8684 in 0x8436, So I overwrite 4 bytes blx instruction, after that I use IDA pro to load the program, and it seems successful from IDA's view:

IDA view
-----------------------------------------------------------------
.text:00008430    LDR     R0, =(aOkkkkkkk___ - 0x8438)
.text:00008432    PUSH    {R4,LR}
.text:00008434    ADD     R0, PC  ; "okkkkkkk..."
.text:00008436    BLX     sub_8684
.text:0000843A    POP     {R4,PC}

HEX view(the machine code)
-----------------------------------------------------------------
00008436  00 F0 25 E9

However, the program failed to run(the src program runs normally):

arm-eabi-gdb
-----------------------------------------------------------------
(gdb) x/10i 0x8430
=> 0x8430:      ldr     r0, [pc, #8]    ; (0x843c)
   0x8432:      push    {r4, lr}
   0x8434:      add     r0, pc
   0x8436:                      ; <UNDEFINED> instruction: 0xf000e925
   0x843a:      pop     {r4, pc}

(gdb) x/10x 0x8436
   0x8436: 0xe925f000      0x001cbd10 

So the machine code of blx instruction is wrong? Please help me... I want to know the right instruction and the arithmetic to convert blx to machine code...

And the original instructions(runs normally) here:

ori:
.text:00008430    LDR   R0, =(aOkkkkkkk___ - 0x8438)
.text:00008432    PUSH  {R4,LR}
.text:00008434    ADD   R0, PC  ; "okkkkkkk..."
.text:00008436    BLX   sub_83F0
.text:0000843A    POP   {R4,PC}

ori:
00008430  02 48 10 B5  78 44 FF F7  DC EF 10 BD

modified:
00008430  02 48 10 B5  78 44 00 F0  25 E9 10 BD

Upvotes: 0

Views: 2345

Answers (1)

old_timer
old_timer

Reputation: 71506

00008436  00 F0 26 E9

0xF000 111 10 00000000000 first half, immed 00000000000
0xE926 111 01 00100100110 second half, blx, immed 00100100110

0x8436 + 0b0000000000000100100110<<1 + 2 =
0x8436 + 0x24C + 2 = 
0x8684

From the ARM Architectural Reference Manual (ARM ARM).

if H == 10 then
LR = PC + (SignExtend(offset_11) << 12)

The PC is always two instructions ahead, this is thumb code and basically that means 2 bytes head, 16 bits, so for 0x8436 the PC is 0x8436+2

First instruction

0xF000 111 10 00000000000 first half, immed 00000000000
LR = 0x8436+2 + 0b00000000000_000000000000
LR = 0x8438

Second instruction

0xE926 111 01 00100100110 second half, blx, immed 00100100110

if H == 01 then 
 PC = (LR + (offset_11 << 1)) AND 0xFFFFFFFC 
 LR = (address of next instruction) | 1 
 CPSR T bit = 0

PC = (0x8438 + 0b00100100110_0)&0xFFFFFFFC
PC = (0x8438 + 0x0000024C)&0xFFFFFFFC
PC = (0x8684)&0xFFFFFFFC
PC = 0x8684
LR = 0x843A | 1
LR = 0x843B

Learn something new every day and this is probably why nobody uses blx. You can only use this to branch to arm from thumb. And ARM blx only from ARM to thumb. bl you use for staying in the same mode and BX it depends on the address, so you dont have to know ahead of time.

Upvotes: 1

Related Questions