IOS 逆向开发(二十六) 汇编-寄存器总结

@[TOC](IOS 逆向开发(二十六) 汇编-寄存器总结)

IOS 逆向开发(二十六) 汇编-寄存器总结

  • 本篇主要讲解关于寄存器相关的知识,我们在逆向的过程中会经常和寄存器打交道。如果我们逆向不懂汇编将不会研究得很深入,如果我们能够看懂汇编代码,将会大大提高我们调试代码和逆向的能力。

先来回顾一些历史性的问题。

  • 汇编语言有哪些种类?
  1. 8086汇编 ,16位
  2. x86汇编, 32位
  3. x64汇编, 64位
  4. ARM 汇编, 主要是在嵌入式手持设备中,我们做IOS逆向,就是主要研究这个。

那么做IOS逆向,最主要的汇编语言是什么呢?

  1. AT & T 汇编, 对应的是IOS模拟器
  2. ARM汇编, 对应的是IOS真机

我们知道Objective C源文件(.m)的编译器是Clang + LLVM,Swift源文件的编译器是swift + LLVM。所以借助clang命令,我们可以查看一个.c或者.m源文件的汇编结果:

x86架构的汇编:

clang -S KYLDemo.m

ARM64我们可以借助xcrun:

xcrun --sdk iphoneos clang -S -arch arm64 KYLDemo.m

前面也提到,做IOS逆向经常要用到的就是寄存器地址分析,那么我们常见的寄存器有哪些呢?

  • 16个常用寄存器:
  1. rax、rbx、rcx 、rdx、rsi、rdi、rbp、rsp
  2. r8、r9、r10、r11、r12、r13、r14、r15

其中:

rax: 常作为函数返回值使用
rdi、rsi、rdx、rcx、r8、r9等寄存器常用于存放函数参数
rsp、rbp用于栈操作
rip作为指令指针: 存储着CPU下一条要执行的指令的地址. 一旦CPU读取一条指令,rip会自动指向下一条指令(存储下一条指令的地址)

这里只是简单概括一下寄存器的种类,下面会详细介绍。

我们了解寄存器后是不够的,逆向时还需要理解各种汇编指令,下面列举一些常见的汇编指令:

指令名称/作用AT & T 汇编语法Intel汇编语法说明
寄存器命名%raxrax
操作数顺序movq %rax, %rdxmov rdx, rax将rax的值赋值给rdx
常数/立即数movq $0x10, %raxmov rax, 0x10将0x10赋值给rax
内存赋值movq $0xa, 0x1ff7(%rip)mov qword ptr [rip+0x1ff7], 0xa将0xa赋值给地址为rip+0x1ff7的内存空间
取内存地址leaq - 0x18(%rbp), %raxlea rax, [rbp - 0x18]将rbp - 0x18这个地址值赋值给rax
jmp指令jmp *%rdxjmp rdxcall和jmp写法类似
操作数长度leaw 0x10(%dx), %axlea ax, [dx + 0x10]b = byte(8位) , s= short(16位整型或者32位浮点类型), w = word (16位整型), l = long(32为整型或64位浮点类型), q = quad (64位)

理解了汇编指令后,我们很多时候做逆向的时候,依赖于命令行调试,所以了解一些常用的lldb调试指令是必须的。

