1. 程式人生 > 其它 >教我兄弟學Android逆向10 靜態分析反除錯apk

教我兄弟學Android逆向10 靜態分析反除錯apk

上一篇 《教我兄弟學Android逆向09 IDA動態破解登陸驗證》我帶你分析了黑寶寶.apk,並且用IDA動態除錯破解了登陸驗證 看上節課你學習的不錯 這節課給你帶來的是過反除錯的教程

在進入本節課之前我先問你一個問題
什麼是反除錯?
答:反除錯技術是為了保護自己程式的程式碼不被逆向。增加逆向分析的難度 防止程式被破解, 針對動態分析。
要麼學!要麼不學!學和不學之間沒有中間值 不學就放棄,學就要去認真的學! --致選擇


分析環境:JEB2.2.7+IDA7.0測試手機:nexus
IDA7.0下載連結
連結:https://pan.baidu.com/s/1xEtjnTVZFuLiMpHKwMOY2Q密碼:g3v9

前言
測試一:首先拿到反除錯挑戰.apk 安裝後直接執行,這裡因為我沒有動態除錯程式,所以彈出框恭喜你,挑戰成功!
測試二:用第9課講的除錯方法 先執行程式等程式彈框後再掛起IDA除錯 發現IDA直接退出 猜測程式做了反除錯。

一 用jeb反編譯反除錯挑戰.apk
1開啟Manifest檢視android:debuggable="true" 說明此程式是可以被動態除錯的。
2找到程式入口MainActivity 分析可知程式執行的時候呼叫了myJNI類中的Native函式checkport並彈框 所以checkport是彈框的內容 看函式名可知裡面也有可能做了反除錯
3分析程式碼可知程式彈框後說明checkport函式已經執行完了,但是IDA掛起來後程序還是退出,說明還是被反除錯了 猜想有兩種情況:
猜想一: checkport函式中開啟了一個執行緒迴圈來做反除錯 就算函式執行完 這個執行緒中的反除錯還是執行的 (如果不開啟執行緒 迴圈檢測反除錯程式主執行緒將會堵塞 )
猜想二: 我們知道init_array和JNI_OnLoad會在so載入的時候就開始執行,所以程式也有可能會在這裡開啟執行緒進行反除錯。


<ignore_js_op>
<ignore_js_op>
<ignore_js_op>
4.帶著上面的猜想 我們下面來分析下so


二 驗證猜想一
IDA分析so
解壓反除錯挑戰.apk進入lib資料夾下找到libsix.so並用ida開啟由於我手機支援v7所以這裡我開啟的是armeabi-v7a下的so
注意:這裡一定要開啟手機對應的so 如果手機是arm的就開啟armeabi資料夾下的so,支援v7則開啟armeabi-v7a下的so 同理x86的要開啟x86資料夾下的so進行分析這裡很重要 不然會和動態除錯的記憶體地址不對應
1.我們先來找到 checkport函式 看看程式碼裡面到底有什麼 按照以前教程中找Native函式的方法 我們開啟函式匯出表發現並沒有checkport函式 在String視窗搜尋恭喜你,挑戰成功!也是搜尋不到的說明此字串被隱藏了但是發現了JNI_OnLoad函式 說明函式checkport是動態註冊的。
<ignore_js_op>

2. 怎麼在IDA裡面找到動態註冊的函式呢?動態註冊的函式一般會在.data.rel.ro.local或data中 Ctrl+s開啟segment表找到.data.rel.ro.local這個段裡面放的是動態註冊的函式 點進去後就找到Checkport函數了 函式的定義在dword_1140中
<ignore_js_op>


<ignore_js_op>



3點進dword_1140發現這部分程式碼IDA沒有解析好這裡需要手動解析一下 點住dword_1140右鍵Data轉化成資料 然後滑鼠放在__unwind按住P鍵就轉換成函數了 這個函式就是checkport對應的函式


<ignore_js_op>


<ignore_js_op>
<ignore_js_op>
<ignore_js_op>

4.分析checkport函式 F5轉換成C虛擬碼 匯入Jni.h (不會匯入的看前面的課程) 然後手動解析程式碼 提高程式碼可讀性 解析完成後Esc返回到C程式碼 再按下F5重新整理一下程式碼 解析的字串就出來了
<ignore_js_op>
<ignore_js_op>
<ignore_js_op>

5 通過以上操作可以看到 恭喜你,挑戰成功字串已經被我們解析出來了 接下來分析這個函式 這個函式會 讀取/proc/net/tcp,查詢23946埠,也就是IDA動態除錯的埠 如果查詢到了說明程式正在被動態除錯 然後退出程式 從而達到了反除錯的目的。
但是這裡我們看到這個函式的反除錯並沒有放到執行緒中做 說明只執行一次就結束了而且測試一驗證的時候這裡的程式碼已經執行完了所以其他地方一定還有反除錯 並且只能在這個函式之前執行。
<ignore_js_op>

三 驗證猜想二
init_array介紹
init_array段是在so載入的時候執行的 執行順序要優先於 JNI_OnLoad所以這裡是最早被執行的函式 把反除錯和so的解密放到這裡是比較好的選擇。

