1. 程式人生 > >使用IDA除錯Android原生程式

使用IDA除錯Android原生程式

     今天已是國慶的第五天,白天去武館訓練過後,晚上回來品一杯西湖龍井,更一篇部落格,一來幫助需要之人,二來加深自己的理解。

下面就說關於在IDA中Android so的動態除錯的問題以及在so的三個層次下斷點的操作。

問題篇:

1.動態除錯的作用以及與我們常說的脫殼區別之處?

2.IDA的下斷點除錯的原理?

3.有無反除錯的步驟區別?以及原理?

4.反除錯與反附加的區別?

5.IDA動態除錯so時有哪三個層次?以及如何下斷點?

注意:so的動態除錯與脫殼在步驟上有很多的相似之處,關於脫殼在後面會詳細介紹加殼以及脫殼的發展歷程。

解答原理篇:

第一個問題

曰:動態除錯作用有二:

其一:dump記憶體,即:找準時機dump出解密後的正確檔案;

其二:檢視每一步狀態,進一步分析出正確的邏輯;

脫殼只是我們在除錯系統級別的.so檔案後,找準時機dump出正確而真實的.so檔案,而動態除錯只不過是手動脫殼的一種表現方式。

第二個問題

曰:(由於師哥說面試時喜歡問,此處列出來)

下斷點原理:

由於下斷點有硬體斷點和軟體斷點,我們在這裡只說IDA中的軟體斷點原理:

 X86系列處理器提供了一條專門用來支援除錯的指令,即INT 3,這條指令的目的就是使CPU中斷(break)到偵錯程式,以供除錯者對執行現場進行各種分析。

當我們在IDA中對程式碼的某一行設定斷點時,即:F2,偵錯程式會先把這裡的本來指令的第一個位元組儲存起來,然後寫入一條INT 3指令,因為INT 3指令的機器碼為11001100b(0xCC)當執行到這的時候CPU會捕獲一條異常,轉去處理異常,CPU會保留上上下文環境,然後中斷到偵錯程式,大多數偵錯程式的做法是在被除錯程式中斷到偵錯程式時,會先將所有斷點位置被替換為INT 3的指令恢復成原來的指令,然後再把控制權交給使用者。這樣我們就可以愉快的開始除錯了。如下圖所示也是寫偵錯程式的原理圖:


第三個問題

:先說無反除錯:

1.adb push d:\android_server(IDA的dbgsrv目錄下)  /data/local/tmp/android_server(這個目錄其實可以隨便放,有的反除錯會檢測這)

2.adb shell 

3.su(一定要有root許可權)

4.cd /data/local/tmp

5.chmod 777 android_server(執行許可權要給)

6.再開一個cmd
adb forward tcp:23946 tcp:23946(埠轉發,除錯手機上的某個程序要有協議支援通訊)

7.開啟待除錯的應用程式,就可以愉快的除錯了

再來說有反除錯:

在很多情況下我們遇到的是有反除錯並且用上面的步驟,附加進去以後直接就退出了,這樣的例子數不勝數,那就是反除錯惹的貨。

這時候我們就要改變除錯戰略了

在上文的基礎上:

1.啟動android_server;

2.埠轉發adb forward tcp:23946 tcp:23946

3.adb shell am start -D -n 包名/類名

(說明:以啟動模式啟動,是停在載入so檔案之前,報名在AndroidMainfest檔案中可以找到)

4.開啟IDA,附加上對應的程序之後,設定IDA中的load so的時機,在debug options中設定一下,後面會有實戰部分;

5.adb forward tcp:8700 jdwp:程序號;(jdwp是後面jdb偵錯程式的協議,轉換到待除錯的指定的應用程式);

6.jdb -connect com.sun.jdi.SocketAttach:hostname=localhost,port=8700(jdb進行附加);

7.可以愉快的下斷點,開始除錯了;

第四個問題

:反除錯就是阻止你進行動態除錯所採用的一種手段,在下一篇中會進行具體的講解反除錯的手段,以及解決反除錯的辦法。

反附加,在這塊重要的是說jdb的反附加,很多情況下jdb會附加不上,就是會出現“無法附加到目標的VM”這樣的問題那是因為在每個應用程式下,有這個android:debuggable="true"才能除錯,因為篇幅問題,照樣會在下一篇中會針對反附加尋找目前所有解決辦法。

第五個問題:

曰:我們知道在so的載入時候有個這個過程:

.init->->.init array->->JNI_Onload->->java_com_XXX;

