Reputation: 113
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
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