Android逆向—ARM汇编(一)

    xiaoxiao2021-08-22  133

    Android逆向—ARM汇编(一)

    ARM概述

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

     

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

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

     

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

     

    ARM指令集 ARM处理器可以支持3种指令集——ARMThumbJazelle

    采用那种指令集,由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):运行具有特权的操作系统任务;

    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

     

     

     

     

    转载请注明原文地址: https://ju.6miu.com/read-676839.html

    最新回复(0)