您的位置:首页 > 移动开发 > Android开发

Android逆向—ARM汇编(一)

2016-11-18 00:08 316 查看

Android逆向—ARM汇编(一)

ARM概述

ARM处理器是英国Acorn有限公司设计的低功耗成本的第一款RISC微处理器。全称为Acorn
RISC Machine。ARM处理器本身是32位设计,但也配备16位指令集,一般来讲比等价32位代码节省达35%,却能保留32位系统的所有优势。ARM公司是一个特别的公司,是一家CPU设计公司,ARM的经营模式在于出售其知识产权核(IP
core),授权厂家依照设计制作出建构于此核的微控制器和中央处理器。最成功的实作案例属 ARM7TDMI,几乎卖出了数亿套内建微控制器的装置。还可以可以针对企业做定制版的CPU。

 

为什么移动端,嵌入式设备喜欢ARM架构的处理器:这是因为ARM CPU特点,体积小,高性能,低功耗,成本低。

由于节能的特点,ARM处理器非常适用于移动通讯领域,符合其主要设计目标为低耗电的特性。在加上成本低,所以在在移动端,ARM CPU的占用率高达99%。现在Intel从Core处理器也开始开始降功耗,但是不明显。

 

经典系列:ARM1 - ARM11,ARM8
以上是64位, 大部分ARM程序是32位程序。Cortex-A,智能手机端。
由于ARM CPU 普及率高,所以我们研究某种嵌入式设备软件的逆向,也变得简单了,这是后话。说了那么多ARM好,ARM棒,ARM顶呱呱的话,我们回到我们指令集,这才是我们关心的。

 

ARM指令集
ARM处理器可以支持3种指令集——ARM,Thumb和Jazelle

采用那种指令集,由cspr中的标志位来决定。大体说来:

◆ ARM——这是ARM自身的32位指令集

◆ Thumb ——这是一个全16位的指令集,在16位外部数据总线宽度下,这个指令集的效率要比32位的ARM指令高一些。

◆ Jazelle ——这是一个8位指令集,用来加速Java字节码的执行

 

ARM约定:

BYTE(字节):      8Bits

HalfWORD(半字): 16bits

WORD(字):       32bits

 

ARM流水线:

ARM处理器的指令属于定长指令,所以每个指令的取指,译码,周期都是一致的,除了指向周期可能不一致(大部分指令执行周期一致).

ARM的流水线是3级流水线,如下,

1  2  3          

   1  2  3

      1  2  3

最先的ARM的流水线6级流水, 这样是为了解决指令同步问题。

 

ARM 寄存器

特殊的寄存器,在汇编中中,我们常有另外助记符

R15: PC => EIP

R14: LR => 链接寄存器,CALL指令存放返回地址,还是用栈

R13: SP => 堆栈指针

ARM寄存器:31个通用寄存器   6个状态寄存器

 

ARM 工作模式:

1、用户模式(Usr):用于正常执行程序;

2、快速中断模式(FIQ):用于高速数据传输;

3、外部中断模式(IRQ):用于通常的中断处理;

4、管理模式(svc):操作系统使用的保护模式;

5、数据访问终止模式(abt):当数据或指令预取终止时进入该模式,可用于虚拟存储以及存储保护;

6、系统模式(sys):运
b81d
行具有特权的操作系统任务;

7、未定义指令中止模式(und):当未定义的指令执行时进入该模式,可用于支持硬件;

 

Arm的工作模式切换有两种方法:

被动切换:在arm运行的时候产生一些异常或者中断来自动进行模式切换

主动切换:通过软件改变,即软件设置寄存器来经行arm的模式切换,应为arm的工作模式都是可以通过相应寄存器的赋值来切换的。

 

Tips:当处理器运行在用户模式下,某些被保护的系统资源是不能被访问的。

 

除用户模式外,其余6种工作模式都属于特权模式;

特权模式中除了系统模式以外的其余5种模式称为异常模式;

大多数程序运行于用户模式;

进入特权模式是为了处理中断、异常、或者访问被保护的系统资源;

 

 

 

ARM汇编

arm汇编编译器: gun-as

ARM汇编帮助文档:http://sourceware.org/binutils/docs/as/index.html 

 

一段ARM汇编代码的分析:

.arch armv5te       

;.arch: 指定ARM架构版本                 

.fpu softvfp

;.fpu: 指定浮点运算的处理方法,softvfp:软件实现浮点与运算       

.section.rodata

    ;.section: 定义一个节,rodata:只读数据节   

.align2

    ;.align: 对齐单位2字节

.LC0:

.ascii"Hello World\000"

    ;.ascii:定义数据串

.text

.align2

.globalmain

    ;.global:声明一个全局符号main

.typemain, %function

main:

;定义main函数

@ args = 0, pretend = 0, frame = 8

@ frame_needed = 1, uses_anonymous_args = 0

stmfdsp!, {fp, lr}

;将fp,lr入展, 调用函数是,lr保存调用函数的返回地址

addfp, sp, #4

;将fp = sp+4,相当intel bp,用于访问参数和局部变量

subsp, sp, #8

;将sp = sp-8,申请函数内部局部变量空间

strr0, [fp, #-8]

;ARM 中函数调用约定,R0-R3,存储1-4的参数,多余4个参数,栈传参,

;str 指令,将寄存器的值存储到内存中,  将参数0存储在预留空间

strr1, [fp, #-12]

    ;将参数1存储在预留空间

ldrr3,.L2

.LPIC0:

addr3, pc, r3

    ;r3指向Helle World字符串

movr0, r3

;传参

blputs(PLT)

;调用函数puts, PLT:Procedure Linkage Table(相当于PE导入表)

movr3, #0

movr0, r3

;r0=0 返回值

subsp, fp, #4

;r0=0 回收函数内部局部变量空间

ldmfdsp!, {fp, pc}

; 1.还原非pc寄存器环境

; 2.pc = lr

.L3:

.align2

.L2:

.word.LC0-(.LPIC0+8)

    ;在地址L2处定义一个32位常量,常量值:.LC0-(.LPIC0+8),这个

.sizemain, .-main

.ident"GCC: (GNU) 4.6 20120106 (prerelease)"

.section.note.GNU-stack,"",%progbits

 

 

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: