本文介绍了为什么“LDR"不能替换为“B"?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个程序(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_83D0PC相对的.指令序列,

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 相关,但会跳转到绝对地址.您假设链接地址是运行时地址.这并不总是正确的,尤其是在可能重定位或启用MMUbootstrap代码中.

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.

上面的序列可以从任何地址运行,并将控制权转移到绝对的0x83d0branch变体只通过添加改变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"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-04 22:32