Fn+f5轉成c語言偽代碼
shift+f12 查看文件中所有常量字符串的值
ctrl+s查看so文件字段信息
JNI函數方法名還原 選中v3 按y建 作用(類型還原)
v3 + 676 前面是一個指針 比如 *(_DWORD *)v3 + 676 表示 v3 是JNIEnv *類型
形如 *(_DWORD *)vX + YYY 皆是
可選中v3 按y鍵進行類型替換,替換為JNIEnv *
為偽代碼添加注釋 : /
g跳轉到指定地址
IDA動態調試
目的:找到自毀程序的內置密碼
IDA下載配置 mac需要在10.15以下版本才可以使用
首先,需要准備安卓真機,最好是pxiel 6.0的系統,
將ida文件夾里面的dbgsrv下的android_server放入真機的/data/local/tmp/下 添加777權限 chmod 777 xxx
./android_server運行服務並且監聽端口23946 adb forward tcp:23946 tcp:23946
后面再運行ida 32 點go打開ida new是靜態調試
我們選擇 debugger-->attach -remote ARMLinux/Android debugger
輸入127.0.0.1點ok。會出來如下界面,如果說鏈接拒絕,請檢查前面啟動服務和監聽端口是否正常
我們找到需要調試的進程com.yaotong.crackme點ok
稍等一會兒之后會出來如下界面
由於我們之前說過,這個函數的驗證密碼的函數叫securityCheck
我們現在需要跳到這個函數的內存地址,去調試這個函數,如何找到這個函數的內存地址呢
函數運行實際內存地址=頭so文件的基地址(根據實際運行情況,此基基地值app每次執行的值都不一樣) + 該函數的偏移量(固定不變.so文件可查看)
我們現在另外打開一個ida 以靜態方法打開此apk的libcrackme.so文件找到securityCheck函數的偏移量為11A8
再打開以動態方法調試的ida 按control+s(顯示app中的so文件)
我們找到libcrackme.so 找到第一個標有x權限的so文件
打開
顯示的內存地址為F4395000
我們打開電腦上的科學計算器,計算方法以16進制進行計算
用F4395000+11A8得到的就是實際的securityCheck運行的的內存地址 F43961A8
我們在動態的ida里面按下G 輸入剛才得到的內存地址,跳到此內存地址
跳轉后的界面如下
現在我們對此函數進行調試,我們需要在Java_com_yaotong_crackme_MainActivity_securityCheck函數這里進行打斷點調試,右鍵addbreakpoint
斷點后的樣子
然后我們點左上角點綠色三角形運行按鈕,讓程序繼續運行
我們再在手機里隨便輸入個密碼比如1111,點擊輸入密碼,讓程序進入下一步
(打上斷點以后,程序需要點運行按鈕才能繼續運行,此時我們才能輸入密碼,不然程序會一直卡在那里,動不了)
調試有兩個快捷鍵,F7 和F8
F7單步調試,要進入函數
F8單步調試,不進入函數
一般都是F8。進入函數步驟太多了。看不出來。我們F8嘗試調試
發現報錯,沒關系 我們再次嘗試
再次報錯,一直都報錯,此時 我們想到,可能是此app用了反調試
IDA調試原理 是利用Linux系統 ptrace 來實現
當應用被調試時,應用內存里的TracerPid 字段就不為0
進入設備查看ptrace字段:
//進入設備
adb shell
//獲得APP的進程ID
ps | grep 包名
//打印該APP里內存狀態信息
cat /proc/pid(進程ID)/status
TracerPid為 0代表 沒有被調試,不為0代表在被調試。
反調試的原理,檢測TracerPid是否被占用,如果被調用。阻止app繼續運行
反反調試
動態調試,找到檢測TracerPid的代碼,不執行此代碼
方法:
此檢查代碼一般在.init_arra 和 JNI_OnLoad兩處。此函數都是在程序最開始運行的時候執行
在JNI_OnLoad函數出打斷點調試,找到檢測TracerPid的代碼,修改so文件的執行函數,不執行此代碼
IDA調試反調試小經驗 如何找到反調試代碼:
結合IDA靜態時的代碼,觀察程序邏輯
指令一般會整過執行完,直到函數末尾。
so文件在加載階段會執行JNI_ONLoad函數。此后便不再執行。要在so文件加載階段才能給JNI_ONLoad打斷點。
分下面幾個步驟:
1.修改APP的AndroidManifest.xml文件的application字段,再后面加上一段代碼android:debuggable=''ture".然后重新打包簽名安裝
2.運行的時候檢查是否允許debuggable項
adb shell dumpsys package com.yaotong.crackme(一定要有debuggable 沒有的話會導致后面附加進程出現致命錯誤,無法附加的VM)
3.以調試模式啟動APP,APP此時會掛住
adb shell am start -D -n 包名/.類名
adb shell am start -D -n com.yaotong.crackme/.MainActivity(MainActivity是application 下的第一個activity.此activity為初始啟動界面)
掛起 的程序就像上圖這樣。一直等待調試,
4.我們打開ida動態調試,對此app再次進行調試
打開好找到 Debugger-->Debugger options 勾選下圖紅色選框內容
再點擊一下左上角對運行按鈕
5.再進入設備查看進程對PId ps |grep 包名 或者frida-ps -Ua也可以
6.使JDB命令使程序恢復運行
adb forward tcp:8700 jdwp:18776(APP的PID)
jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8700
7.so文件在被加載時。ida會停住此文件對加載,我們用control+s來一步步查看libcrackme.so文件是否被加載。並且加載對so文件需要有x權限
如果未加載。我們再點擊左上角對運行按鈕,來一步步對嘗試,如此反復,直到出現帶有x權限對libcrackme.so文件
點進去,我們得到libcrackme.so文件本次運行的基地址,我們現在需要跳轉到JNIONLOAD函數里 對此函數進行調試 G ,然后和JNI_onload內存值相加
得到這樣的圖
現在我們對JNI_onload進行打斷點 點左上角的運行三角形,讓程序進行運行。F8進行調試
(對JNI_inload進行調試是找出此段代碼中檢測tracepid的代碼,對檢測tracepid的代碼進行定位,找到 pthread_create() 的位置。后修改so文件的十六進制內容,從而讓此段代碼不執行)
每一步的F8調試,我們都一一都找,鼠標放上去,看到里面運行的代碼,找尋 pthread_create這個函數,由於這個函數是一直不停的去檢測,應該是個while循環,我們可以按照里面的箭頭,線路圖,是否有往回走的,來判斷pthread_create大致在哪里
如圖 ,找到了 位置在BLX R7位置。現在我們到靜態so文件里面 JNI_ONload函數里找到blx r7的執行命令
鼠標點在blx R7 在點hexview1 陰影的地方就是該函數的運行指令的16進制
我們現在把37 FF 2E E1復制一下,用文本方式打開so文件,在里面搜索37 FF 2E E1 將搜到的37 FF 2E E1全部改為 00 00 00 00,
讓指令變為空指令
改完以后報錯,再重新打包,簽名 安裝
安裝完成后,我們就可以重新對securityCheck進行動態調試了
繼續接之前的
(
然后我們點左上角點綠色三角形運行按鈕,讓程序繼續運行
我們再在手機里隨便輸入個密碼比如1111,點擊輸入密碼,讓程序進入下一步
(打上斷點以后,程序需要點運行按鈕才能繼續運行,此時我們才能輸入密碼,不然程序會一直卡在那里,動不了)
)
現在繼續調試就不會報錯了
我們一步步的F8向下走。看看程序執行,(在此之前在app上隨便輸入個密碼)
我們試想這個密碼肯定是錯的。程序會判斷密碼是對是錯,如果錯了,肯定會走錯的流程,對了肯定走對的流程,我們一步步的F8,發現
發現紅紅色圈子的箭頭一直閃,正常應該走短的哪個箭頭,結果卻繞過短的執行了長的,我們把鼠標放在R0上
發現寄存器里面的值正好是我們輸入的1111 由此可判斷這部分函數應該是判斷密碼和輸入的是否正卻,我們F5轉化為偽代碼進行查看
仔細看這段代碼 判斷v7不等於v5 break ,v7是v6賦值的。我們把鼠標放在v6上。發現v6的值為aiyou,bucuoo 前面的unsigned __int8可以上網上查下含義,大致的意識是定義類型,
我們把得到的密碼輸入進入嘗試,發現密碼正確,完成
學自猿人學