0x00前言 一個安卓應用可以被調試的條件是應用AndroidManifest.xml顯示指定android:debuggable="true",如果沒有設置android:debuggable的值,則預設android:debuggable="false",所以發佈的應用大部分都是不可調試的,如果 ...
0x00前言
一個安卓應用可以被調試的條件是應用AndroidManifest.xml顯示指定android:debuggable="true",如果沒有設置android:debuggable的值,則預設android:debuggable="false",所以發佈的應用大部分都是不可調試的,如果要調試,則需要解包,改屬性然後重打包,這樣非常麻煩,而且效率低。第二個條件是內核配置文件default.prop的屬性ro.debuggable=1,這樣就不用管應用裡面設置的屬性了,看來是一個比較好的解決方案,我們只要修改一次內核就可以一勞永逸了。
安卓應用程式常用的一種反調試手段是查看/proc/[pid]/status下的信息,如果處於調試狀態,那麼TracerPid的值就是調試進程的Pid,那麼程式就會做出相應的行為來反調試。
0x01提取內核
查看boot所在的分區
ls -l /dev/block/platform/msm_sdcc.1/by-name
提取內核
dd if= /dev/block/mmcblk0p17 of=/data/local/boot.img adb pull /data/local/boot.img boot.img
解包內核
bootimg.exe --unpack-bootimg
解包之後的文件結構
0x02修改ro.debuggable
修改initrd/default.prop文件中的ro.debuggable=1
0x03修改kernel文件
複製一份kernel為zImage.gz方便後面的修改
用010editor打開zImage.gz查找十六進位1F 8B 08 00,刪除前面的所有數據,使文件變成一個標準的gzip壓縮文件,這樣就可以使用gunzip解包了。
gunzip zImage.gz
解包生成的zImage就是內核二進位文件了。
用IDA打開文件,設置處理器類型為ARM Little-endian
設置ROM start address和Loading address為0xc0008000
在安卓root終端關閉符號屏蔽
echo 0 > /proc/sys/kernel/kptr_restrict
查看proc_pid_status和__task_pid_nr_ns函數地址
cat /proc/kallsyms | grep proc_pid_status
cat /proc/kallsyms | grep __task_pid_nr_ns
為什麼要查找這兩個函數呢,我們根據源碼/kernel/msm/fs/proc/array.c來看一下
函數proc_pid_status內聯了task_state函數,在task_state內聯函數裡面通過函數__task_pid_nr_ns 獲取到tracerpid並且列印出來。
在IDA中按快捷鍵g跳轉到函數c0187f88(__task_pid_nr_ns)函數處,按x出來引用搜索框,在其中找到函數c02764b8(proc_pid_status)
查看局部的調用為
可以看到調用的結果會存儲在R11中,所以修改命令MOV R11, R0為MOV R11, #0,機器碼為00 B0 A0 E3,文件的偏移為(0xC02765F8-0xC0008000= 26E5F8)
重新壓縮zImage
gzip -n -f -9 zImage
用010editor添加原kernel的首部和尾部二進位數據到文件zImage.gz(新的zImage.gz文件必須比原zImage.gz文件小,並且回寫回去時不能改變原kernel文件的大小及修改原kernel文件後面的內容,否則會很麻煩),這時得到了kernel文件。
添加首部3DEB長的數據
先占位,然後複製首部的數據到頭部
添加尾部數據
替換原先的kernel文件,重新生成新的boot.img
bootimg.exe --repack-bootimg
0x04刷入新的內核
手機重啟到bootloader模式
adb reboot bootloader
刷入新的boot
fastboot flash boot boot-new.img
重啟
fastboot reboot
如果手機開不了機,那麼重新刷回老的內核
fastboot flash boot boot-old.img
0x05SELinux導致IDA無法調試
在安卓端以root許可權啟動andorid_server之後,併在本機做埠轉發,IDA可以正常列出可調試的應用列表,但是當選擇某個程式的時候就會出現如下錯誤
The debugger could not attach to the selected process.
This can perhaps indicate the process was just terminated, or that you dot't have the necessary privileges.
關閉SELinux,之後就正常了,不知道是不是MIUI獨家的問題。
檢測SELinux是否打開
getenforce
返回值:Enforcing:強制模式 Permissive:寬容模式 Disabled:關閉
臨時關閉SELinux
setenforce 0
0為關閉,1為打開,執行後立即生效,無需重啟
0x06小結
工欲善其事,必先利其器,有一個基本的調試環境對逆向學習是非常有幫助的。因為很多的手機產商沒有將手機系統源代碼放出,所以只能採取逆向內核的方式進行修改,如果手機廠商有把系統的源代碼放出,那麼從源碼編譯將會更具有修改性,可以定製更多的內核特性。如果手機有開源的安卓系統支持,比如lineage os或者CM的支持,也可以選擇這些優秀的開源代碼來編譯。
參考:
Android逆向之旅—應用的”反調試”方案解析(附加修改IDA調試埠和修改內核信息)
[原創]支持windows下打包boot/recovery.img的bootimg.exe,且支持自動解包/打包dt.img,加入MTK機型支持