靜態: dex so
資源逆向工具 AXMKPrinter2(Android binary XML):
java -jar AXMLPrinter2.jar xxx.xml output.xml
查看源碼工具dex2jar(dex->jar)、jd-GUI(jar->java):
APK逆向工具APKTool(resources.arsc/xml資源文件/.dex文件):
apktool d input.apk -o output
Android逆向助手(APKTOOL/jd-gui/dex2jar/jarsigner):
反彙編工具IDA PRO:
APK文件:
zip壓縮包
解釋性語言smali語言
反編譯前結構:
assets 聲音、字體、網頁······資源【無編譯可以直接查看】
com 第三方庫,不解釋
lib 應用中使用到的庫
armeabi .so文件,C/C++代碼庫文件【重要】
META-INF APK的簽名文件【***.RSA、***.SF、***.MF3文件】
org 第三方庫,如org.apache.http庫
res 應用中使用到的資源目錄,已編譯無法直接閱讀
anim 動畫資源animation
color 顏色資源
drawable 可繪製的圖片資源
drawable-hdpi 圖片資源高清
drawable-land 圖片資源橫向
drawable-land-hdpi 圖片資源橫向高清
drawable-mdpi 圖片資源中等清晰度
drawable-port 圖片資源縱向
drawable-port-hdpi 圖片資源縱向高清
layout 頁面佈局文件
layout-land 頁面佈局文件橫向
layout-port 頁面佈局文件縱向
xml 應用屬性配置文件
AndroidManifest.xml 應用的屬性定義文件,已壓縮無法直接閱讀【重要】
classes.dex Java源碼編譯後的代碼文件【重要】
resources.arsc 編譯後的資源文件,如strings.xml文件【重要】
反編譯後結構:
assets 聲音、字體、網頁······資源
lib 應用中使用到的庫
armeabi .so文件,C/C++代碼庫文件【重要】【JNI部分】【無法閱讀】
META-INF APK的簽名文件【***.RSA、***.SF、***.MF3文件】
org 第三方庫,如org.apache.http庫
res 應用中使用到的資源目錄,目錄下的東西可以直接閱讀
anim 動畫資源animation【可以直接閱讀】
color 顏色資源【可以直接閱讀】
drawable 可繪製的圖片資源【可以直接閱讀】
drawable-hdpi 圖片資源高清【可以直接閱讀】
drawable-land 圖片資源橫向【可以直接閱讀】
drawable-land-hdpi 圖片資源橫向高清【可以直接閱讀】
drawable-mdpi 圖片資源中等清晰度【可以直接閱讀】
drawable-port 圖片資源縱向【可以直接閱讀】
drawable-port-hdpi 圖片資源縱向高清【可以直接閱讀】
layout 頁面佈局文件【可以直接閱讀】【重要】
layout-land 頁面佈局文件橫向【可以直接閱讀】【重要】
layout-port 頁面佈局文件縱向【可以直接閱讀】【重要】
values
strings.xml 應用中使用到的字符串常量【可以直接閱讀】【重要】
dimens.xml 間隔(dip、sp)常量【可以直接閱讀】
xml 應用屬性配置文件【可以直接閱讀】
AndroidManifest.xml 應用的屬性定義文件,【可以直接閱讀】【重要】
smali Java 代碼反編譯後生成的代碼文件,【smali語法】【重要】
apktool.ymlapktool 反編譯的配置文件,用於重新打包
學習Smali語言的語法與結構
逆向分析.so文件,.so文件是二進制文件
分析DEX文件:Dalvik Executable
smali:DEX執行文件格式的彙編器
baksmali:DEX執行文件格式的反彙編器
DEX文件生成過程:
JVM虛擬機 Dalvik虛擬機
.Java文件-->Javac編譯-->.class文件-->dx編譯-->.dex文件
DEX文件結構: Header、Table、Data
Header:存儲的是所有區域片段的大小、偏移量
Table:存儲的是各種結構化數據、引用數據以及數據的偏移量
Data:存儲的是具體的數據以及代碼邏輯
虛擬機指令smali:
smali:寄存器指令
Java: 解釋性語言
Smali語法基礎:
Java語法 Smali語法 說明
private boolean isFlag .field private isFlag:z 定義變量
Package .class 指定當前的類名
.super 所繼承的父類
.local 定義使用局部變量
.method 方法
.parameter 方法參數
.prologue 方法開始
.line 12 此方法位於.java中的第12行,可去除,不影響運行結果
super invoke-super 調用父函數
const/high16 v0,0x7fo3 把ox7fo3賦值給v0
invoke-direct 調用函數
return Return-void 函數返回void
.end method 函數結束
new new-instance 創建實例
iput-object 對象賦值
iget-object 調用對象
invoke-static 調用靜態函數
if(vA == vB) if-eq vA,vB 如果vA等於vB
先寫java代碼,再反編譯獲取smali指令
分析SO文件:
廣告植入與去除:
掛廣告:導入SDK、權限配置、廣告組件配置、初始化、加載插屏廣告
收費限制:邏輯反轉
漢化:strings.xml
動態:DDMS、emulator、Andbug、IDA PRO
代碼安全分析: APK文件
組件安全分析:四大組件
存儲安全分析:數據、私有文件
通信安全分析:證書密碼技術
TraceView:方法跟蹤
加入調試函數: Debug.startMethodTracing()/Debug.stopMethodTracing()
dmtracedump
graphviz
IDA PRO: so dex
Hook技術:劫持函數調用
java層級的hook:java反射
native層級的hook:ELF文件
ptrace函數附加進程:動態地attach(跟蹤一個目標進程)、detach(結束跟蹤一個目標進程)、peektext(獲取內存字節)、poketext(向內存寫入地址)等
加載so庫:dlopen,以指定模式打開指定的動態鏈接庫文件
目標進程的虛擬地址空間解析與ELF文件解析:
通過讀取/proc/<PID>/maps文件找到鏈接庫的基地址
讀取動態庫,解析ELF文件,找到符號(需要對ELF文件格式的深入理解)
計算目標函數ude絕對地址
目標進程函數絕對地址=函數地址+動態庫基地址
用ptrace函數attach上目標進程
發現裝載共享庫so函數
裝載指定的.so
讓目標進程的執行流程轉到注入的代碼執行
使用ptrace函數的detach釋放目標進程
ptrace函數:
int ptrace(int requets, int pid, int addr, int data)
request: 請求ptrace執行的操作
pid:目標進程的ID
addr:目標進程的地址值
data:作用的數據
Android中so庫文件: Got表Hook、Sym表Hook、inline Hook
java反射問題: 無法反射調用關鍵字爲native的方法函數(JNI實現的函數)、基本類型的靜態常量無法反射修改
zygote進程:Hook框架Xposed、Cydiasubstrate(app_process)
Hook工具:
Xposed框架:/system/bin/app_process java層級
Per App Setting(爲每個應用設置單獨的dpi或修改權限)
Cydia
XPrivacy(防止隱私泄露)
BootManager(開啓自啓動程序管理應用)
安裝本地服務XposedInstaller
下載使用API庫
Cydiasubstrate框架:java/native層級
安裝Cydiasubstrate框架本地服務
下載使用Cydiasubstrate庫
ADBI/DDI框架:java/native層級
命令行工具
虛擬文件系統:/proc目錄
Android內核空間和用戶空間之間進行通信,查看當前進程的一些狀態信息
maps文件查看進程的虛擬地址空間如何使用
cat /proc/<PID>/maps
/data/*.dex //java層級
/data/*.so //native層級
dev/__properties__
https://www.qubes-os.org/screenshots/
應用加固:
最小化組件暴露:
android:exported="false" //不跨應用,私有
protectionLevel=["normal" | "dangerous" | "signature" | "signatureOrSystem" //簽名權限
android:permission= //訪問權限
Activity安全:
私有Activity:android:exported="false"
公共Activity:android:exported="true"
夥伴Activity:android:exported="false" GetSignature getPackageInfo //應用簽名
內部Activity:android:exported="true" protectionLevel="signature" GetSignature getPackageInfo //應用簽名
Broadcast Receiver安全:LocalBroadcastManager
私有Broadcast Receiver:android:exported="false"
公共Broadcast Receiver:android:exported="true"
內部Broadcast Receiver:android:exported="true" protectionLevel="signature"
Service安全:
私有Service:android:exported="false"
公共Service:android:exported="true"
合作Service:android:exported="true" GetSignature getPackageInfo //應用簽名
內部Service:android:exported="true" protectionLevel="signature"
Provider安全:
私有Content Provider:android:exported="false"
公共Content Provider:android:exported="true"
合作Content Provider:android:exported="true" GetSignature getPackageInfo //應用簽名
內部Content Provider:android:exported="true" protectionLevel="signature" GetSignature getPackageInfo //應用簽名
部分Content Provider:android:exported="false"
防止逆向:
代碼混淆:花指令
ProGuard:壓縮、優化和混淆代碼
DEX保護:
DEX優化與混淆:
dalvik-obfuscato
加殼與解殼:
APKProtect、android-unpacker
SO文件保護:
upx
防止jd-GUI查看代碼:
這個工具的bug
防止二次打包:
java層簽名驗證:
PackageInfo;->Signatures
底層簽名驗證:
/content/pm/Signature
防止動態分析:
調試程序:android_server、gdbserver
模擬器:Build.MODE="sdk"/"google_sdk"
系統安全:
啓動驗證:device-mapper-verity(dm-verity)
build/make/target/product/verity.mk PRODUCT_SUPPORTS_VERITY := true
SELinux:
對象管理器(Object Manager, OM)
訪問權限緩存(Access Vector Cache, AVC)
安全服務
安全策略
主體(Subject): 進程
目標(Object): 資源
MAC: 對訪問的控制強制化
TE:對於進程只賦予最小的權限
domain:遷移、防止權限升級
RBAC:對於用戶只賦予最小的權限
安全上下文:user、role、type、sensitivity
身份認證:user
角色:role
安全類型:type
安全等級:sensitivity
App進程:service_contexts
App數據文件: seapp_contexts
系統文件: file_contexts
系統屬性: property_contexts