Android逆向-Android基础逆向9(so相关学习干货)

时间:2021-06-08 00:34:24

0X00 前言

导航

博客导航戳这里
练习资源戳这里

IDA 是反汇编工具,Android Killer 是反编译工具

内容

1.ARM基础知识
2.so文件基础知识

0x01 ARM基础知识

SO Helper工具 介绍

Android逆向-Android基础逆向9(so相关学习干货)
可以直接对ARM汇编进行直接修改
Android逆向-Android基础逆向9(so相关学习干货)

ARM介绍

ARM是ARM公司的32位处理器。ARM汇编指令的机器码就是32位。

ARM的作用

学会了ARM,就会了主流的嵌入式开发。
还可以进行硬件编程,可以从事机器人或机械制造。

ARM 和Thumb指令

Thumb 是16位的ARM汇编。
如同样的beq,bne这两个汇编指令,用ARM的4个HEX数表示时,
其HEX值为0A,1A,而当用2个HEX数表示时,其HEX值为D0,D1。
在动态调试的时候,IDA无法分辨ARM和Thumb指令。所以需要人工去进行纠正和调整。

ARM的机器码

ARM机器码的一般格式。
举一个实例:
movne r2,r1
0001 00 0 1101 0 0000 0010 000000000001
Android逆向-Android基础逆向9(so相关学习干货)

Android逆向-Android基础逆向9(so相关学习干货)

首先来说说 31-28字段,cond是条件码,就是表明这条语句里是否有大于、等于、非零等的条件判断。
Android逆向-Android基础逆向9(so相关学习干货)

再来一张图片

Android逆向-Android基础逆向9(so相关学习干货)

这张图片就能更好的说明了。

指令与条件码可以有多重组合,比如MOV指令可以有MOVEQ、MOBLT等多种形式。

27-26位为保留位,恒为00

25位,shifter_operand段存放的是立即数还是寄存器,若为寄存器则为0,如果是立即数则为1

24-21 位为opcode

Android逆向-Android基础逆向9(so相关学习干货)

20位:表明指令是否会影响程序状态寄存器,如果是就是1,否则为0。

19-16位,表示第一个源操作数寄存器。

11-0 目的寄存器

ARM寄存器

R0-R7: 通用寄存器
R8-R10:不常用的通用寄存器
R11:基质寄存器(FP)
R12:暂时寄存器(IP)
R13:堆栈制作(SP)
R14:链接寄存器(LR)
CPSR:状态寄存器

ARM指令集

B 无条件跳转
BL 带链接的无条件跳转
BLX 带状态的无条件跳转

BNE 不相等跳转
BEQ 相等跳转

寄存器交互指令

LDR 从存储器中加载数据到寄存器。
LDR R1,[R2],把R2指向的位置的数据给R1

STR:把寄存器的数据存储到存储器
STR R1,[R2],在R2指向的地址,存储R1

LDM :将存储器的数据加载到一个寄存器列表。
LDM R0,{R1,R2,R3},把R0中的数据一次加载到R1,R2,R3

SDM: 将一个寄存器列表的数据存储到指定的存储器
SDM R0,{R1,R2,R3},把R1,R2,R3加载到R0单元

PUSH:入栈
POP:出栈

数据传送指令

MOV 将立即数或寄存器的数据传送到目标寄存器

数据算数运算指令

ADD : 加法
(Addition)
ADD{条件}{S} , , dest = op_1 + op_2
ADD 将把两个操作数加起来,把结果放置到目的寄存器中。操作数 1 是一个寄存器,操作数 2 可以是一个寄存器,被移位的寄存器,或一个立即值:
ADD R0, R1, R2 ; R0 = R1 + R2 ADD R0, R1, #256 ; R0 = R1 + 256 ADD R0, R2, R3,LSL#1 ; R0 = R2 + (R3 << 1)
加法可以在有符号和无符号数上进行。
ps:带进位的加法ADC

SUB : 减法
(Subtraction)
SUB{条件}{S} , , dest = op_1 - op_2
SUB 用操作数 one 减去操作数 two,把结果放置到目的寄存器中。操作数 1 是一个寄存器,操作数 2 可以是一个寄存器,被移位的寄存器,或一个立即值:
SUB R0, R1, R2 ; R0 = R1 - R2 SUB R0, R1, #256 ; R0 = R1 - 256 SUB R0, R2, R3,LSL#1 ; R0 = R2 - (R3 << 1)
减法可以在有符号和无符号数上进行。
ps:带进位的减法SBC

MUL : 乘法
这两个指令与普通算术指令在对操作数的限制上有所不同:
给出的所有操作数、和目的寄存器必须为简单的寄存器。
你不能对操作数 2 使用立即值或被移位的寄存器。
目的寄存器和操作数 1 必须是不同的寄存器。
最后,你不能指定 R15 为目的寄存器
(Multiplication)
ps:带累加的乘法MLA
MUL{条件}{S} , , dest = op_1 * op_2
MUL 提供 32 位整数乘法。如果操作数是有符号的,可以假定结果也是有符号的。

DIV除法
SDIV 带符号除法
UDIV 不带符号位除法

数据逻辑运算指令

与:AND
或:ORR
异或:EOR

LSL:逻辑左移
LSR:逻辑右移

比较指令

CMP:比较指令

其他指令

SWT:切换用户模式
伪指令:DCB

寻址方式

恩,其实和8086挺像的

7种,但是是分享常用的

立即寻址:MOV R0,#1234 R0=0X1234
寄存器寻址:MOV R0,R1 R0=R1
寄存器移位寻址:MOV R0,R1,LSL #2 R0=R1*4
寄存器间接寻址:LDR R0,[R1] 将R1寄存器中的值作为地址,取出地址中的值赋予R0
寄存器间接基址偏移寻址:LDR R0,[R1,#-4]将R1寄存器的值-0x4的值作为地址,取出地址中的值给R0

汇编难以分析的原因

1.IDA自身的缺陷
2.函数库与类有时无法识别
3.自身对ARM汇编的熟练度

0x02 so简要说明

和Linux的关系

.so文件实际上是Linux文件里的动态链接库。

还有一些其他文件,比如说静态可执行文件,,没有后缀名。

如果在linux下编写用过gcc文件。那么就要生成可执行文件。

so文件的来源

so文件主要是通过NDK编程来源。因为是程序猿,所有通过Android Studio就可以编译了。具体请看之前的文章。

so文件的文件格式

so文件的文件格式是ELF文件。有自己的文件格式。一般的文件都分为静态下的状态和动态下的状态,当然之后要对ELF文件进行一个分析,之前姜大佬分析过了,不过这个是人家分析的,只有自己过一遍才能对ELF进行一个更深的了解。当然这个会在10中进行说明。

readelf指令

readelf命令用来显示一个或者多个elf格式的目标文件的信息,可以通过它的选项来控制显示哪些信息。这里的elf-file(s)就表示那些被检查的文件。可以支持32位,64位的elf格式文件,也支持包含elf文件的文档(这里一般指的是使用ar命令将一些elf文件打包之后生成的例如lib*.a之类的“静态库”文件)。

部分指令:

-a --all 显示全部信息,等价于 -h -l -S -s -r -d -V -A -I. 
-h --file-header 显示elf文件开始的文件头信息. 
-l --program-headers --segments 显示程序头(段头)信息(如果有的话)。 
-S --section-headers --sections 显示节头信息(如果有的话)。 
-s --syms --symbols 显示符号表段中的项(如果有的话)。 
-d --dynamic 显示动态段的信息。 
-V --version-info 显示版本段的信息。 
-A --arch-specific 显示CPU构架信息。 
-I --histogram 显示符号的时候,显示bucket list长度的柱状图。 

-a演示:

Android逆向-Android基础逆向9(so相关学习干货)

-h演示

Android逆向-Android基础逆向9(so相关学习干货)

-l演示

Android逆向-Android基础逆向9(so相关学习干货)

其他的自己回去玩

objdump指令

objdump命令是用查看目标文件或者可执行的目标文件的构成的gcc工具。

一些常用命令

-a 显示档案库的成员信息,类似ls -l将lib*.a的信息列出。 

-V --version 版本信息 

--debugging -g 显示调试信息。企图解析保存在文件中的调试信息并以C语言的语法显示出来。仅仅支持某些类型的调试信息。有些其他的格式被readelf -w支持。

--disassemble -d 从objfile中反汇编那些特定指令机器码的section。 

-f --file-headers 显示objfile中每个文件的整体头部摘要信息。 

-h --section-headers --headers 显示目标文件各个section的头部摘要信息。 

-H --help 简短的帮助信息。 

-V演示

Android逆向-Android基础逆向9(so相关学习干货)

windows下的Linux命令

开虚拟是可以的,但是呢却非常占用内容,那么我们想在Windows下使用Linux的命令应该怎么办呢。

使用cygwin即可。安装或者其他,自行Google or 百度。

当然还有很多其他的方法。

以上