逆向手機內核,添加調試支持及繞過反調試


 

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機型支持

Android反調試筆記

記錄下android SELinux造成ida無法調試

修改Android手機內核,繞過反調試


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM