未加星标

Magisk on T1

字体大小 | |
[系统(linux) 所属分类 系统(linux) | 发布者 店小二05 | 时间 2019 | 作者 红领巾 ] 0人收藏点击收藏

Smartisan T1是一款老机型了,时至今日,运行的仍然是Android 4.4的系统。以前研究过它的Bootloader解锁,如今打算回头再看看怎么把最新的root方案Magisk移植进来实现持久。

不同于supersu需要twrp的支持,Magisk提供了一种十分便捷的修改镜像的方法。只要把目标设备的boot.img拖出来,放到任何一台安装有Magisk Manager的手机上,就能进行重打包,包装成一个带有root功能的镜像。接下来,无论用什么方法,只要能把boot.img刷回boot分区就可以了。

临时root

T1升到最新版本后(2018年2月份的版本),为了把boot.img拖出来,并放回去,需要取得一个临时的root权限,我利用的是CVE-2017-8890,不过这不是重点。问题是后面的Magisk重打包。

Magisk原理

Magisk的重打包,从底层看,主要就是把/init替换成了它自己的magiskinit。当boot启动时,magiskinit首先从/.backup恢复原始的init文件。然后从magiskinit中释放出来magisk.bin和Manager的APK等后续建立root需要的文件。接着它会以init权限patch sepolicy,增加一个名为magisk的上下文环境,最后启动magiskd等待su的连接。

当su命令执行时,背后实际上是向magiskd请求root,magisk则会向Magisk Manager发起问询,等待用户确认后才赋予放行,最后magiskd启动一个shell,并把它重定向到su通过unix socket发送过来的输入输出句柄上。

T1带来的麻烦

现在最大的问题是Magisk Manager编译时只能运行在5.0以上的系统,4.4没有支持。如果抛弃magisk,单靠suid之不能建立起完整root的,4.4虽然selinux弱得很(通过/proc/self/attr/current就能任意修改自身上下文),但普通的用户进程其capability已经几乎全部丢弃,即便uid和gid都为0,能做的事情也有限。还是需要一套magisk这种劫持启动流程的方案才能从一开始就拿到init。

所以打算完全抛弃Magisk Manager,通过patch magisk自身的逻辑,实现任意进程执行su时无需校验就放行。

patched_boot.img的重打包

想要patch magisk,要修改的实际上是Manager重打包后的patched_boot.img。它当中的magiskinit包含了magiskd的代码,只要修改两个关键的跳转就算通过了。不过问题是这里每个环节都很繁琐。首先magiskinit的文件结构很特殊:

$ binwalk init DECIMAL HEXADECIMAL DESCRIPTION -------------------------------------------------------------------------------- 0 0x0 ELF, 32-bit LSB executable, ARM, version 1 (SYSV) 262482 0x40152 Unix path: /vendor/etc/selinux/precompiled_sepolicy 262824 0x402A8 Unix path: /sys/fs/selinux/policy 262895 0x402EF Unix path: /sys/fs/selinux/load 263576 0x40598 Unix path: /sys/fs/selinux/policy) 266224 0x40FF0 Unix path: /vendor/etc/selinux/plat_sepolicy_vers.txt 296964 0x48804 xz compressed data 301647 0x49A4F xz compressed data 346435 0x54943 xz compressed data 376768 0x5BFC0 Unix path: /proc/device-tree/firmware/android

其中0x49A4F开始的这个区块就是magiskd也就是su_daemon。由于magiskinit要根据这些偏移解出来所需要的文件,修改的时候必须要保证文件大小精确一致。

0x49A4F 文件可以dd出来,然后unxz解开。修改二进制后,不能直接xz,xz命令和magisk用的结构稍微不太一样,需要使用python3的lzma的compress去压缩,也就是:

lzma.compress(magisk, preset=9, check=lzma.CHECK_NONE)

dd回去之后,还要进行ramdisk的重打包,这里同样有个文件大小要保持一致的问题。因为patched_boot.img已经和boot.img不一样了,末尾会增加一个xz,包含Manager的APK文件,虽然用不到,但虽已覆盖会导致初始化失败。

虽然ramdisk重打包有很多工具,但都无法和magisk的cpio保持一致,主要原因是普通的重打包都没有考虑到/.backup等隐藏目录的引入。所以更精确的做法是直接对cpio文件操作,找到init文件的位置,写入修改后的文件内容。对cpio进行gzip时同样还有问题,系统自带的gzip会加入过多的metadata导致文件比原来要大。我解决的方法是minigzip.py,去掉文件名相关的metadata,然后进行压缩,这样大小就和原来相同了,最后dd回patched_boot.img就可以了。再次开机启动就拿到了久违的su:

shell@msm8974sfo:/ # id -Z uid=0(root) gid=0(root) context=u:r:magisk:s0

本文系统(linux)相关术语:linux系统 鸟哥的linux私房菜 linux命令大全 linux操作系统

代码区博客精选文章
分页:12
转载请注明
本文标题:Magisk on T1
本站链接:https://www.codesec.net/view/628549.html


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 系统(linux) | 评论(0) | 阅读(299)