问题描述
我有一个程序(arm)和一些指令(IDA 禁止):
I have a program(arm) and some instructions in there(disas by IDA):
.plt:000083F0 ADRL R12, 0x83F8
.plt:000083F8 LDR PC, [R12,#(off_90D8 - 0x83F8)]! ; sub_83D0
地址 0x90D8 存储 0x83D0:
The addr 0x90D8 stores 0x83D0:
000090D8 D0 83 00 00
那么,在 ldr 之后,pc 是 0x83D0 并且会在 0x83D0 中执行 inst,不是吗?
So, after ldr, the pc is 0x83D0 and will exec the inst in 0x83D0, isn't?
这里我想直接jmp到0x83D0,不使用09D8,我修改了二进制机器码,用IDA重新加载:
Here I want to jmp to 0x83D0 directly and not use 09D8, I modify the binary machine code and reload it by IDA:
.plt:000083F0 B sub_83D0
IDA显示它会jmp到0x83D0,所以我认为修改是有效的.
但是修改后程序运行失败.
我的修改以及如何实现我的目标有什么问题吗?请帮帮我...
IDA shows that it will jmp to 0x83D0, so I think the modify is valid.
However, the program failed to run after modify.
Is there any wrong with my modify and how to achieve my target? Please help me...
我在这里放了一些disas:
源代码
I put some more disas here:
SRC
.plt:000083E4
.plt:000083E4 ; =============== S U B R O U T I N E =======================================
.plt:000083E4
.plt:000083E4 ; Attributes: thunk
.plt:000083E4
.plt:000083E4 sub_83E4 ; CODE XREF: .text:00008410j
.plt:000083E4 ADRL R12, 0x83EC
.plt:000083EC LDR PC, [R12,#(off_90D4 - 0x83EC)]! ; sub_83D0
.plt:000083EC ; End of function sub_83E4
.plt:000083EC
.plt:000083F0
.plt:000083F0 ; =============== S U B R O U T I N E =======================================
.plt:000083F0
.plt:000083F0 ; Attributes: thunk
.plt:000083F0
.plt:000083F0 sub_83F0 ; CODE XREF: sub_8430+6p
.plt:000083F0 ; sub_8430+Ep ...
.plt:000083F0 ADRL R12, 0x83F8
.plt:000083F8 LDR PC, [R12,#(off_90D8 - 0x83F8)]! ; sub_83D0
.plt:000083F8 ; End of function sub_83F0
.plt:000083F8
.plt:000083F8 ; .plt ends
.plt:000083F8
修改
.plt:000083E4
.plt:000083E4 ; =============== S U B R O U T I N E =======================================
.plt:000083E4
.plt:000083E4 ; Attributes: thunk
.plt:000083E4
.plt:000083E4 sub_83E4 ; CODE XREF: .text:00008410j
.plt:000083E4 ADRL R12, 0x83EC
.plt:000083EC LDR PC, [R12,#(off_90D4 - 0x83EC)]! ; sub_83D0
.plt:000083EC ; End of function sub_83E4
.plt:000083EC
.plt:000083F0
.plt:000083F0 ; =============== S U B R O U T I N E =======================================
.plt:000083F0
.plt:000083F0
.plt:000083F0 sub_83F0 ; CODE XREF: sub_8430+6p
.plt:000083F0 ; sub_8430+Ep ...
.plt:000083F0 ADRL R12, loc_83F8
.plt:000083F8
.plt:000083F8 loc_83F8 ; DATA XREF: sub_83F0o
.plt:000083F8 B sub_83D0
.plt:000083F8 ; End of function sub_83F0
.plt:000083F8
.plt:000083F8 ; .plt ends
.plt:000083F8
在 0x90D4 中:
And in 0x90D4:
000090D4 D0 83 00 00 D0 83 00 00
推荐答案
指令B sub_83D0
是PC相对的.指令序列,
The instruction B sub_83D0
is PC relative. The instruction sequence,
.plt:000083F0 ADRL R12, 0x83F8
.plt:000083F8 LDR PC, [R12,#(off_90D8 - 0x83F8)]! ; sub_83D0
000090D8: D0 83 00 00
与 PC 相关,但会跳转到绝对地址.您假设链接地址是运行时地址.这并不总是正确的,尤其是在可能重定位或启用MMU的bootstrap代码中.
Is PC relative, but it jumps to an absolute address. Your assumption is that the link address is the runtime address. This is not always true, especially in bootstrap code which may relocate or enable an MMU.
上面的序列可以从任何地址运行,并将控制权转移到绝对的0x83d0,branch变体只通过添加改变PC
一个偏移量.即,
The sequence above can run from any address and will transfer control to the absolute 0x83d0, the branch variant only changes the PC
by adding an offset. Ie,
PC = PC + (SignExtend) (immediate << 2);
一个等价物是 mov pc, #0x83D0
,但这不符合 8bit 由多个旋转的 mov
立即数限制2. 你可以试试,
An equivalent would be mov pc, #0x83D0
, but this will not fit the mov
immediates limitation of an 8bit rotated by a multiple of 2. You could try,
mov r12, #0x8300
orr pc, r12, #0xd0
但转移到的代码可能还需要将 r12
值设置为旧的运行时地址.
but the code that is transferred to may also need the r12
value set to the older runtime address.
这篇关于为什么“LDR"不能替换为“B"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!