尝试绕过TracerPID反调试

准备工作

Windows下Linux环境准备

安装MinGW

在官网下好MinGW之后, 右键按下图选中要下载的,之后直接在Installation中直接选中Apply change即可。

###
进入安装目录<MinGW安装的地方>\MinGW\bin, 将gcc.exe重命名为cc.exe, 就短暂地这样改就好了,之后用完make工具再改回来。反正我没找到哪里可以改Makefile的内容。不这样修改的话会出现如下报错:

具体原因好像是MinGW的bug, 在Linux环境下一般gcc是等同于cc的, 然而在Windows中却不是这样的, 如果有人找到Makefile的内容可以在哪里改的话, 可以告诉我=v=, 虽然下面并没有可以评论的地方。

注:还有千万别学人家瞎改名, 把mingw-make.exe改成make.exe直接用, 这样也会报错!

准备boot

  1. 提取boot.img
    1
    2
    3
    4
    C:\Users\[your username]>adb shell
    shell@hammerhead:/ $ su
    root@hammerhead:/ # cd /dev/block/platform/msm_sdcc.1/by-name
    root@hammerhead:/dev/block/platform/msm_sdcc.1/by-name # ls -al

输入以上命令即可找到boot的位置。

将boot导出成boot.img。这里一定要注意, 要按照你自己的情况将boot导出, 要修改if=/dev/block/[实际boot文件夹名]

1
dd if=/dev/block/mmcblk0p19 of=/data/local/boot.img

重新开一个命令行页面,或直接exit退出,输入如下指令:
adb root pull /data/local/boot.img boot.img

这里加了一个root是因为之前直接pull的时候说我权限不够。加了root之后发现还是一直失败, 就尝试先将boot.img存到/sdcard/Download下面之后直接用pull指令就成功了。

1
2
3
4
5
root@hammerhead:/sdcard/Download$ su
root@hammerhead:/sdcard/Download# cp /data/local/boot.img /sdcard/Download/boot.img
root@hammerhead:/sdcard/Download# exit
root@hammerhead:/$ exit
C:/Users/[your username]> adb pull /sdcard/Download/boot.img

在哪个目录下pull的,文件就会存在哪个目录下。

  1. 准备好bootimg-tools工具
    git clone https://github.com/pbatard/bootimg-tools.git

下载后打开文件夹到[MinGW安装的目录]]\MinGW\msys\1.0, 双击msys.bat即可进入到一个模拟Linux环境的GUN界面中。进入[bootimg-tools所在文件夹]/bootimg-tools(如果找不到的话可以用everything找找看), 用make指令生成二进制文件。

将boot.img拷到[bootimg-tools所在文件夹]\bootimg-tools\mkbootimg文件夹下, 执行命令./unmkbootimg -i boot.img。(要记录下面输出的一大段字,之后要重新生成boot.img的时候直接复制修改成相应kernel文件名和输出文件名即可)

  1. 提取原始zImage
    复制kernel文件并将其重命名为zImage.gz。用010 Editor工具找到16进制1f 8b 08 00, 删掉查找到的位置的前面的所有数据,使文件变成标准的gzip压缩文件, 保存之后再执行命令gunzip zImage.gz

到这里zImage文件就提取完成了。

修改内核

说明

我这里用的是IDA 7.0

正式开始

用IDA直接打开zImage文件, 并做如下改动

点击OK之后, 继续按照下面修改。

定位函数位置

打开命令提示符, 输入如下指令关闭符号屏蔽, 并查看函数地址, 因为在IDA中查看二进制文件不好直接用函数名进行定位。

1
2
3
4
5
C:\Users\[your username]>adb shell
shell@hammerhead:/ $ su
root@hammerhead:/ # echo 0 > /proc/sys/kernel/kptr_restrict /*关闭符号屏蔽*/
root@hammerhead:/ # cat /proc/kallsyms |grep proc_pid_status
root@hammerhead:/proc # cat /proc/kallsyms |grep __task_pid_nr_ns

函数地址如下:

在IDA中按下快捷键G跳转到c01b0884(__task_pid_nr_ns函数)

之后点击函数名c01b0884(__task_pid_nr_ns函数), 按下快捷键X, 会弹出交叉引用, 在其中查找我们上面找的第二个函数c02ba04c( proc_pid_status)的位置。

好的, 上面选中的并不是我想找的函数TAT。这个时候, 就在IDA界面中按下Shift+F12, 在字符串界面查找TracerPid。找到之后双击查询后的结果。

IDA在解析的时候没有解析好这个文件, 出现了下面的情况。

这时候选中S的位置即0x53按下A, 即可正常解析。如果解析出来还不是下面这种格式,可以鼠标左键选中该字符串的所有内容再按一次A

如果字符串都解析出来之后, 还是识别不出来c02ba04c( proc_pid_status)函数的话, 直接G跳转到c02ba04c, 并按下C, 但是识别的函数也不是正确的。所以这里采用第三篇参考文章的方法, 直接修改TracePid字符串。

修改TracePid字符串

(1) 选中TracePid中的%d

(2) 将TracePid中的%d改为0\t, 选中%d后按下Alt+4

上图中第四行第一个%d就是我们要修改的(TracerPid后的字符串), 十六进制为25 64。点击25前面按下F2, 输入30 09, 再按下F2就修改成功了。

最后保存修改的内容, 按下图点开之后直接点OK即可。

修改kernel文件

在MinGW命令行界面输入命令gzip -n -f -9 zImage, 压缩修改好的文件zImage生成zImage.gz。用010 Editor打开文件kernel, 并在kernel中查找1F 8B 08 00。(下图是覆盖完成的样子)

选中1F 8B 08 00位置之后,点开Edit->Insert/Overwrite->Overwrite File..., 选择zImage.gz文件即可, 这样就不用自己计算文件大小并且直接覆盖了, 完成之后点击保存为新的文件boot-new.img

使用执行unmkbootimg生成的命令, 修改-o参数名(要输出的文件名), 直接拷贝到MinGW命令行中直接执行。

1
2
3
    $ mkbootimg --base 0 --pagesize 2048 --kernel_offset 0x00008000 --ramdisk_offset 0x02900000 --second_offset 0x00f00=
000 --tags_offset 0x02700000 --cmdline 'console=ttyHSL0,115200,n8 androidboot.hardware=hammerhead user_debug=31 max
cpus=2 msm_watchdog_v2.enable=1' --kernel kernel --ramdisk ramdisk.cpio.gz -o boot-new.img

  1. 刷机
    我这里用的是Nexus 5, 直接在关机状态下按音量键-开机键(或输入命令adb reboot bootloader)即可进入fastboot状态。在命令行中输入fastboot flash boot boot-new.img, 之后再输入fastboot reboot即可。

刷完倒是能正常开机了, 但是我手机又要重新root了…..(这个时候有尝试过用SuperSU刷成砖, 还是用magisk+twrp比较好)

参考材料\文章

逆向修改内核,绕过TracerPID反调试
make: cc: Command not found
Android逆向之旅—应用的”反调试”方案解析(附加修改IDA调试端口和修改内核信息)