IDA動態調試技術及Dump內存
來源 https://blog.csdn.net/u010019468/article/details/78491815
最近研究SO文件調試和dump內存時,為了完整IDA調試起來,前后摸索了3天才成功,里面有很多坑和細節,稍微不注意,就一直排行,需要理解每步驟的作用意義,否則就會覺得教程不對,要詳細的教程可能找不到,大部分都是簡單介紹,沒有提醒細節和易忽視的點
動態調試步驟,順序嚴格如下
事先准備工作
1、要求root手機或者直接用模擬器
否則沒有權限啟動android_server
2、IDA在6.6以上版本 或者手機為5.0以下 否則會出現 pie異常:
error: only position independent executables (PIE) are supported.
- 1
細步驟如下::
1、首先把IDA安裝目錄下的android_server文件通過adb push 命令push到手機/data/local/tmp/目錄下,並通過root權限身份運行./android_server
C:\Windows\System32>adb shell shell@HWGRA:/ $ cd /data/local/tmp/ shell@HWGRA:/data/local/tmp $ ./android_server IDA Android 32-bit remote debug server(ST) v1.19. Hex-Rays (c) 2004-2015
- 1
- 2
- 3
- 4
2、通過adb forward命令把端口轉cp端IDA的監聽應用端口號 adb forward tcp:23946 tcp:23946
3、通過adb shell am start -D -n com.exaple.cctf/.MainActivity 命令打開應用的調試模式
4、打開IDA進行attach
是32-bit的debug server,於是將IDA換成32位的。注意,調試32位的程序得用IDA的32位版,64位的程序用64位版。不然會出錯。如下:
Incompatible IDA version 以及ida報不識別host
- 1
通過運行android_server之后 顯示的位數來判斷是32位還是64,如下:
IDA Android 32-bit remote debug server(ST) v1.19. Hex-Rays (c) 2004-2015
5、啟動IDA之后並attach了調試進程,設置了Debugger Options 使能在so加載調試下停住。重點再是讓進程運行起來之后,再用jdb連接手機虛擬機,否則連不起來,會阻塞,會無法添加到vm,順序很重要。
6、jdb連接,使進入調試模式
jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8700
可能會存在阻塞或者顯示無法添加到vm等錯誤:阻塞可能是因為沒有把ida運行起來app_process
后者錯誤就可能是apk沒有配置到調試模式。
成功之后,ida會再次掛起,繼續按鈕恢復成可以點擊狀態。
7、設置斷點,再繼續運行,便會停在斷點處。
相關adb 命令收集
1、adb shell pm list packages 獲取手機包名列表
2、adb shell dumpsys package [name] 獲取安裝包的信息 查看是否可以debugable
flags=[ DEBUGGABLE HAS_CODE ALLOW_CLEAR_USER_DATA TEST_ONLY ALLOW_BACKUP STO PPED ]
- 1
- 2
flags中還有debuggable
3、adb forward tcp:23946 tcp:23946 把手機中的android_server的端口號轉發到cp應用Ida端口
4、android list adv 列出adv虛擬機列表
5、emulator -adv [name] 啟動某個名為name的虛擬機
6、當有時候adb鏈接失敗時
,通過重啟來鏈接adb
adb kill-server 殺死adb進程,
adb start-server
7、adb shell am start -D -n [package/MainActivity.class路徑] 調試模式啟動應用
相關Adb命令文章和介紹
Android ADB 常用命令
Android adb你真的會用嗎?
Dump內存
一種是直接調試時候斷點到libdvm.so加載dex時候,找到在內存中的起始點r0和大小r1,然后通過ida運行腳本:
static main(void) { auto fp, begin, end, dexbyte; fp = fopen("C:\\dump.dex", "wb"); begin = r0; end = r0 + r1; for ( dexbyte = begin; dexbyte < end; dexbyte ++ ) fputc(Byte(dexbyte), fp); }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
把內存這塊連續地址內容dump出來,這種只能dump安裝運行時apk中classes.dex,不方便dump多次dex加載或動態加載時定位到起始地址
第二種直接運行apk之后通過首先通過cat /proc/[pid]/maps查看目標dex文件所在的內存地址,這樣就可以查找所有加載過的dex內存映射地址,不論是在什么時候加載的,只要運行了,就必會在內存中找到相應的映射地址:
方法步驟:通過adb shell 之后,ps查找相關進程的pid 然后再cat 找出maps映射內存地址
4b92f000-4bce7000 r--p 00000000 1f:01 567 /data/dalvik-cache/data@app@com .example.xianwang_danji-1.apk@classes.dex 4bce7000-4bd38000 rw-p 00000000 00:07 1746 /dev/ashmem/dalvik-aux-structur e (deleted) 4bd38000-4bd3f000 r-xp 00000000 1f:01 519 /data/data/com.example.xianwang _danji/lib/libme_xxx.so 4bd3f000-4bd40000 r--p 00006000 1f:01 519 /data/data/com.example.xianwang _danji/lib/libme_xxx.so 4bd40000-4bd61000 rw-p 00007000 1f:01 519 /data/data/com.example.xianwang _danji/lib/libme_xxx.so
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
可以發現所有加載到內存中連續的地址塊,以及出處,就很方便定位自己要dump的內容了,找到相關地址4b92f000-4bce7000直接通過上述script command執行dump相關內容出來。就用ida通過上述步驟附加到手機應用即可,然后通過腳本生成文件。
對於dump出來的文件是odex直接打開看不夠清晰,如用GDA工具打開里面都是類似匯編語言。這時就需要用到baksmali.jar 和smali.jar來轉換成dex文件,可以直接方便查閱。詳見我的另一篇文章《手機dump內存Odex格式反編譯》
當然這只是最簡單脫殼方法,很多高級殼會動態修改dex的結構體,比如將codeoffset指向內存中的其他地址,這樣的話你dump出來的dex文件其實是不完整的,因為代碼段保存在了內存中的其他位置。那么針對這種反調試情況下以及其他阻礙動態調試下,dump內容和ida調試都很難進行下去,看到網上有這樣的文章:利用開源脫殼工具DexExtractor來脫殼。它的原理就是修改系統的DexFile.cpp源碼,在解析dex的函數開頭處加上自己的dumpdex邏輯。 這樣不論怎么繞,只要加載了dex就可以dump出來,可以研究下,傳送門:http://blog.csdn.net/jiangwei0910410003/article/details/54409957
相關文章:
IDA附加調試apk程序,並修改內存,編寫IDA腳本程序,把修改后的dex文件dump到本地
Android逆向之旅—動態方式破解apk進階篇(IDA調試so源碼)