thumb汇编在ldr pc时容易忽略的一个细节

最近在修花指令,脚本修复 ldr 的时候,如果是从 PC 开始计算,发现ida的表现和keystone 的表现是不一致的,查了很久没找到原因。直到后面翻arm手册,才发现一个小细节。

一、重现方式

二、错误理解

看看这段程序,主要也就把 [PC+4]的内容放到 r0和r1里,因为pc在变,所以访问的内存地址也在变,ok。

在thumb模式下,pc永远等于当前地址+4。

在执行第一句的时候,pc=5(因为是thumb),加上4等于9,访问时候去掉最后一个bit,所以r0是0x11111111。

在执行第二句的时候,pc=7(因为是thumb),加上4等于11,访问时候去掉最后一个bit,所以r1是0x22221111。

但是,实际却不是这样的,请看下面的部分。

三、正确理解

看看objdump,它认为r0是+8位置,r1也是+8位置。

 

看看ida,它直接告诉我,r0=0x11111111,r1=0x11111111。

那么问题在哪呢?我错误的理解是为什么?于是我翻官方手册,翻到了下面这段话。

A8.8.64 LDR (literal)
LDR{<c>}{<q>} <Rt>, <label> Normal form
LDR{<c>}{<q>} <Rt>, [PC, #+/-<imm>] Alternative form
The label of the literal data item that is to be loaded into <Rt>. The assembler calculates the required value of the offset from the Align(PC, 4) value of the instruction to this label.

注意,这里说访问地址时,将 PC 向4对齐后,再进行访问。而我之前错误的理解是,将最后一个bit去掉,其实是向2对齐了。所以,这里报道存在了偏差,对thumb的 PC 理解是没问题的,是 LDR 对这种情况加了特殊处理。

四、工具对它的处理

既然ldr语句自身的位置会影响到即将访问到的位置,那么各个工具是如何正确处理的呢?

这里看 pwntools 和 keystone的表现。

汇编时,它们是按照需求去翻译的,没有问题;反汇编时,会根据实际情况稍微算一下。

五、结论

thumb的ldr在处理pc相对位置时,要先让pc向4对齐,然后再访问相对偏移。


=============================================================
随着访客的增多,LeadroyaL在本站流量的开支越来越多了,曾经1元能用1个月,现在1元只能用3天。如果觉得本文帮到了你,希望能够为服务器的流量稍微打赏一点,谢谢!

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*

code