【Android 原創(chuàng)】實(shí)戰(zhàn)分析一個(gè)Crackme的過程(超級(jí)詳細(xì))
[超級(jí)詳細(xì)]實(shí)戰(zhàn)分析一個(gè)Crackme的過程
一、寫在前面
自學(xué)這個(gè)也有幾個(gè)星期了,今天就總結(jié)一下近期學(xué)習(xí)的成果,實(shí)戰(zhàn)分析一個(gè)Crackme,并寫下了這篇超級(jí)詳細(xì)的過程,從軟件環(huán)境的配置到軟件詳細(xì)的使用再到最后的逆向分析出結(jié)果,為了文章的貼圖方便和文章美觀展示,用了兩臺(tái)電腦+MUMU模擬器+Google6.0.1版真機(jī),相互切換著截圖附在帖子里,也主要是因?yàn)槟M器動(dòng)態(tài)調(diào)試so加載好像有問題。我是新入門的小白一個(gè),如果文章中出現(xiàn)錯(cuò)誤,希望大佬們能及時(shí)斧正,以免對(duì)其他萌新產(chǎn)生誤導(dǎo)。(此文章只發(fā)布在吾愛和看雪)
二、所用工具
IDA?Pro V7.0版
、jadx 1.2版
、Android Kill 1.3.1版
、Google真機(jī) 6.0.1版
?、MUMU模擬器 2.4.2版
三、jadx分析AliCrackme
先使用MUMU模擬器打開軟件隨便輸入密碼,提示?驗(yàn)證碼校驗(yàn)失敗

將軟件拖入jadx去分析一下軟件代碼的執(zhí)行流程,直接使用軟件的搜索功能,發(fā)現(xiàn)只有一條數(shù)據(jù)并進(jìn)去看一下。

分析一下軟件中代碼執(zhí)行密碼校驗(yàn)的流程,試圖分析出軟件的真實(shí)的密碼

經(jīng)過上圖的一些分析步驟之后,我發(fā)現(xiàn)軟件的真實(shí)的密碼在crackne.so里面,接下來使用jadx的全部保存(ctrl+s) 并選擇保存的位置將so文件提取出來,如下圖:

四、IDA靜態(tài)/動(dòng)態(tài)/反反/再動(dòng)態(tài)調(diào)試
1.靜態(tài)分析
接著打開 IDA 點(diǎn)擊 NEW 打開libcrackme.so文件,中途出現(xiàn)彈窗一致?ok?即可!

直接看到了這里,這個(gè)與上面反編譯分析的方法名一致,只是前面加入了一些軟件包的特征,如下圖:

匯編不是太方便看,直接使用左邊的功能將其轉(zhuǎn)換為 偽C代碼 或 直接使用快捷鍵 F5

轉(zhuǎn)換為 偽C代碼之后,分析一下代碼的執(zhí)行,點(diǎn)擊 v3 通過JNIEnv* 還原類似((_DWORD?)v3 + 676))格式的指令,重命名以及注釋的方式記錄分析,如下圖:

下面詳細(xì)的分析一下代碼的邏輯,判斷出用戶輸入的密碼和軟件真實(shí)的密碼,如下圖所示:

下面使用Rename lvar或快捷鍵 N 的方式直接將分析出來的 直接重命名一下,方便以后容易查看,最終如下圖:

2.動(dòng)態(tài)調(diào)試
接下來就是通過動(dòng)態(tài)調(diào)試 分析這個(gè)so文件的密碼了,在動(dòng)態(tài)調(diào)試之前我需要配置一些環(huán)境,步驟如下:

連接MUMU模擬器:adb connect 127.0.0.1:7555? ?? ?? ? //7555為mumu模擬器端口,其它模擬器百度一下
將文件push 進(jìn)手機(jī)的指定目錄下:adb push android_x86_server /data/local/tmp/
進(jìn)入手機(jī)端命令:adb shell
切換獲取手機(jī)的root權(quán)限:su
查找push的文件是否在手機(jī)中:cd /data/local/tmp/
查看路徑下的文件以及權(quán)限:ls -l
擁有root權(quán)限更改文件的權(quán)限為777:chmod 777 android_x86_server
在手機(jī)中啟動(dòng)運(yùn)行該文件:?./android_x86_server
windows運(yùn)行 端口轉(zhuǎn)發(fā)到PC:adb forward tcp:23946 tcp:23946

再開啟一個(gè) 命令行 做一下端口的轉(zhuǎn)發(fā),如下圖所示:

全部執(zhí)行完畢之后,可以看到正在監(jiān)聽這個(gè)端口,這時(shí)候我們打開 IDA 并且點(diǎn)擊GO??然后按照下圖選擇所使用的

并輸入 127.0.0.1 后面的端口是默認(rèn)的,上面的命令也在監(jiān)聽這個(gè)端口。

找到要?jiǎng)討B(tài)調(diào)試的軟件的包名,直接選中,點(diǎn)擊 ok 打開即可!

