逆向手机内核,添加调试支持和反调试

Posted 夏侯爷の星辰大海

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了逆向手机内核,添加调试支持和反调试相关的知识,希望对你有一定的参考价值。

 

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手机内核,绕过反调试

以上是关于逆向手机内核,添加调试支持和反调试的主要内容,如果未能解决你的问题,请参考以下文章

Android修改内核

逆向分析反调试程序

Android逆向案例:干掉梆梆加固免费版的反调试检测

Android逆向案例:干掉梆梆加固免费版的反调试检测

Crimsonland 血腥大地 逆向无敌通关分析报告配置文件加密Dll隐藏MD5检测补丁反调试函数反反调试

去除ios反调试