首页
社区
课程
招聘
[原创]修改android内核绕过Anti-Debug
发表于: 2016-7-8 11:22 14462

[原创]修改android内核绕过Anti-Debug

2016-7-8 11:22
14462

0X00 前言
在分析android的时候,开发者为了增加软件破解的难度会增加一些检测调试或者后期直接加固APK。对于JAVA层的的调试检测比如判断是否Android.os.Debug.isDebuggerConnected(),对应的我们可以修改Smali代码去掉这个检测函数,或者改变函数返回的逻辑,二次打包Apk去掉检测,在不能二次打包的时候我们可以通过Xposed 框架Hook java函数方法,同样可以绕过检测。对于Jni层,大多数应用都是通过检测TracerPid这个值去判断,比如这篇文章里面讲的,http://drops.wooyun.org/mobile/16969,通过判断TracerPid,默认情况下,这个值是0,如果我们在用GDB,IDA这样调试工具附加APP的时候,系统会把这个值修改进程的pid值,这样用来检测是否被调试。因此我们在内核中修改这个值,让其始终为0.这样绕过通过检测TracerPid的Anti-Debug。
0X01 内核的修改编译与刷机
整个操作是在ubuntu 14.04 64位系统上,我的手机是Google Nexus4,高通的芯片,当你的手机型号不同的时候,你要选择自己的版本,具体可以看这里https://source.android.com/source/building-kernels.html

下载源码,创建一个文件夹,执行

`$ git clone https://android.googlesource.com/kernel/msm.git`
这里有的会提示网络拒绝连接,我们选择清华的aosp源,

`$ git clone https://aosp.tuna.tsinghua.edu.cn/kernel/msm.git`

`$ git branch -a` 

`$ git checkout origin/android-msm-mako-3.4-jb-mr2`
代码下载好以后,通过全局查找TracerPid,在源码的的fs/proc/array.c文件里面,找到了TracerPid的修改过程,

pid_t ppid, tpid = 0, tgid, ngid;
if (tracer)
    tpid = task_pid_nr_ns(tracer, ns);
    .....
    seq_printf(m,
    "State:\t%s\n"
    "Tgid:\t%d\n"
    "Ngid:\t%d\n"
    "Pid:\t%d\n"
    "PPid:\t%d\n"
    "TracerPid:\t%d\n"
    "Uid:\t%d\t%d\t%d\t%d\n"
    "Gid:\t%d\t%d\t%d\t%d\n"
    "FDSize:\t%d\nGroups:\t",
    get_task_state(p),
    tgid, ngid, pid_nr_ns(pid, ns), ppid, tpid,
    from_kuid_munged(user_ns, cred->uid),
    from_kuid_munged(user_ns, cred->euid),
    from_kuid_munged(user_ns, cred->suid),
    from_kuid_munged(user_ns, cred->fsuid),
    from_kgid_munged(user_ns, cred->gid),
    from_kgid_munged(user_ns, cred->egid),
    from_kgid_munged(user_ns, cred->sgid),
    from_kgid_munged(user_ns, cred->fsgid),
    max_fds);
开始的时候tpid初始化为0,然后有个if判断,重新赋值tpid,因此,在这个if判断后面,我们再次添加

tpid = 0;
这样无论前面怎么操作,TracerPid始终为0.修改好代码后,下面设置环境变量,注意每次编译之前都得设置一下,如果你没有编译过android源码,你还得下载这个工具,

$ git clone https://android.googlesource.com/platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6

$ export PATH=$(pwd)/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin:$PATH
$ export ARCH=arm
$ export SUBARCH=arm
$ export CROSS_COMPILE=arm-eabi-
$ make mako_defconfig
$ make -j12
一切顺利的话,会在当前子目录arch/arm/boot 目录下面生成zImage,我们的kernel文件。 有了kernel,怎么刷入手机中,两种方式,如果你是android源码编译的话,将这个zImage替换android源码的device/lge/mako-kernel文件夹的中kernel文件,这样你编译出来的系统内核被替换我们自己编译的内核。还有一种方式,我们手机刷入recovery以后,用卡包的方式刷机,在这个zip文件中,有个boot.img文件,通过解包得到内核和文件系统,然后替换内核,在重新打包得到boot.img,再把这个boot.img刷入到手机就可以。下载所需要的工具

