.text:4044A5EC LDR R5, =(unk_40885080 - 0x4044A5F8)
看看unk_40885080的值,它在.data段中的值为20。
#1 楼
这似乎是ARM PIC(与位置无关)代码,其中地址是相对于程序计数器给出的。 Ida会检测到该错误并显示“真实”地址。不幸的是,您没有在单个语句周围发布任何代码,因此我正在使用我自己的反汇编代码向您显示:
.text:00062454 LDR R3, [R4,#8]
.text:00062458 MOV R0, #0x2C ; ','
.text:0006245C LDR R1, =(unk_218172 - 0x62474) <--- a
.text:00062460 MOV R5, #0
.text:00062464 MOV R2, #4 ; n
.text:00062468 STRB R0, [R3,#0x12]
.text:0006246C ADD R1, PC, R1 <--- b
.text:00062470 LDR R3, [R4,#8]
.text:00062474 ADD R0, R3, #0x30 ; dest
.text:00062478 STR R1, [R3,#8]
.text:0006247C STR R1, [R3,#0x14]
代码将一些值加载到R1(a)中,然后(b)将PC添加到其中。因此,该寄存器的值应该是一个指向内存的指针,但是由于后来添加了PC,所以在2645C加载的值没有任何意义。 Ida检测到ADD指令,并以某种方式显示LDR指令,使您可以看到它应该指向的位置。
0x62474的“校正偏移量”不是
ADD
的地址指令是由于处理器内的流水线;在执行ADD
的那一刻,已经读取了下一条指令,因此PC是ADD
指令所在位置的“后面”两条指令。(编译器生成此类代码的原因就是说,当相同的代码在以后加载到不同的地址时,它仍然有效,即使没有重新定位补丁,链接器/加载器也必须这样做。这称为PIC,即位置无关的代码。)
评论
我想我遵循,那么您的示例使用的伪代码是什么?
– allbabel
2014年5月28日在19:43
您不能从我的示例中真正制作出有意义的伪代码,因为这只是来自较大函数的一些指令。但是,如果您确实想要伪代码,则可以将CDR中的组合指令LDR R1 =(unk_218172-0x62474)和ADD R1,PC,R1写入C中,结果是指向该内存位置的指针,但是这些指令不会访问内存本身;在其操作数中具有[R1]的后续指令将通过指针访问内存。
–贡特拉姆·布洛姆(Guntram Blohm)
2014年5月28日在22:29
它与代码无关,而是它的编译器工具链的实现,以支持位置无关代码的概念,这是因为其运行的体系结构。但是,您可以使用编译器标志(例如-pie(gcc))来执行此操作,该标志应生成必要的asm代码。
– Gandolf
2014年5月28日22:30
@gandolf:-fPIC,而不是-pie。
–贡特拉姆·布洛姆(Guntram Blohm)
2014年5月28日在22:32
谢谢@GuntramBlohm,我是从内存中写入的,这是不可信的。
– Gandolf
2014年5月28日在22:33