JNI_OnLoad函數大概功能就是在程序加載so的時候,會執行JNI_OnLoad函數,做一系列的准備工作。
很多時候,程序猿們會將一些重要信息放在此函數中,而不是通過某種事件來重復觸發。包括說將反調試函數放置在此函數中。因此,調試手段發生了改變,上述調試方法基本上被淘汰。
1.靜態分析,找到JNI_OnLoad函數的偏移

2.執行android_server

3.端口轉發

4. 以調試模式啟動程序
adb shell am start -D -n com.example.mytestcm/.MainActivity
此時,手機界面會出現Waiting For Debugger頁面


5.打開ddms或者Eclipse (必要,為了使用jdb命令),獲取應用程序的端口號

6.IDA附加


7.設置調試選項


8. F9運行程序

在命令行中執行:jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8700其中port=8700是從ddms中看到的。

此時程序會斷下來

9.下斷點,首地址加偏移,跟上一篇遠程調試的方法一樣


下好斷點之后,直接F9運行吧,就能斷在JNI_OnLoad函數處~

當這種調試手法出現之后,將特殊函數,或者反調試函數放在JNI_OnLoad中也不是那么的安全了。此時,程序猿們通過分析系統對SO文件的加載鏈接過程發現,JNI_OnLoad函數並不是最開始執行的。在JNI_OnLoad函數執行之前,還會執行init段和init_array中的一系列函數。
因此,現在的調試方法,都是將斷點下在init_array中~
至於下斷點的方法,可以類比於在JNI_OnLoad中下斷點的方法,在init_array的函數中下斷點。還有一種方法便是通過在linker模塊中,通過對其中函數下斷點,然后也能單步到init_array中