打開之后,直接使用下圖的方式,或者 快捷鍵 Ctrl+s 找到到要調(diào)試的libcrackme.so文件 帶x權(quán)限的文件。

在所有的so文件中直接使用快捷鍵Ctrl+f 搜索,并找到 Start地址先執(zhí)行且有 X(可執(zhí)行權(quán)限) 的 選中點(diǎn)擊OK進(jìn)入,
模擬器的是下圖顯示的so:

這里使用模擬器的話,so文件加載會(huì)有一些問題,在這里我改用了Google真機(jī)6.0.1版本進(jìn)行動(dòng)態(tài)調(diào)試!
真機(jī)的是下圖顯示的so:

打開so文件之后我們要定位到要調(diào)試函數(shù)的一個(gè)內(nèi)存的絕對(duì)地址=so文件的基地址+函數(shù)的偏移量

經(jīng)計(jì)算可知,函數(shù)的絕對(duì)地址就是F49591A8在IDA中 使用快捷鍵G跳轉(zhuǎn)到地址的位置,也就是要調(diào)試的函數(shù)位置

找到函數(shù)名之后,鼠標(biāo)右鍵 選擇 Add breakpoint 或者 直接使用快捷鍵F2打斷點(diǎn),然后讓程序恢復(fù)執(zhí)行,使用快捷鍵F8往下走。

點(diǎn)擊 F8 給so文件的函數(shù)打斷點(diǎn)調(diào)試,直接就退出或出現(xiàn)錯(cuò)誤彈窗等等!如下圖所示:

證明軟件有反調(diào)試的機(jī)制,先看一下軟件是通過何種方式反調(diào)試的,又是如何檢測(cè)被調(diào)試的呢?
檢測(cè)是否被調(diào)試:利用Linux系統(tǒng) ptrace 來實(shí)現(xiàn),當(dāng)應(yīng)用被調(diào)試時(shí)應(yīng)用內(nèi)存里的TracerPid字段就不為0,只要是不為0的時(shí)候,就會(huì)直接的退出程序,達(dá)到反調(diào)試的目的。
接下來進(jìn)入設(shè)備查看一下ptrace字段:
進(jìn)入設(shè)備:?adb shell
獲取Root權(quán)限:su
獲得APP的進(jìn)程ID:ps | grep 軟件的包名
查看進(jìn)程的信息及TracerPid值:?cat??/proc/進(jìn)程ID/status

知道了軟件有反調(diào)試之后,接下來就需要對(duì)其反反調(diào)試了。
3.反反調(diào)試
下面為方便發(fā)帖截圖說明,我又換回了模擬器來做調(diào)試(模擬器可以調(diào)就用模擬器,不能調(diào)的當(dāng)然就要換真機(jī)啦)
如何反反調(diào)試:程序的so文件在加載階段會(huì)先執(zhí)行JNI_OnLoad,之后就不再執(zhí)行,在程序的so文件加載階段才能給JNI_OnLoad打斷點(diǎn)調(diào)試即可!
//調(diào)試APP掛在加載界面
adb shell am start -D -n 包名/.類名
adb shell am start -D -n com.yaotong.crackme/.MainActivity
用調(diào)試模式啟動(dòng)APP,APP此時(shí)會(huì)掛在啟動(dòng)界面,現(xiàn)在并沒有開始加載so文件。

重新關(guān)閉打開 IDA 并調(diào)試上面掛載的程序,進(jìn)入之后點(diǎn)擊Debugger->Debugger options... 選項(xiàng)如下圖:

勾選這兩項(xiàng)Suspend on thread start/exit? ?? ?Suspend on library load/unload,之后ok,之后點(diǎn)擊下圖左上角的運(yùn)行符號(hào),然后讓它運(yùn)行起來。

然后讓模擬器的APP也運(yùn)行起來,用過下面的這些命令運(yùn)行APP,即可
進(jìn)入設(shè)備:?adb shell
獲取Root權(quán)限:su
獲得APP的進(jìn)程ID:ps | grep com.yaotong.crackme
監(jiān)聽進(jìn)程的ID:adb forward tcp:8700 jdwp:4495(4495為上面獲得的APP進(jìn)程ID)
運(yùn)行進(jìn)程:jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8700
獲取APP的進(jìn)程的ID以及再開啟一個(gè)命令行,直接做端口的監(jiān)聽轉(zhuǎn)發(fā),并直接的運(yùn)行進(jìn)程,如下圖:

注意:卡在運(yùn)行進(jìn)程這一步的不出現(xiàn)上圖的正在初始化jdb...,應(yīng)該是你漏掉了一個(gè)步驟,我就是因?yàn)榻貓D過之后忘記了在IDA 動(dòng)態(tài)調(diào)試的時(shí)候,忘記點(diǎn)擊了一下IDA左上角的運(yùn)行符號(hào),而導(dǎo)致的一致不出來正在初始化jdb...的情況,出現(xiàn)初始化后,APP處于這個(gè)沒有控件的界面,此時(shí)的APP并沒有完全的運(yùn)行起來,只是掛在這里

