准备工作
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
- 提取boot.img
1
2
3
4C:\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
5root@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的,文件就会存在哪个目录下。
- 准备好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文件名和输出文件名即可)
- 提取原始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
5C:\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
- 刷机
我这里用的是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调试端口和修改内核信息)