|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区
您需要 登录 才可以下载或查看,没有账号?立即注册
×
ARM和Thumb
ARM处理器有两种工作状态ARM和Thumb(Jazelle此处先不考虑)。这两种工作状态和运行模式没有任何关系。比如不论是ARM还是Thumb状态的代码都可以运行在用户模式下。这两种工作状态之间最大的差异是指令集,ARM状态的指令长度是32位的,Thumb状态的指令长度是16位的(也可能为32位)。了解如何使用Thumb工作状态对于编写ARM平台的漏洞利用是至关重要的。当我们编写ARM shellcode时,需要使用16 bit的Thumb指令代替32 bit的ARM指令,从而避免在指令中出现’’截断。
容易引起混淆的是,不同的ARM版本,支持的Thumb指令集并不相同。在某些版本中,ARM引入了扩展的Thumb指令集(也就是Thumb-2),它支持32 bit指令以及条件执行。这在原本的Thumb指令中都是不受支持的。为了在Thumb状态下支持条件执行,“it”指令被引入。然而,可能是为了简化指令集,这个指令在后来的版本中被删除了。我认为这种设计反而增加了兼容的复杂度。不过,当然我认为没必要知道所有ARM版本的ARM/Thumb指令集变体,我建议你也不必在这上面浪费太多时间。你只需要知道目标设备的版本和该版本对Thumb指令有哪些特殊支持,然后调整你的代码就好了。ARM Infocenter可以帮助你了解各个ARM版本的具体细节(http://infocenter.arm.com/help/index.jsp)。
我们已经知道了Thumb有不同的版本,下面我们对不同的版本做一下简单的介绍,注意不同的命名只是为了区分不同的版本(换句话说,处理器只知道它运行在Thumb状态,其它一概不知)。
Thumb-1(16位指令):用于ARMv6和更早的版本。
Thumb-2(16位和32位指令):对Thumb-1的扩展,添加了更多指令并允许它们为16位或32位宽(ARMv6T2,ARMv7)。
ThumbEE:在Thumb-2基础上包含了针对动态代码生成(代码在执行前或执行期间编译代码)的一些变更和补充。
ARM和Thumb的区别:
条件执行:ARM状态下的所有指令都支持条件执行。某些ARM处理器版本允许使用IT指令在Thumb中进行条件执行。条件执行提高了代码密度,因为它减少了要执行的指令数量,并节省了昂贵的分支指令。
32位ARM和Thumb指令:32位Thumb指令具有.w后缀。
桶形移位器是另一种ARM模式特有的功能。它可以将多个指令合并成一个。例如,您可以通过使用如下指令(将移位包含在MOV指令内)左移1位“Mov R1,R0,LSL#1; R1 = R0 * 2”从而代替两个乘法指令(只用乘法指令将寄存器的值乘以2,并使用MOV将结果存储到另一个寄存器中)。
要切换处理器的执行状态,必须满足以下两个条件之一:
我们可以使用分支指令BX(分支和状态切换)或BLX(分支,返回和状态切换),并将目标寄存器的最低有效位置1。这可以通过将1添加到偏移量(如0x5530+1)来实现。你可能会认为这会导致对齐问题,因为指令总是2或4字节对齐的。然而,这么做不会导致问题,因为处理器在读取指令时是忽略最低有效位的。更多的细节将在第6篇:条件分支中介绍。
如果当前程序状态寄存器中的T位置1,我们知道我们处于Thumb模式。
ARM指令简介
这一节的目的是简要介绍ARM的指令集和它的基本用法。作为汇编语言的基本单位,了解指令的用法,指令间的如何关联以及将指令进行组合能实现什么功能对于学习汇编语言是至关重要的。
ARM汇编由ARM指令组成。ARM指令通常跟一到两个操作数,我们使用如下模板描述:
MNEMONIC{S}{condition} {Rd}, Operand1, Operand2
需要指出的是,只有部分指令用到了指令模板中的所有域。模板中各字段的作用如下所示:
MNEMONIC - 指令的助记符如ADD
{S} - 可选的扩展位
- 如果指令后加了S,将依据计算结果更新CPSR寄存器中相应的FLAG
{condition} - 执行条件,如果没有指定,默认为AL(无条件执行)
{Rd} - 目的寄存器,存储指令计算结果
Operand1 - 第一个操作数,可以是一个寄存器或一个立即数
Operand2 - 第二个(可变)操作数
- 可以是一个立即数或寄存器甚至带移位操作的寄存器
助记符、S扩展位、目的寄存器和第一个操作数的作用很好理解,不多做解释,这里补充解释一下执行条件和第二个操作数。设置了执行条件的指令在执行指令前先校验CPSR寄存器中的标志位,只有标志位的组合匹配所设置的执行条件指令才会被执行。第二个操作数被称为可变操作数,因为它可以被设置为多种形式,包括立即书、寄存器、带移位操作的寄存器,如下所示:
#123 - 立即数
Rx - 寄存器比如R1
Rx, ASR n - 对寄存器中的值进行算术右移n位后的值
Rx, LSL n - 对寄存器中的值进行逻辑左移n位后的值
Rx, LSR n - 对寄存器中的值进行逻辑右移n位后的值
Rx, ROR n - 对寄存器中的值进行循环右移n位后的值
Rx, RRX - 对寄存器中的值进行带扩展的循环右移1位后的值
最后我们来看一些满足上述指令模板的常见指令,这些指令将会在后续的例子中出现。
本文由看雪翻译小组 ljcnaix 编译,来源Azeria Labs 转载请注明来自看雪社区 |
|