$ git clone https://github.com/pbatard/bootimg-tools.git
$ cd bootimg-tools/
$ make 
解包boot.img

$ unmkbootimg -i boot_img/boot.img

kernel written to 'kernel' (8331496 bytes)
ramdisk written to 'ramdisk.cpio.gz' (498796 bytes)

To rebuild this boot image, you can use the command:
mkbootimg --base 0 --pagesize 2048 --kernel_offset 0x00008000 --ramdisk_offset 0x02900000 --second_offset 0x00f00000 --tags_offset 0x02700000 --cmdline 'console=ttyHSL0,115200,n8 androidboot.hardware=hammerhead  user_debug=31 maxcpus=2 msm_watchdog_v2.enable=1' --kernel kernel --ramdisk ramdisk.cpio.gz -o boot_img/boot.img
重新打包boot.img

$ cp msm/arch/arm/boot/zImage-dtb kernel
$ mkbootimg --base 0 --pagesize 2048 --kernel_offset 0x00008000 --ramdisk_offset 0x02900000 --second_offset 0x00f00000 --tags_offset 0x02700000 --cmdline 'console=ttyHSL0,115200,n8 androidboot.hardware=hammerhead  user_debug=31 maxcpus=2 msm_watchdog_v2.enable=1' --kernel kernel --ramdisk ramdisk.cpio.gz -o boot.img
选择新的boot.img启动或者直接刷入

fastboot boot boot.img
或者
fastboot flash boot boot.img
如果一切顺利,手机可能正常启动,也可能变为砖。我遇到的问题的是WIFI挂了,启动不了。XD

0X02 测试一个APK
这里我们以ALimsc的题目验证一下,题目的详情和解析思路可以参看蒸米大大写的文章,http://drops.wooyun.org/tips/6840。题目大体是我们的输入与一个字符串比较,但是这个字符串在运行时被修改,并且会通过读取当前进程的TracerPid判断是否被调试,如果被调试,就kill自己。现在我们用IDA附加看我们的修改是否起作用。

这里讲个技巧,如果你是mac,又没有IDA for mac,像我一样,可以装个win系统,通过端口转发的方式,在/etc/pf.anchors/目录下面新建个com.my文件,并写入下面的内容

rdr pass on vmnet8 inet proto tcp from any to self port 2333 -> 127.0.0.1 port 23946
然后执行 pfctl -ef /etc/pf.anchors/com.my即可,其他步骤和常规调试一样,只是在hostname选择你的mac id地址,附加成功我们发现程序并没有退出,我们在比较的地方下个断点。成功获取到正确的比较值。也就是说我们的修改成功了。 


我们看下此时的TracerPid也为0。

0X03 小结&参考
这样的修改方式在调试APP的时候简化了一些操作分析。

http://marcin.jabrzyk.eu/posts/2014/05/building-and-booting-nexus-5-kernel
https://source.android.com/source/building-kernels.html
http://drops.wooyun.org/mobile/16969
http://drops.wooyun.org/tips/6840


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 3
支持
分享
最新回复 (6)
雪    币: 233
活跃值: (285)
能力值: ( LV12,RANK:270 )
在线值:
发帖
回帖
粉丝
2
偷偷说一句,同文件还有个地方要改~否则还是可能被anti
2016-7-8 11:41
0
雪    币: 62
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
继续完善这应该是一个不错的方案吧
2016-7-9 11:49
0
雪    币: 25
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
难道t改成S
2016-7-11 01:36
0
雪    币: 546
活跃值: (1662)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
5
State 的状态  sleeping
2016-7-11 08:49
0
雪    币: 34
活跃值: (21)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
感谢评论君的提示
2016-8-30 13:07
0
雪    币: 191
活跃值: (195)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
7
哈哈多谢分享,原来TracerPid的源码位置在这里,想问楼主,这种方式对/proc/pid/status和/proc/pid/task/tid/status里面的TracerPid的值都起效果吗,还是只能对/proc/pid/status起效果
2016-8-30 19:14
0
游客
登录 | 注册 方可回帖
返回
//