Android逆向-Android基礎逆向9(so相關學習干貨)

ARM 390瀏覽


0X00 前言

導航

博客導航戳這里
練習資源戳這里

IDA 是反匯編工具,Android Killer 是反編譯工具

內容

1.ARM基礎知識
2.so文件基礎知識

0x01 ARM基礎知識

SO Helper工具 介紹

這里寫圖片描述
可以直接對ARM匯編進行直接修改
這里寫圖片描述

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
這里寫圖片描述

這里寫圖片描述

首先來說說 31-28字段,cond是條件碼,就是表明這條語句里是否有大于、等于、非零等的條件判斷。
這里寫圖片描述

再來一張圖片

這里寫圖片描述

這張圖片就能更好的說明了。

指令與條件碼可以有多重組合,比如MOV指令可以有MOVEQ、MOBLT等多種形式。

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

25位,shifter_operand段存放的是立即數還是寄存器,若為寄存器則為0,如果是立即數則為1

24-21 位為opcode

這里寫圖片描述

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演示:

這里寫圖片描述

-h演示

這里寫圖片描述

-l演示

這里寫圖片描述

其他的自己回去玩

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演示

這里寫圖片描述

windows下的Linux命令

開虛擬是可以的,但是呢卻非常占用內容,那么我們想在Windows下使用Linux的命令應該怎么辦呢。

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

當然還有很多其他的方法。

以上

七星彩走势图2元网官网