建议在git bash下操作
由于解压kernel.gz
时使用的不是命令行,导致没有看到输出信息gzip trailing garbage ignored
,进而没有对这些数据进行处理,浪费了很多时间。
概述
直接修改内核,降维打击绕过反调试。
如果有内核源码以及环境,当然可以通过直接修改源码的方式生成boot.img
。
在无内核源码(或者还没配置安卓源码编译环境)的情况下则只能通过逆向来修改内核。
环境
Redmi Note 3
, arm64
, cm12.1
过程
1. 找到并导出boot.img
进入adb shell
并执行su命令获取root权限(platform下文件夹可能会有所不同,即可能不是mtk-msdc.0)
1 | ls -al /dev/block/platform/mtk-msdc.0/by-name |
根据输出信息boot -> /dev/block/mmcblk0p7
得知boot对应该mmcblk0p7
dd大法导出该文件
1 | dd if=/dev/block/mmcblk0p7 of=/data/local/boot.img |
2. 解包boot.img以及内核
此处使用的是bootimg
工具(下载地址),创建一个临时文件夹,执行./bootimg.exe --unpack-bootimg .\boot.img
,再解压kernel.gz
得到内核文件
强烈建议在git bash
下使用gzip -d
解压,这样才能查看具体的输出信息
输出gzip trailing garbage ignored
(尾部垃圾被忽略处理)
gzip认为这是尾部垃圾,实际上却是必要的数据,不考虑的话可能会导致无限重启。
收集尾部数据
解压kernel.gz
后重新压缩内核文件,得到没有尾部数据的真实kernel.gz
。
再通过010Editor
在原kernel.gz
中,查找真实kernel.gz
文件尾(一般四个字节就只有一个结果了),定位到尾部这段数据,保存下来
3. 使用IDA64反编译
processor type
选择ARM Little-endian
弹出来一个提示框,点击确定,然后输入ROM start address
和Loading address
为内核基址:0xffffffc000080000
4.修改内核文件
方法1 修改TracerPid的格式字符串
(该思路来自逆向修改内核,绕过TracerPID反调试)
使用010Editor
打开内核文件,搜索TracerPid
,修改TracerPid
后的第一个 "%d"
改成 "0\t"
(30 09
) 或 "0\n"
(30 10
) 或 "00"
(十六进制30 30
)
方法2 修改proc_pid_status函数指令
查看函数地址
1 | echo 0 > /proc/sys/kernel/kptr_restrict |
输出为
1 | ffffffc0001f7aa8 T proc_pid_status |
定位函数及patch
在ida中按g跳转到ffffffc0000bb1f0
(task_pid_nr_ns
),按p解析函数
再按g跳转到ffffffc0001f7aa8
(proc_pid_status
),按p解析函数
然后回到ffffffc0000bb1f0
(task_pid_nr_ns
),按x查看交叉引用,发现已经有ffffffc0001f7aa8
(proc_pid_status
)调用的信息了
双击进入,在IDA View视图中定位到关键指令
1 | MOV W1, W25 |
修改往前第两条和后一条的mov指令(可使用KeyPatch插件),结果为
1 | MOV W1, #0 |
对应机器码为01 00 80 52
和19 00 80 52
5. gzip压缩内核
在git bash
下使用gzip
压缩修改后的内核文件
1 | gzip -n -f -9 kernel |
6. 重打包boot.img
方法1 使用bootimg打包(推荐)
使用010Editor
编辑刚刚生成的kernel.gz
,添加上之前获取的尾部数据
然后执行./bootimg.exe --repack-bootimg
得到的boot-new.img
文件,刷入即可
方法2 手动写入boot.img
使用010Editor
分别打开kernel.gz
和boot.img
,搜索1F 8B 08 00,定位到内核gzip位置(一般是0x800,不确定的话可以打开原本kernel.gz
对比)
压缩后大小<=真实kernel.gz时
按下insert
键,将010改为overwrite
(右下角有提示)
然后把kernel.gz
的内容复制到boot.img
的相应位置,保存即可
(根据引用文章所说,小于的话可以直接不考虑后面的字节)
压缩后大小>真实kernel.gz时
按下insert
键,将010改为insert
(右下角有提示)
选定真实kernel.gz
部分(即不包括之前获取的尾部数据)
然后把kernel.gz
的内容复制到boot.img
的相应位置,保存即可
6. 使用fastboot刷入
使用adb reboot bootloader
重启到fastboot
然后执行
1 | fastboot flash boot boot.img |
如果成功的话就直接正常开机了,失败的话看看是不是修改错了内核文件的内容,从原内核开始修改,再次尝试