.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