還有我們在脫殼的過程中會在一些系統級的.so中下斷點比如:fopen,fget,dvmdexfileopen,等等

而.init以及.init_array一般會作為殼的入口地方,那我們索性叫它外殼級的.so檔案

這裡歸納為三類:

應用級別的:java_com_XXX;

外殼級別的:JNI_Onload,.init,.init_array;

系統級別的:fopen,fget,dvmdexfileopen;

對於在應用級別的和系統級別的就不說了比較簡單容易理解,這裡也是在實現篇中會重點說的,看到上面的.so的載入執行過程我們知道如果說反除錯放在外殼級別的.so檔案的話我們就會遇程式在應用級核心函式一下斷點就退出的尷尬,事實上多數的反除錯會放在這,那麼過反除錯就必須要在這些地方下斷點,那麼我們就重點的說如何在.init_array和JNI_Onload處理下斷點。

實現篇:

這裡我們會拿阿里有一年的比賽樣本,會放在附件中。

在JNI_Onload處下斷點方法一:(雙開定位)

1.啟動android_server;

2.埠轉發以及除錯模式啟動:如圖所示:

3.開啟IDA,設定


4.附加上對應的程序進去之後如圖:


5.這一步很重要在Debugger option下面選擇這三個選項(讓在load so的每個介面處停下來)


6.jdwp協議埠轉發


7.jdb附加


8.F9執行,忽略提示框;這時候執行到linker處,如圖:


9.這時候找JNI_Onload的絕對地址:

基地址+相對地址;

基地址為:ctrl+s顯示為:


相對地址,用IDA靜態分析libcrack.so可得到相對地止:


絕對地址為:4151E000+1B9C=4151FB9C

按下“G”鍵輸入4151FB9C

如圖所示:按下F2下好斷點,再按F9執行到斷點處就可以愉快的除錯了


在JNI_Onload處下斷點方法二:(簡單好用)

1.首先把要分析的libcrackme.so檔案拉進IDA裡面在要下斷點的JNI_Onload處下好斷點如圖所示:


2.啟動android_server與上面一樣;

3.埠轉發以及除錯模式啟動:如圖所示


4.先設定一下Debugger 如圖所示


5.IDA進行附加程序回到之前靜態分析libcrackme.so的IDA介面單擊Debugger -> Process options 配置除錯資訊,這裡只需配置hostname為localhost,其餘的保持預設設定即可


6.單擊Debugger -> Attach to process進行附加程序


7.jdwp轉發(當然開啟DDMS就不需要這一步了)jdb附加


8.F9執行一路取消就OK,得到如圖所示:


是不是很簡單??

在.iniy_array處下斷點(與上面方法二雷同)

得到的結果是:


OK,搞定


在JNI_Onload處下斷點方法三:(適合於脫殼的時候)

1.可以根據看原始碼,對應不同版本的系統原始碼就會發現一點,如下在vm/Native.cpp路徑下:


2.我們逆向去看,首先把系統中的libdvm.so a db pull出來,拉到IDA中去分析;

找到JNI_Onload處進行分析:F5可以看到,首先V20進行“JNI_Onload”符號查詢,同時在V23有對V20的呼叫,


回到ARM指令處可以看到如下:


0x50008就是偏移處,這個時候我們就開始下斷:

載入上要除錯的APK以後,找到libdvm.so的基址,然後加上50008,下斷點。如果看不到彙編,那就P一下,下斷點,這個比較適合於脫殼的時候。


----------------------