1 ctrl+s開啟segment表找到.init_array段點進去 發現init_array段裡面有一個thread_create函式 點進去F5轉換成C虛擬碼 並分析函式
<ignore_js_op>
<ignore_js_op>
<ignore_js_op>
<ignore_js_op>
<ignore_js_op>

2.我們開啟命令列視窗來驗證一下 檢視當前程式的status檔案ps命令用來列出系統中當前執行的那些程序
<ignore_js_op>
<ignore_js_op>
<ignore_js_op>

3.通過上面分析可知thread_create函式是建立執行緒迴圈讀取當前程式的Tracepid的值 如果值大於0說明程式當前正在被動態除錯並退出程式 那麼現在就知道為什麼在程式彈出恭喜你,挑戰成功框後我們進行動態除錯 程式還是會退出了 因為這裡開啟了一個執行緒進行迴圈反除錯。
4.那麼到這裡程式的反除錯是不是就找完了呢?剛剛我們也說了除了init_array還有一個地方JNI_OnLoad函式也會在so剛載入的時候執行 那麼出於習慣 我們還是來看一下JNI_OnLoad函式

四 JNI_OnLoad函式
1.在函式視窗中搜索並找到JNI_OnLoad函式 F5反編譯成C虛擬碼(有點時候匯出表裡面是沒有JNI_OnLoad函式的 所以這裡在函式視窗中搜索)
<ignore_js_op>
<ignore_js_op>
<ignore_js_op>
<ignore_js_op>
<ignore_js_op>


2.經過上面分析知道 JNI_OnLoad函式中呼叫SearchObjProcess函式進行反除錯這個函式通過ps列出當前手機的所有程序 然後如果程序名中包含android_server,gdbserver,gdb等名稱 則認為程式當前被動態除錯 退出程式

五 小結
1.首先我們通過JEB工具靜態分析了反除錯挑戰.apk 發現在MainActivity類中呼叫了Native函式checkprot 因為這個函式是動態註冊的 所以我們在data.rel.ro.local段中找到了這個函式 分析知道這個函式會讀取/proc/net/tcp,查詢23946埠 如果找到則認為程式當前被動態除錯 退出程式
2 在init_array段裡面發現了thread_create函式 這個函式建立了一個執行緒迴圈來讀取/proc/pid/status檔案下的TracePid的值 如果大於0說明程式正在被除錯 退出程式
3.JNI_OnLoad函式中發現了SearchObjProcess函式通過搜尋指定程序名來判斷程式有沒有被除錯

六 解決方案一
1.對於checkprot我們可以通過-p將IDA除錯埠改為23947或者其他埠 注意埠轉發和IDA除錯的埠號都要改成23947
<ignore_js_op>
<ignore_js_op>

<ignore_js_op>

2.對於thread_create函式我們可以刷機改核心讓TracePid的值永遠為0
參考文章《逆向修改核心,繞過TracerPID反除錯
3.對抗SearchObjProcess函式可以將android_server改成其他名字然後執行 比如zs ls ww(張三,李四,王5)
參考文章《教我兄弟學Android逆向番外03 Android逆向必會命令

七 解決方案二
1.也可以通過exit函式定位到反除錯位置並patch掉當前函式 這裡以thread_create函式為例子 因為此函式在init_array段裡面 所以是沒有呼叫的地方的 這裡直接把第二條指令改成pop直接出棧 改Hex指令這裡我就不為你演示了 前面教程都有教過。
<ignore_js_op>
<ignore_js_op>
<ignore_js_op>
<ignore_js_op>
<ignore_js_op>
<ignore_js_op>


2.對於SearchObjProcess函式 直接找到呼叫此函式的位置 然後nop掉 或者進函式裡面把exit給nop掉都行最後一處反除錯這裡也不演示了 方法相同
<ignore_js_op>

八 另一種patch方法
以前我們都是用IDA外掛modifyfile.plw來patch 其實還有一種patch的方法 直接用IDA Patch Program外掛來Patch也是可以的 點選單Edit->Patch Progra
<ignore_js_op>
<ignore_js_op>
<ignore_js_op>
<ignore_js_op>

最後將patch後的so替換原包的so 重打包簽名 執行 即可過反除錯。

九總結
本節課我帶你用JEB+IDA工具靜態分析了反除錯APK 通過本節課的學習 你瞭解了init_array段和JNI_OnLoad函式的執行順序和這三處反除錯的找尋方法對於反除錯 當然也可以通過搜尋特徵的方式定位位置 比如TracePid反除錯可以在字串視窗搜尋/proc/%d/status 檢測程序名可以搜尋android_server檢測埠號搜尋5D8A 然後我又帶你重溫了一遍函式Patch的方法 以及第二種儲存修改so的方法 通過本節課我想你對反除錯技術已經有了初步的瞭解 教程附件裡面前人總結出來的反除錯大全 你可以看一看並且學習一下。學習完之後 下節課我將會為你講解怎麼動態除錯這個apk。

十 課後作業
1.按照本節課教程把附件裡面的反除錯.apk so裡面的反除錯函式給patch掉 並重打包
2.瞭解並熟悉附件裡面常見的反除錯



下一篇:《教我兄弟學Android逆向11 動態除錯init_array

學習時的痛苦是暫時的 未學到的痛苦是終生的