arm简述

ARM(32bit)简述

ARM指令的两种模式

ARM处理器存在两种运行模式:ARM与Thumb,这两种模块均与特权模式无关,例如,运行在SVC模式的代码可以是ARM与可以是Thumb,这两种模式的主要区别在于指令集:ARM模式的指令集是32bit,Thumb模式的指令集为16bit(但是也可以是32bit)。在编写ARM shellcode的时候,确定什么时候以及如何使用thumb指令集是尤其重要的,通常编写shellcode我们需要克服null字节,我们通常可以使用Thumb指令集来替代ARM指令集,以避免null字节。
Thumb指令集存在不同版本,如下为Thumb的不同版本,命名的不同仅仅是为了区分不同版本的指令,对于机器来说,运行的都是Thumb指令集。

  • Thumb-1(16-bit):使用在ARMv6及之前的版本中
  • Thumb-2(16-bit与32-bit):在Thumb-1的基础上增加了更多的指令,并且指令长度可以是16-bit或32-bit(ARMv6T2,ARMv7)
  • ThumbEE:包括一些针对动态生成代码(dynamically generated code)的更改和添加(在执行之前或执行期间在设备上编译的代码)。

ARM与Thumb的区别

  • 条件执行:ARM模式的所有指令都支持条件执行,存在一些ARM处理器的版本允许在Thumb模式下使用IT指令实现条件执行。
  • 32-bit Thumb指令存在一个 .w 后缀
  • barrel 移位器是ARM模式的一个特性,可以使乘法指令压缩到一个指令,例如,通常乘法指令需要两个指令(将寄存器乘以2,再使用MOV将结果存入另一个寄存器),在ARM模式下可以使用移位指令将乘法包括在一个MOV指令中:

Mov R1,R0,LSL #1 ;R1=R0*2

处理器要想切换两种状态,需要满足以下两个条件之一:
  • 使用分支指令BX (branch and exchange)或BLX (branch, link, and exchange),并将目标寄存器的最低有效位设置为1。当使用bx跳转指令,跳到一个奇数地址时,默认跳到这个奇数地址-1的位置,然后标志位T位会置1,表示切换到Thumb指令集,所以我们引出下面这条指令,经常使用它来进行指令集的切换(r3随意,任意寄存器即可,别用特殊寄存器)

add r3, pc, #1
bx r3

  • 如果CPSR的Tbit置为,则代表程序处于Thumb模式

寄存器规则

  1. 子程序间通过寄存器R0~R3来传递参数。这时,寄存器R0~R3可记作arg0~arg3。被调用的子程序在返回前无需恢复寄存器R0~R3的内容,R0被用来存储函数调用的返回值。
  2. 在子程序中,使用寄存器R4~R11来保存局部变量。这时,寄存器R4~R11可以记作var1~var8。如果在子程序中使用了寄存器v1~v8中的某些寄存器,则子程序进入时必须保存这些寄存器的值,在返回前必须恢复这些寄存器的值。R7经常被用作存储系统调用号,R11存放着帮助我们找到栈帧边界的指针,记作FP。在Thumb程序中,通常只能使用寄存器R4~R7来保存局部变量。
  3. 寄存器R12用作过程调用中间临时寄存器,记作IP。在子程序之间的连接代码段中常常有这种使用规则。
  4. 寄存器R13(Stack Pointer)用作堆栈指针,记作SP。在子程序中寄存器R13不能用作其他用途。寄存器SP在进入子程序时的值和退出子程序时的值必须相等。
  5. 寄存器R14(Link Registe)称为连接寄存器,记作LR。它用于保存子程序的返回地址。如果在子程序中保存了返回地址,寄存器R14则可以用作其他用途。
  6. 寄存器R15(Program Counter)是程序计数器,记作PC。每次执行指令,PC自动增加对应执行指令的长度,在ARM中总是4字节,Thumb总是2字节,在执行分支指令时,PC指向目的地址,在执行过程中,PC通常指向当前指令+2条指令长度的地址,即在ARM模式下,PC指向当前指令地址+8,在Thumb模式下,PC指向当前指令+4。这个和汇编指令的流水线有关吧

在这里插入图片描述
CPSR:Curren Program Status Register,当前状态寄存器,相当于x86里的EFLAG寄存器。上图为32-bit ARM中的CPSR(最右为低地址),对应字段如下:
在这里插入图片描述

ARM架构寄存器与Intel架构寄存器对比:

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

传参规则

  • 对于参数个数可变的子程序,当参数个数不超过4个时,可以使用寄存器R0~R3来传递参数;当参数超过4个时,还可以使用堆栈来传递参数。
  • 在传递参数时,将所有参数看作是存放在连续的内存字单元的字数据。然后,依次将各字数据传递到寄存器R0,R1,R2和R3中。如果参数多于4个,则将剩余的字数据传递到堆栈中。入栈的顺序与参数传递顺序相反,即最后一个字数据先入栈。

返回值规则

  • 结果为一个32位整数时,可以通过寄存器R0返回
  • 结果为一个64位整数时,可以通过寄存器R0和R1返回
  • 结果为一个浮点数时,可以通过浮点运算部件的寄存器f0、d0或s0来返回
  • 结果为复合型浮点数(如复数)时,可以通过寄存器f0fn或d0dn来返回
  • 对于位数更多的结果,需要通过内存来传递。

汇编

简略了解可以参考壁纸图片
https://blog.csdn.net/github_38641765/article/details/85208743
详细可以参考arm汇编指令以及安全客-ARM架构下的 Pwn 的一般解决思路
知乎

AArch64

需要指出的是,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对齐

参考blog

安全客-ARM架构下的 Pwn 的一般解决思路
简书
arm汇编指令
知乎

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值