1.動態除錯一般的Android原生程式 例項程式:debugnativeapp ①在Android裝置中新增、配置android_server程式 先將IDA目錄下的./dbgsrv/android_server程式拷貝到Android裝置下: adb push[IDA]/dbgsrv/android_server /data/local/tmp/ 配置檔案許可權屬性,使其為可執行檔案: adb shell chmod 755/data/local/tmp/android_server ②將例項程式新增到Android裝置 adb push debugnativeapp/data/local/tmp/ adb shell chmod 755/data/local/tmp/debugnativeapp ③啟動除錯服務 adb shell/data/local/tmp/android_server  
④進行埠轉發,使PC埠與Android埠可進行互動 adb forward tcp:23946tcp:23946 ⑤啟動IDA,進行程式除錯 啟動IDA的32bit程式,點選:Debugger-Run-RemoteArmLinux/Android debugger,開啟除錯程式的設定對話方塊: Application:對應除錯程式所在的路徑 Directory:對應除錯程式所在的目錄路徑 HostName:輸入localhost,Port:PC埠 點選OK,IDA便可進入除錯介面: IDA動態除錯的小技巧 ①除錯快捷鍵: F2設定斷點,F4執行到滑鼠位置,F7單步步入,F8單步步過,F9執行程式 F5/Tab 將相應的簡單彙編代表粗略轉換為C/C++程式碼 ②將IDA誤識別的程式碼手動轉為ARM彙編程式碼 如下圖,程式在Thumb狀態執行BX PC,PC最後一位為0,應是跳轉到ARM狀態,但應IDA仍誤識別為16位的Thumb,所以不是正常的程式。 如果按快捷鍵C來直接強制轉換,將不成功。應先通過Edit-Segment-Change segment register value(Alt+G),將Value改為0x00,這時程式會變為下邊CODE32的編碼方式,但仍非正常轉換 再按下U,轉為未定義 最後通過快捷鍵C,來轉換便可成功。如是ARM轉為Thumb狀態,則相似(將Value改為0x01) ③修改二進位制碼並儲存修改程式 修改:Edit-PatchProgram-Change byte 儲存:Edit-PatchProgram-Apply patches to input file 2.除錯Android原生動態連結庫 例項:debugjniso.apk ①將apk安裝在裝置中,執行後介面如下,點選“設定標題”按鈕,便會呼叫動態連結庫libdebugjniso.so中的jniString()方法返回一個修改標題欄的字串。在分析加殼程式的殼時,應以除錯方式來啟動除錯程式(adb shell am start-D -n packagename/activityname) ②啟動除錯服務,進行埠轉發 adb shell/data/local/tmp/android_server adb forward tcp:23946tcp:23946 ③啟動IDA進行程式除錯 點選Debugger-Attach-RemoteArmLinux/Android debugger,開啟設定框 HostName:輸入localhost,Port:對應PC埠 點選OK,便會彈出附加Android程序的對話方塊,選中程序com.droider.debugjniso
④使用jdb來連線上apk的java層 jdb -connectcom.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8601 程式所對應的埠可通過eclipse中的devices視窗檢視,執行上邊jdb的命令後,便會在連線上的程式前顯示綠色昆蟲 ⑤確定jniString()方法的偏移地址 從apk中取出動態連結庫檔案,並在另啟的IDA例項上載入,在反彙編程式碼中定位方法的程式位置,由下圖可知,jniString()方法在相應段中的偏移地址為:0xC38(一般固定不變) ⑥確定jniString()方法當前的基地址 回到除錯的IDA,使用Ctrl+S快捷鍵開啟段選擇對話方塊,可查詢到libdebugjniso.so當前的基地址為:4B1F2000(隨載入改變) ⑦定位到jniString()方法的程式位置 由記憶體地址=基地址+偏移地址(4b1f2000:00000c38),可得當前jniString()方法的記憶體地址為:0x4b1f2c38,使用快捷鍵G開啟地址跳轉框,輸入記憶體地址 ⑧設定斷點,進行除錯 跳轉在jniString()方法的程式位置,在0x4b1f2c38行設定斷點(F2) 點選工作欄上的綠色箭頭(F9)讓程式執行起來,然後按下Android上的“設定標題”按鈕,程式會中斷在0x4b1f2c38行,便可進行相應除錯。如按F9執行程式,標題修改結果如下: 3.另一種除錯動態連結庫的方法(無需用到jdb) ①先使用IDA來載入libdebugjniso.so,定位到jniString()方法的程式位置,並在程式開始處設定下斷點 ②點選Debugger-Processoptions,將HostName設定為localhost,然後點選Debugger-Attach to Process,彈出附加Android程序的對話方塊,選中程序com.droider.debugjniso ③載入程序後,便會彈出警告框,詢問兩個檔案是否相同,選擇same ④點選Debugger-Breakpoints-Breakpointlist檢視斷點列表,可發現原先設定的斷點在載入動態庫後仍然存在,且定位到相應的記憶體地址 ⑤進入斷點位置,點選工作欄上的綠色箭頭(F9)讓程式執行起來,然後按下Android上的“設定標題”按鈕,程式會中斷在0x4b1f2c38行,便可進行相應除錯。

9.png (30.63 KB, 下載次數: 13)

9.png

10.png (69.44 KB, 下載次數: 11)

10.png
轉自:http://blog.csdn.net/feibabeibei_beibei/article/details/52740212