指令作用或名称用法举例说明
读取寄存器的值register read/格式,register read/x
修改寄存器的值register write 寄存器名称 数值register write rax 0
读取内存中的值x/数量-格式-字节大小 内存地址x/3xw 0x0000010
修改内存中的值memory write 内存地址 数值memory write 0x0000010 10
格式x是16进制,f是浮点,d是十进制
字节大小b – byte 1字节, h – half word 2字节,w – word 4字节, g – giant word 8字节
expression 表达式可以简写:expr 表达式expression $rax, expression $rax = 1
po 表达式po 内存地址po &0x1000010
打印信息 print 表达式po/x $raxpo (int)$rax
指令作用或名称用法举例说明
thread step-over、next、n单步运⾏行行,把子函数当做整体⼀一步执⾏行行(源码级别)
thread step-in、step、s单步运⾏行行,遇到子函数会进⼊入子函数(源码级别)
thread step-inst-over、nexti、ni单步运⾏行行,把子函数当做整体⼀一步执⾏行行(汇编级别)
thread step-inst、stepi、si单步运⾏行行,遇到子函数会进⼊入子函数(汇编级别)
thread step-out、finish直接执⾏行行完当前函数的所有代码,返回到上一个函数(遇到断点会卡住)

寄存器

因为我们主要是研究IOS的逆向需要的汇编知识,所以重点是ARM架构。ARM的全称是Advanced RISC Machine,翻译过来是高级精简指令集机器。

iOS设备CPU架构都是基于ARM的,做过早起IOS开发的肯定对IOS的系统架构非常熟悉了,arm64,arm7…它们指的都是CPU指令集。iPhone 5s及以后的iOS设备的CPU都是ARM 64架构的。

通用寄存器

通用寄存器可用于传送和暂存数据,也可参与算术逻辑运算,并保存运算结果。除此之外,它们还各自具有一些特殊功能。通用寄存器的长度取决于机器字长,汇编语言程序员必须熟悉每个寄存器的一般用途和特殊用途,只有这样,才能在程序中做到正确、合理地使用它们。

16位cpu通用寄存器共有 8 个:AX,BX,CX,DX,BP,SP,SI,DI. 这八个寄存器都可以作为普通的数据寄存器使用。但有的有特殊的用途:AX为累加器,CX为计数器,BX,BP为基址寄存器,SI,DI为变址寄存器,BP还可以是基
指针,SP为堆栈指针。

32位cpu通用寄存器共有 8 个: EAX,EBX,ECX,EDX,EBP,ESP,ESI,EDI功能和上面差不多

而我们用的IPhone 设备中,ARM64常见的的通用寄存器31个64bit,命名为x0-x30。

通用寄存器主要分为5大类:

  • 数据寄存器
  • 变址寄存器
  • 指针寄存器
  • 段寄存器
  • 指令指针寄存器

接下来我们看看这些通用寄存器的作用:

寄存器特殊用途作用说明
SP堆栈指针可以把栈理解为存储数据的容器,而Stack Pointer告诉你这个容器有多高,你可以通过移动Stack Pointer来增加/减少你的容器容量。
x30LR链接寄存器在子程序调用的时候保存下一个要执行指令的内存地址
x29FP帧指针保存函数栈的基地址
x19…x28Callee-saved寄存器
x18平台保留寄存器,应用不可以使用。
x17IP1第二个过程内调用临时寄存器(可以被调用单板和PLT代码使用);在其他时候可以用作临时寄存器。
x16IP0第一个内部过程调用的scratch寄存器(可以被调用单板和PLT代码使用);在其他时候可以用作临时寄存器。
x9…r15临时寄存器
x8间接返回值寄存器,在一些特殊情况下,函数的返回值是通过x8返回的。
x0…x7用来参数传递给子程序或者从函数中返回值,也可以用来存储中间值
寄存器特殊用途作用说明
PC寄存器PC寄存器保存下一条将要执行的指令的地址,正常情况下PC指令加1,顺序执行下一跳指令,PC按条件执行指令(比如依次执行指令1,指令5,指令3),是条件分支(比如if/while)的理论基础。
FLAGS程序状态寄FLAGS程序状态寄存器,保存若干flags,数据处理的指令会修改这些状态,条件分支指令会读取flag,决定跳转。
XZR,和WZR代表零寄存器。
寄存器AX寄存器AX乘、除运算,字的输入输出,中间结果的缓存
ALAL字节的乘、除运算,字节的输入输出,十进制算术运算
AH
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值