赞
踩
ARM处理器存在两种运行模式:ARM与Thumb,这两种模块均与特权模式无关,例如,运行在SVC模式的代码可以是ARM与可以是Thumb,这两种模式的主要区别在于指令集:ARM模式的指令集是32bit,Thumb模式的指令集为16bit(但是也可以是32bit)。在编写ARM shellcode的时候,确定什么时候以及如何使用thumb指令集是尤其重要的,通常编写shellcode我们需要克服null字节,我们通常可以使用Thumb指令集来替代ARM指令集,以避免null字节。
Thumb指令集存在不同版本,如下为Thumb的不同版本,命名的不同仅仅是为了区分不同版本的指令,对于机器来说,运行的都是Thumb指令集。
Mov R1,R0,LSL #1 ;R1=R0*2
add r3, pc, #1
bx r3
CPSR:Curren Program Status Register,当前状态寄存器,相当于x86里的EFLAG寄存器。上图为32-bit ARM中的CPSR(最右为低地址),对应字段如下:
ARM架构 寄存器名 | 寄存器描述 | Intel架构 寄存器名 |
---|---|---|
R0 | 通用寄存器 | EAX |
R1~R5 | 通用寄存器 | EBX、ECX、EDX、EDI、ESI |
R6~R10 | 通用寄存器 | 无 |
R11(FP) | 栈帧指针 | EBP |
R12(IP) | 内部程序调用 | 无 |
R13(SP) | 堆栈指针 | ESP |
R14(LP) | 链接寄存器 | 无 |
R15(PC) | 程序计数器 | EIP |
CPSR | 程序状态寄存器 | EFLAGS |
简略了解可以参考壁纸图片
详细可以参考arm汇编指令以及安全客-ARM架构下的 Pwn 的一般解决思路
知乎
需要指出的是,AArch64架构并不是ARM-32架构的简单扩展,他是在ARMv8引入的一种全新架构。ARMv支持3种指令集,A64、A32和T32。AArch拥有31个通用寄存器(X0~X30或者W0~W30),系统运行在64位状态下的时候名字叫Xn,运行在32位的时候就叫Wn。,指令中设计的寄存器(X或W)决定了指令操作位数,如ADD W0,W1,W2 实现的是32bit运算;ADD X0,X1,X2实现的是64bit运算 。除此之外,还可以有其他bit运算,如Bx代表8bit,Hx代表16bit,Sx代表32bit,Dx代表64bit,Qx代表128bit
X0~X7:用于函数传参(32bit用W,64bit用X),多余8位的用栈传递
X8:XR寄存器,当被调用函数返回一个结构时,X8为当前结构体的地址
X9~X15:用于函数内部调用
X16/X17 :Intra-Procedure-call寄存器,连接器使用这些寄存器在调用者和被调用者之间插入单板(veneer)。单板是小块代码。最常见的例子是分支范围扩展。A64中的分支指令范围有限。如果目标超出了这个范围,那么连接器需要生成一个单板来扩展分支的范围。
XZR/WZR :0寄存器,永远代表0
X29:frame pointer,帧寄存器
SP:stack pointer,ARMv8里有多个SP,每个SP与一个具体的异常等级(Exception level)相关联
X30:用于Link Register,等价于arm中的LR寄存器
PC:程序计数器,A64中PC不再是通用寄存器,并且不可以用于数据处理指令,PC的值可以通过如下指令读取
ADR Xd,.
其中ADR返回一个label的地址,"."符号表示当前位置,上述指令即加载当前指令位置,等价于读取PC指令值
SVC :supervisor call:造成EL1层的异常,用于应用向OS发送请求
HVC :hypervisor call:造成EL2层的异常,用于OS调用hypervisor,EL0层不可使用该指令
SMC :Secure monitor call:造成EL3层的异常,用于OS或者hypervisor调用EL3的firmware,EL0层不可使用该指令
aarch64里用LDP(load pair)和STP(store pair)取代了LDM和STM,LDM与STM没有限制寄存器操作数的数量,但是LDP和STP规定一次LDP和STP指令只能操作2个寄存器,其基本含义如下
将X0寄存器的值所表示的内存处的值存入W3中,即w3=[X0];将X0寄存器的值+4所表示的内存处的值存入W7,即w7=[X0+4]
LDP W3, W7, [X0]
将DO值存入X4寄存器表示的内存中,将D1值存入X4寄存器的值8所表示的内存中,即[X4]=D0,[X4+8]=D1
STP D0, D1, [X4]
STP和LDP通常用来其push和pop作用,如下将X0和X1压入栈
STP X0, X1, [SP, #-16]!
如下指令从栈中弹出X0和X1
LDP X0, X1, [SP], #16
记住在AARCH64中stack poniter需要128bit对齐
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。