我有一个程序(arm)和一些指令(IDA 拒绝):
.plt:000083F0 ADRL R12, 0x83F8
.plt:000083F8 LDR PC, [R12,#(off_90D8 - 0x83F8)]! ; sub_83D0
地址0x90D8存储0x83D0:
000090D8 D0 83 00 00
所以,在ldr之后,pc是0x83D0并且将执行0x83D0中的inst,不是吗?
这里我想直接跳转到0x83D0而不是使用09D8,我修改了二进制机器码并通过IDA重新加载:
.plt:000083F0 B sub_83D0
IDA显示会跳转到0x83D0,所以我认为修改是有效的。
但修改后程序无法运行。
我的修改有什么问题以及如何实现我的目标?请帮助我...
我在这里添加了一些更多的缺点:
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 中:
000090D4 D0 83 00 00 D0 83 00 00
最佳答案
指令B sub_83D0
是相对于PC的。指令顺序,
.plt:000083F0 ADRL R12, 0x83F8
.plt:000083F8 LDR PC, [R12,#(off_90D8 - 0x83F8)]! ; sub_83D0
000090D8: D0 83 00 00
是相对于PC的,但它跳转到绝对地址。您假设链接地址是运行时地址。这并不总是正确的,特别是在可能重新定位或启用MMU的引导代码中。
上面的序列可以从任何地址运行,并将控制权转移到绝对地址 0x83d0,branch 变体仅通过添加来更改 PC
一个偏移量。即,
PC = PC + (SignExtend) (immediate << 2);
等效项是 mov pc, #0x83D0
,但这不符合 mov
立即数旋转 8 位 的限制2.你可以尝试,
mov r12, #0x8300
orr pc, r12, #0xd0
但传输到的代码可能还需要将 r12
值设置为较旧的运行时地址。
关于assembly - 为什么 'LDR' 不能替换为 'B' ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17428025/