然后我們回到 IDA 的動(dòng)態(tài)調(diào)試 找到要調(diào)試的crackme.so 文件,按Ctrl+s 之后按Ctrl+f搜索crackme,如果沒有就點(diǎn)擊左上角的運(yùn)行?運(yùn)行一步繼續(xù)操作,直到可以在所有的so文件中搜索到crackme.so文件,并且找到可執(zhí)行的X權(quán)限的文件。(這里模擬器又出現(xiàn)了沒有X可執(zhí)行的情況,直接換Google6.0.1真機(jī))模擬器調(diào)試如下圖所示:

真機(jī)動(dòng)態(tài)調(diào)試前一定要修改APP AndroidMenifest.xml文件, 在<application 里給APP加上可調(diào)試權(quán)限,android:debuggable="true",重新打包APP,簽名,安裝,如下圖所示:

接下來點(diǎn)擊 IDA 左上角的運(yùn)行,按照上面說的,知道找到 crackme.so 中有X(可執(zhí)行的),進(jìn)入,如下圖:

然后我們要進(jìn)入 JNI_ONLoad ,接下來算絕對(duì)地址=執(zhí)行so文件的基地址+函數(shù)的偏移量?最終如下圖所示:

最終的計(jì)算結(jié)果如下圖所示:

跳轉(zhuǎn)到 JNI_ONLoad 里面去了,先結(jié)合靜態(tài)分析看一下這個(gè)文件流程圖的大致邏輯,然后在動(dòng)態(tài)調(diào)試?yán)锎驍帱c(diǎn)調(diào)試,并點(diǎn)擊IDA左上角的運(yùn)行,恢復(fù)程序的運(yùn)行如下圖所示:

BLX R7的位置跳了出去,很可疑的位置需要重點(diǎn)注意,嘗試修補(bǔ)so文件的這個(gè)位置,看一下,如下圖所示:

然后IDA 靜態(tài)調(diào)試分析 找到上面的BLX R7位置,點(diǎn)擊一下,可以看Hex View-1視圖中的3F FF 2F E1

把?3F FF 2F E1?修改為?00 00 00 00?即可,下面直接使用兩種方式修改這個(gè):
第一種:


第二種:

修改完畢之后,找到這個(gè)文件所在的位置,與之前Android kill反編譯之后的里面的so文件做替換,然后就回編譯簽名安裝即可


修改了關(guān)于程序反調(diào)試的TracerPid 指令37 FF 2F E1 改為 00 00 00 00 然后對(duì)軟件重新回編譯打包安裝后,就可以繼續(xù)動(dòng)態(tài)調(diào)試軟件的真實(shí)密碼了,不會(huì)再有反調(diào)試的防護(hù)機(jī)制了,接下來就是再次動(dòng)態(tài)調(diào)試。
4.再動(dòng)態(tài)調(diào)試
有了上一次的經(jīng)驗(yàn)這次直接使用 Google6.0.1版本真機(jī),很快的通過上面的方式,找到了要調(diào)試的函數(shù)所在的位置,如下圖所示

打斷點(diǎn)后讓程序恢復(fù)執(zhí)行,真機(jī)上輸入密碼(yimingrj)并存到寄存器,一直F8找到有跳轉(zhuǎn)的地方,鼠標(biāo)查看寄存器的值:

之后我們看一下R3的值,直接使用快捷鍵F5看一下偽C代碼,又根據(jù)之前的靜態(tài)調(diào)試分析可知v6就是真實(shí)密碼,最后分析出了這個(gè)軟件真實(shí)的進(jìn)入密碼為:aiyou,bucuoo(哎呦,不錯(cuò)哦)!

輸入密碼經(jīng)過模擬器上程序驗(yàn)證后,進(jìn)入軟件成功!這個(gè)軟件的密碼分析到這里這部分就結(jié)束了。

五、最后總結(jié)
因?yàn)槟M器動(dòng)態(tài)調(diào)試so加載好像有問題,又因?yàn)槲恼碌馁N圖需要,所以用了兩臺(tái)電腦+MUMU模擬器+Google6.0.1版真機(jī),模擬器對(duì)動(dòng)態(tài)調(diào)試so文件支持的好像不是很好。
(不斷學(xué)習(xí)+總結(jié)積累=持續(xù)性進(jìn)步)
總結(jié)一條經(jīng)驗(yàn):以后再動(dòng)態(tài)調(diào)試就可以直接使用真機(jī)了。
這篇詳細(xì)的實(shí)戰(zhàn)分析文章:
文章對(duì)我而言:是一次詳細(xì)的總結(jié),也可以當(dāng)做以后自己再調(diào)試軟件的一個(gè)經(jīng)驗(yàn)貼和排錯(cuò)貼;
文章對(duì)你而言:是對(duì)逆向比較感興趣的同學(xué)的一個(gè)入門介紹,希望可以幫助到你。
論壇原文地址:https://www.52pojie.cn/thread-1315444-1-1.html