前言
当下,移动互联发展尤为迅速,还记得几年前大家还用着翻盖、滑盖、按键手机,如今按键越来越少,屏幕越来越大,功能越来越多,现在你可以没有电脑,但是你一定不会没有手机,移动安全暗地里发展的更为迅猛,没有人可以停滞不前……
1、Android下常见反调试
0x1Java层反调试
0x2self-debugging反调试
0x3轮训检测反调试
轮训检测反调试原理
读取进程的/proc/[pid]/status文件内的TracerPid字段的值判断当前进程或线程是否正在被调试
status文件信息字段:
(1)Name:进程名
(2)State:表示进程状态
(3)Tgid:线程组ID,一般指进程名
(4)Pid:线程ID,它的值和gettid函数的返回值相等
(5)PPid:父进程的进程ID
(6)TracerPid:实现调试功能的进程ID,值为0 表示当前进程未被调试
我们以调试模式启动一个应用看下
我们用IDA附加后再看,TracerPid的值就是调试的进程PID
0x4 反反调试思路
0x01动态调试时修改TracerPid字段值为0
0x02修改内核,让TracerPid字段值永远为0
为了一劳永逸,本文将探讨修改内核的过反调试方法
0x5而修改内核分为两种:
0x01下载Android源码自己修改后编译
0x02逆向Android内核修改刷机
自己修改Android源码编译请参考:
https://bbs.pediy.com/thread-213481.htm
因为现在一般手机都是厂商定制的系统,所以本文将探讨逆向修改手机内核来达到过反调试的目的
2、下载android4.4.4源码分析
0x1下载
git clone https://aosp.tuna.tsinghua.edu.cn/kernel/msm.git
git branch -a
git checkout remotes/origin/android-4.4
大致目录如下
0x2分析
发现TracerPid的值来自于tpid
Tpid来自于task_pid_nr_ns
发现是proc_pid_status调用了task_state,还记得我们是怎么读取进程的吗
Cat /proc/[pid]/status
所以函数proc_pid_status调用了task_state函数,在task_state内联函数里面通过函数task_pid_nr_ns
获取到TracerPid并且打印出来
3、提取内核
0x1确定位置
Cd /dev/block/platform/
Cd /dev/block/platform/7824900.sdhci/
Cd /dev/block/platform/7824900.sdhci/by-name
Ls
ls -l /dev/block/platform/7824900.sdhci/by-name
lrwxrwxrwx root root 1973-05-20 16:10 boot -> /dev/block/mmcblk
0p25
0x2提取内核
dd if=/dev/block/mmcblk0p25 of=/data/local/tmp/boot.img
root@gucci:/data/local/tmp # chmod 777 boot.img
adb pull /data/local/tmp/boot.img E:boot.img
0x3解包内核
使用bootimg解包boot.img
查看解压出来的文件
4、修改内核支持调试 ro.debuggable
initrd/default.prop文件
ro.debuggable=0改为ro.debuggable=1
5、修改kernel文件
0x1定位函数修改指令法
复制一份kernel为zImage.gz
查找十六进制1F 8B 08 00,删除前面的所有数据,使文件变成一个标准的gzip压缩文件
解包的zImage就是内核二进制文件
用IDA打开文件,设置处理器类型为ARM Little-endian
设置ROM 起始地址和加载地址填0xc0008000
在安卓root权限前提下,关闭符号屏蔽
echo 0 > /proc/sys/kernel/kptr_restrict
查看proc_pid_status函数地址
cat /proc/kallsyms | grep proc_pid_status
c0235ef8 T proc_pid_status
查看__task_pid_nr_ns函数地址
cat /proc/kallsyms | grep __task_pid_nr_ns
c0135d98 T __task_pid_nr_ns
复制函数地址,在IDA中按G跳转
如果出现这样的情况,可以右键,转换为C代码
按G去c0235ef8,没有解析函数名,可按下P键强制解析函数 sub_C0235EF8
(proc_pid_status)
按G去c0135d98(task_pid_nr_ns),右键,交叉引用列表 搜索 sub_C0235EF8
然后修改指令让TracerPid字段值为0
不过不推荐这种方法,一个是对新手有难度,一个是哪怕同厂商的手机硬件和系统都有差别,不是很通用
0x2修改输出字符法
shift+f12,搜索TracerPid
双击进去
ROM:C0B57A23 DCB "TracerPid:",9,"%d",0xA
我们可以把TracerPid那一项的占位符%d,改成'0'
因为'%d'是两个字符,所以我们可以改成'00',或者'0t'
0x C0B57A23 - 0xC0008000 = 0xB4FA23
010Editor打开zImage文件,Ctrl+G跳转到0xB4FA23处
'0t'对应的十六进制就是:30 09,修改25 64为30 09
重新打包成boot.img文件
将修改后的zImage在Linux下用gzip压缩一下
gzip -n -f -9 zImage
同时打开原kernel文件和压缩好的zImage.gz,在zImage.gz中搜索1F 8B 08 00
0x40EB
0x6043F6
zImage.gz结束位置 + kernel中的1F8B0800位置 = 结束位置
0x6043F7 + 0x40EB = 0x6084E2
全选zImage.gz,从kernel中的1F8B0800位置替换到0x6084E2位置
替换原先的kernel文件,重新生成新的boot.img
Bootimg --repack-bootimg
6、刷入新的内核
0x1手机重启到bootloader模式
adb reboot bootloader
0x2刷入新的boot
fastboot flash boot boot-new.img
0x3重启
fastboot reboot
备注:如果手机开不了机,那么重新刷回老的内核
fastboot flash boot boot-old.img
7、验证是否成功
0x1是否不显示包名
0x2是否调试时不为0
本文始发于微信公众号(Secquan圈子社区):实战逆向修改手机内核支持调试、过反调试
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论