来自面具作者的文章对于zygisk的介绍
Zygisk是Zygote的Magisk。这将在Zygote进程中运行Magisk的一部分,使Magisk模块更强大。这也是Magisk"退出舞台"理念中非常重要的一部分。当某一个进程位于上述拒绝列表中时,Magisk 将清理该过程的内存空间,以确保不会应用任何修改(P.S.1)。当然,Zygisk 仍然是 WIP(开发中)的,一旦实施准备好测试,会公布更多细节。
在magisk上有一行说明:systemless root
那么这个systemless是什么东西
在了解systemless之前我们还要了解什么是root以及如何获得root
下面是来自网络的root解释,年代已久不过我感觉还是有用的。
root权限就是root(管理员权限)用户的权限,该权限可以修改根目录下的文件
为了让我们的应用使用root权限
首先我们需要一个处理root请求的 su 进程
我们链接手机到电脑 输入adb shell
再输入 su 如果没root就会提示 su文件找不到
ok 既然没有这个文件那我们就push这个su执行文件到
/system/bin 下面吧
不行,因为你没有root权限所以不能向system传输文件
同样的因为你不能传输文件也就不能植入su 应用程序
也就是没法让你获得root权限 这就是死循环
这个不细说了
利用系统漏洞提权注入。这个方式很多,早期版本的系统用的多。现在系统越来越安全基本难以实现。
定制内核修改system分区的方式。
厂商会定制开发版本自带root权限。在于本身ASOP就支持userdebug版本模式去编译的。
之前的root会对system目录做文件修改
而systemless root 则不会对system目录做任何修改
这是为了应对高版本的系统的检测
基于systemless的root就是 systemless root
magisk 是实现 systemless root 的一个方式,实际上在magisk之前就有systemless root。只不过magisk把这个发扬光大了。
在之前做过magisk的分析,我把答案抄过来。
不难得出核心在于针对boot.img文件的修改
那么修改的patch_boot.img具体做了什么是我们最关心的
开机 打开面具的日志这里
可以看到这里在
/sbin/.magisk/mirror
下面建立了一个系统根目录的镜像目录
我们打开文件的时候就会发现 sbin 里面还拥有一个su执行文件和模块插件等其他文件
然后进行 bind mounted 操作,也就是让这个文件系统生效。
这时候ps -A其实就可以看到 su 进程,也就有了授权root的能力。
接下来就可以用magisk来管理root权限,请求root的都会出现在超级用户
这个列表里。
同时基于 bind mount 可以针对系统文件进行替换以及在这里执行sh脚本,这就是我们写的magisk模块的实现了。
非常多的细节可以在https://topjohnwu.github.io/Magisk/details.html 里面得到,或许我的理解会有误差。
在了解zygisk之前,先了解magisk的功能实现原理。我这里分析zygisk关于注入Zygote的逻辑。
在分析之前我就在猜想他的实现原理了。
xposed注入Zygote原理是替换 app_process,而magisk可以做到替换系统文件。那么magisk是不是可以替换app_process来注入Zygote。
虽然zygisk是新一点东西 好在已经有人分析过了。可以踩在巨人的肩上了。
在magisk仓库里面搜索 app_process
果然找到了相关代码
打开main.cpp看到一行注释
// Entrypoint for app_process overlay
确认无疑了,对app_process进行了替换
Zygisk 源码分析 实际上这篇文章已经写的非常详细了,我加上了一点自己的理解。算是拾人牙慧了。
先总结一下整个流程
搜索 app_process
出现最多的就是这个module.cpp文件
打开文件看到bind_mount
就知道这个类对文件进行了挂载。
对app_process
进行处理的函数在magic_mount
中
mount是Linux下的一个命令,它可以将分区挂接到Linux的一个文件夹下,从而将分区和该目录联系起来,因此我们只要访问这个文件夹,就相当于访问该分区了。
新建文件夹后mount_zygisk
处理挂载文件夹
两件事:文件移动和文件夹挂载
app_process 32/64 放到了zygisk下面
magisk 32/64 放到了 MAGISKTMP
下面
完成文件的app_process
到magisk
的替换
做完这些之后,我们重启手机启动运行的app_process
其实就是运行magisk
我们其实可以看到这些文件的
这部分核心研究跑起来的magisk跑起来之后具体做了什么
包括hook的实现逻辑
运行了magisk文件,现在进入他的函数分析他的逻辑。
Entrypoint for app_process overlay
对着这个注释往下看
通过socker通信设置几个变量的值 LD_PRELOAD INJECT_ENV_1
MAGISKTMP_ENV
ZygiskRequest::SETUP
是通信的标志
这里非常核心的一个就是 LD_PRELOAD 变量的值设置,这将作用到后面的注入
LD_PRELOAD是Linux系统的一个环境变量,它可以影响程序的运行时的链接(Runtime linker),它允许你定义在程序运行前优先加载的动态链接库。
找到消息接收的地方
buf 获取了可执行路径
sendfd 发送持有的真正的 app_process 文件 fd
write_string 发送 MAGISKTMP 路径
到这里我开始发现与参考文件不同的地方了
尤其是
根本对不上,zygisk下面也没有对应的so文件
那就是改版了,下面就自己分析新版zygisk的原理吧
zyg_init函数
这里进行两阶段的加载操作
判断INJECT_ENV_1
进行一阶段加载 这个在 app_process_main
进行设置的
在一阶段加载加载完成阶段设置二阶段标志 INJECT_ENV_2
下面分析两个阶段的事情
一阶段:好在作者加了大段注释 ,我谷歌翻译一遍
在这里我发现 LD_PRELOAD 是个非常重要的变量
修改这个值就可以加载我们的注入的程序
这里一阶段就是来加载 LD_PRELOAD
的文件
这个文件就是之前 app_process_main
设置的
获取fd的值这里最终将这个值写入到 MAGISKFD_ENV
中
同时进行第一次的 android_dlopen_ext
获取MAGISKFD_ENV
的值进行 path
进入 android_dlopen_ext
再一次 dlopen 并立马关闭
恢复 变量 MAGISKTMP_ENV
MAGISKFD_ENV
在结束的时候,调用了
sanitize_environ
字面意思就是 消毒环境。就是用于对抗检测的,消灭证据。具体实现这里不是重点。
hook_functions
具体的hook实现部分
我们已经将自己的文件注入进去,现在要实现hook
核心的hook_functions 处于这个类
我们核心关注XHOOK_REGISTER(ANDROID_RUNTIME, jniRegisterNativeMethods);
这部分的逻辑
在之前的riru分析中,我们已经了解过这种hook的实现方法。基于xhook,对register方法进行hook后做个指针的切换。
几个重要的宏定义
XHOOK_REGISTER
宏
使用 xhook register
DCL_HOOK_FUNC
宏
对函数进行hook
DCL_PRE_POST
宏
定义函数的per和post两种
比如 fork定义了 fork_pre 和 fork_post
挑一对 pre和post来分析
可以发现核心就是两个
run_modules_pre(module_fds);
run_modules_post();
也就是运行modules插入的hook代码
这个两个方法需要记得后面继续分析。
执行hook操作的方法 核心的hook逻辑
三个函数的hook
这三个函数是app进程启动的Zygote中三个相关函数,是应用进程或者系统服务进程被fork 出来的时候会调用的方法。
实现hook后引入
实现具体hook的地方,在这里区分了版本和手机类型。将新旧方法做了保存和指针更换处理。
比如这个就是安卓Q版本的hook处理逻辑,这里有个重要的HookContext
结构体。
核心的三句
ctx.nativeSpecializeAppProcess_pre();
reinterpret_cast<decltype(&nativeSpecializeAppProcess_q)>(nativeSpecializeAppProcess_orig)( env, clazz, uid, gid, gids, runtime_flags, rlimits, mount_external, se_info, nice_name,
is_child_zygote, instruction_set, app_data_dir);
ctx.nativeSpecializeAppProcess_post();
pre
和post
调用用于执行插入的hook code。
而中间那句就是执行原方法orgin
分析到这里差不多,未完待续。后面还有关于如何zygisk屏蔽应用以及如何load moudules 代码的有时间再说。
参考
Zygisk 源码分析
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2022-4-13 16:02
被小黄鸭爱学习编辑
,原因: 勘误