我正在调试ARM程序(android)并对其进行一些修改。我想在0x8436中使用jmp 0x8684,所以我覆盖了4个字节的blx指令,之后我使用IDA pro来加载程序,从IDA看来它似乎很成功:
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
但是,程序无法运行(src程序正常运行):
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
那么blx指令的机器码是错的?请帮助我...我想知道正确的指令和将blx转换为机器代码的算法......
原始说明(正常运行):
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
答案 0 :(得分:1)
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
来自ARM体系结构参考手册(ARM ARM)。
if H == 10 then
LR = PC + (SignExtend(offset_11) << 12)
PC总是提前两条指令,这是拇指代码,基本上意味着2字节头,16位,所以对于0x8436,PC是0x8436 + 2
第一条指示
0xF000 111 10 00000000000 first half, immed 00000000000
LR = 0x8436+2 + 0b00000000000_000000000000
LR = 0x8438
第二条指令
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
每天都学习新东西,这可能就是为什么没有人使用blx。你只能用这个来从拇指分支。而ARM blx仅从ARM到拇指。 bl你用来保持相同的模式和BX它取决于地址,所以你不必提前知道。