为什么“LDR”不能用'B'取代? [英] why 'LDR' cannot replace with 'B'?
问题描述
我有一个计划(ARM),并在那里一些指令(开发协会disas):
.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,将exec的在0x83D0的研究所,是不是?
在这里,我想直接到JMP和0x83D0不使用09D8,我修改二进制机器code和IDA重新加载它:
.PLT:000083F0乙sub_83D0
IDA表明,将JMP到0x83D0,所以我认为修改是有效的。结果
但是,程序没有运行后修改。结果
有什么毛病我修改以及如何实现我的目标?请帮我...
我多放些disas这里:结果
SRC
.PLT:000083E4
.PLT:000083E4; ===============子程序================================== =====
.PLT:000083E4
.PLT:000083E4;属性:的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;功能sub_83E4结束
.PLT:000083EC
.PLT:000083F0
.PLT:000083F0; ===============子程序================================== =====
.PLT:000083F0
.PLT:000083F0;属性:的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;功能sub_83F0结束
.PLT:000083F8
.PLT:000083F8; .PLT结束
.PLT:000083F8
修改
.PLT:000083E4
.PLT:000083E4; ===============子程序================================== =====
.PLT:000083E4
.PLT:000083E4;属性:的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;功能sub_83E4结束
.PLT:000083EC
.PLT:000083F0
.PLT:000083F0; ===============子程序================================== =====
.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乙sub_83D0
.PLT:000083F8;功能sub_83F0结束
.PLT:000083F8
.PLT:000083F8; .PLT结束
.PLT:000083F8
和在0x90D4:
000090D4 D0 83 00 00 83 D0 00 00
指令 B sub_83D0
为 PC 相对的。该指令序列,
.PLT:000083F0 ADRL R12,0x83F8
.PLT:000083F8 LDR PC,[R12,#(off_90D8 - 0x83F8)! ; sub_83D0000090D8:D0 83 00 00
是相对的PC,但它跳转到一个绝对地址。你的假设是,在链接地址是在运行地址。这并非总是如此,尤其是在的引导的code这可能的移居的或启用的 MMU 的
上面的顺序可以从任何地址运行,并且将控制转移到绝对的 0x83d0 的,在分支的变种只改变了 PC
加上偏移。也就是说,
PC = PC +(SignExtend)(立即< 2);
这是相当于将 MOV PC,#0x83D0
,但这不适合 MOV
立即数的限制的 8位的以2的倍数你可以试着转动,
MOV R12,#0x8300
ORR PC,R12,#0xd0
但code,它被转移到可能还需要 12版
值设置到旧的运行的地址。
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
The addr 0x90D8 stores 0x83D0:
000090D8 D0 83 00 00
So, after ldr, the pc is 0x83D0 and will exec the inst in 0x83D0, isn't?
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 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...
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
modified
.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
And in 0x90D4:
000090D4 D0 83 00 00 D0 83 00 00
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
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.
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);
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
but the code that is transferred to may also need the r12
value set to the older runtime address.
这篇关于为什么“LDR”不能用'B'取代?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!