引言
因為導師的方向有android安全的內容,給我看的論文大多也涉及android安全的內容,而我此前一點基礎也沒有,看的一臉懵
故隨便找書先上手再說
書籍詳細內容:android軟件安全權威指南
搭建環境
需求:分析APP
主要圍繞:android軟件開發,android軟件逆向,android源碼編譯
- 安裝JDK
- 安裝Android SDK(使用Android Studio已經包含,無需額外下載)
- 安裝Android NDK(同上)
- Android Studio集成開發環境,可以選擇下載CMake,LLDB
- Android模擬器
Cygwin或Bash on Ubantu on Windows(win10下linux子系統)
常用逆向分析工具
- ApkTool:APK的反編譯與回編譯功能
- smali/baksmali:DEX文件的反編譯與回編譯工具
- dex2jar:DEX文件轉換jar包
- 010Editor:跨平台二進制編輯器,提供二進制模版
搭建源碼分析環境
推薦Win10,使用Docker編譯系統源碼
如何分析Android程序
從開發學起,學習路線是線性的,循環漸進的,分析程序是開發的逆過程
從開發到最終分析並破解的完整路線:
編寫一個Android程序
創建
hint是EditText上的默認提示ems是將對應控件的寬度設為幾個字符的寬度,設置以后,一行最大只能顯示x個字符MessageDigestStringBuilder
編譯
1.命令行方式編譯
進入工程目錄,目錄下內容如下
Crackme0201.iml: Android Studio生成的項目配置文件local.properties: 本地配置文件,記錄了當前系統中安裝的Android SDK和Android NDK的路徑app: 項目目錄,程序代碼和資源setting.gradle: 指定包含的項目模塊的路徑build: 命令執行后輸出文件的存放目錄,第一次未編譯是還沒有的build.gradle: 項目的構建腳本gradlew: macOS和Linux系統使用的腳本編譯命令gradlew.bat: 與gradlew功能相同,用於Windows
gradlew是基於task來編譯項目的,執行gradlew task命令,列出所有支持的task
生成Debug調試版本的APK,在終端執行./gradlew assembleDebug命令,編譯后在app/build/outputs/apk
安裝Debug調試版本的APK,執行./gradlew installDebug命令,會自動安裝到連接的設備或模擬器上
2.Android Studio編譯
直接點運行,Android Studio會自動編譯APK,並安裝到設備上,如果只想編譯不想運行,點擊Build -> Make Project來編譯當前工程。
破解一個Android程序
破解入手
通常方法:使用ApkTool反編譯APK文件,生成smali格式的反編譯代碼。通過閱讀smali文件的代碼來理解程序的運行機制,找到突破口,並對代碼進行修改。使用ApkTool重新編譯生成APK文件並對其進行簽名,運行測試。
如此循環,直到全部破解。
在實際分析中,還可以使用IDA Pro直接分析APK文件,使用dex2jar與jd-gui配合進行Java源碼級的分析等。
反編譯
安裝Apktool工具,對APK文件進行反編譯
apktool d ./app-debug.apk -o outdir
對當前目錄下的debug.apk進行反編譯,文件生成在outdir目錄下
反編譯包含一系列目錄和文件,smali目錄下存放了程序的所有反編譯代碼,res中是所有資源文件,這些目錄的子目錄和文件的組織結構與開發一致。
分析
突破口:錯誤提示信息
錯誤提示代碼附近通常是程序的核心驗證代碼。
錯誤提示屬於Android資源中的字符串資源,可能會被硬編碼到源碼中,也可能在res/value/string.xml中
對smali文件進行分析
checkSN()被調用,進行注冊碼合法性檢查
move-result v0
if-nez v0, :cond_0
第一行將返回結果保存在v0寄存器,第二行對v0寄存器進行判斷,如果其值不為0,即條件為真,跳轉到cond_0標號處,反之程序繼續執行
如果代碼不跳轉,則繼續執行
.line 34
iget-object v0, p0, Lorg/nuaa/crackme0201/MainActivity$1;->this$0:Lorg/nuaa/crackme0201/MainActivity;
const v1, 0x7f06002c
invoke-static {v0, v1, v3}, Landroid/widget/Toast;->makeText(Landroid/content/Context;II)Landroid/widget/Toast;
move-result-object v0
.line 35
invoke-virtual {v1}, Landroid/widget/Toast;->show()V
goto :goto_0
使用iget-object指令獲取MainActivity實例的引用,其中,->this$0是內部類MainActivity$1中的一個synthetic字段,存儲對父類MainActivity的引用。
const v1, 0x7f06002c指令將v1寄存器傳入unsuccess字符串的id,調用Toast;->makeText()創建字符串,在line35show出來
修改smali
關鍵在if-nez v0, :cond_0
類似的跳轉指令有if-nez, if-eqz, if-gez, if-lez等
與if-nez相反的是if-eqz,等於0時跳轉
重新編譯
修改代碼后,重新編譯,打包成APK文件
apktool b outdir_rel
此時編譯生成的APK文件是沒有簽名的,不能進行安裝和測試,需要對APK進行簽名
我沒照書上的做,用的是360簽名工具,鏈接在這里
簽名的key用的是之前新建的
安裝測試
啟動Android模擬器,或者使用設備,在終端直接執行命令先卸載原來版本,再安裝破解后的版本
$adb uninstall com.droider.crackme0201
Success
$adb install signed.apk
Success
再啟動測試,發現已經破解了
小結
破解的流程:
反編譯 -> 分析 -> 修改 -> 回編譯 -> 簽名
如果覺得繁瑣可以采用集成工具
macOS: Android-Crack-Tool, Windows: Android Killer
