Zygisk Next Module Sample

中文 English

中文版本

本仓库包含一个可构建的 Zygisk Next 模块示例项目。

运行 gradle task zipDebug 生成 debug 版本的 zip 或运行 installMagisk|KsuDebug 以安装模块。构建完成的模块 zip 包将输出到 module/release 目录下。

模块声明

一个 Zygisk Next 模块是一个合法的 Magisk 模块, 且具有 Zygisk Next 特有的声明文件,该文件必须被放置在 $MODDIR/zn_modules.txt 文件中, 其中 $MODDIR 是模块目录。

文件的每一行是一个 Zygisk Next 模块库和作用域声明,如下所示:

path=/path/of/program/to/inject path/to/znmodule_lib.so
name=name_of_program_to_inject path/to/znmodule_lib.so

其中,path 表示使用绝对路径的匹配方式,即绝对路径为给定值的程序将被注入; name 表示名字匹配,即名字为给定值的程序将被注入。

被注入的程序会被加载由路径 path/to/znmodule_lib.so 指向的动态链接库。如果动态库的路径是一个相对路径,则会被相对模块目录寻找,如果该路径是一个绝对路径, 则根据绝对路径寻找,无论是相对路径还是绝对路径,动态库的最终路径必须是自身模块目录下的文件,否则动态库不会被加载。

例如,如果需要注入模块目录下的 libmodule.so 到 adbd 进程中,则使用程序名字匹配的方式可以写作:

name=adbd libmodule.so

或者使用绝对路径匹配方式,其中 adbd 绝对路径为 /apex/com.android.adbd/bin/adbd

path=/apex/com.android.adbd/bin/adbd libmodule.so

模块作用范围

目前,Zygisk Next 模块可注入到满足以下要求的进程中:

  • 由 init 进程产生(fork-execve)的服务进程。
  • 程序是 ELF 格式的动态链接的可执行程序(即,不是 shell 脚本或静态链接程序)。
  • 启动晚于 post-fs-data 阶段(早于该阶段启动的无法被 Zygisk Next 拦截)。
  • 不是 zygote 。

可以使用 zygisk-ctl dump-zn -sa 命令观察 Zygisk Next 所知道的服务进程,这些服务进程一般可以注入。

模块 API (草案)

Zygisk Next 模块 API 目前仍在设计当中,具体内容请参见 zygisk_next_api.h

当前 API 版本为 1 ,提供 plt hook 和 inline hook 能力。

请注意:

  • 如需使用 inline hook ,请确保目标进程的 SELinux 域拥有 execmem 权限。可以借助 sepolicy.rule 来允许该权限。
  • 在目前的实现中,每个进程对一个地址的 inline hook 只能进行一次,因此多个模块可能无法 inline hook 同一个地址。

由于模块 API 仍处于草案阶段,在未来可能发生变化。我们期待模块开发者提出 API 的改进建议。

English version

This repository contains a buildable example project for Zygisk Next modules.

Run the Gradle task zipDebug to generate a debug version of the zip file, or run installMagisk|KsuDebug to install the module. The built module zip package will be output to the module/release directory.

Module Declaration

A Zygisk Next module is a valid Magisk module with a specific declaration file for Zygisk Next. This file must be placed in the $MODDIR/zn_modules.txt file, where $MODDIR represents the module directory.

Each line in the file represents a Zygisk Next module library and scope declaration, as shown below:

path=/path/of/program/to/inject path/to/znmodule_lib.so
name=name_of_program_to_inject path/to/znmodule_lib.so

Here, path represents matching by absolute path, meaning programs with the given absolute path will be injected, and name represents name matching, indicating programs with the given name will be injected.

The injected program will load the dynamic link library pointed to by the path path/to/znmodule_lib.so. If the path to the dynamic library is a relative path, it will be searched relative to the module directory. If the path is an absolute path, it will be searched according to the absolute path. In either case, the dynamic library must ultimately reside in the module directory for it to be loaded.

For example, if you need to inject the libmodule.so from the module directory into the adbd process, you can use name matching as follows:

name=adbd libmodule.so

Or you can use absolute path matching, where the absolute path for adbd is /apex/com.android.adbd/bin/adbd:

path=/apex/com.android.adbd/bin/adbd libmodule.so

Module Scope

Currently, Zygisk Next modules can be injected into processes that meet the following criteria:

  • Services processes generated by the init process (fork-execve).
  • Programs that are ELF format dynamically linked executables (i.e., not shell scripts or statically linked programs).
  • Started later than the post-fs-data stage (programs started before this stage cannot be intercepted by Zygisk Next).
  • Not zygote.

You can use the command zygisk-ctl dump-zn -sa to observe the service processes known to Zygisk Next that can generally be injected.

Module API (Draft)

The Zygisk Next module API is still under design. For specific details, please refer to zygisk_next_api.h.

The current API version is 1, providing the ability for PLT hook and inline hook.

Please note:

  • If you intend to use inline hook, ensure that the target process's SELinux domain has execmem permission. You can use sepolicy.rule to allow this permission.
  • In the current implementation, each process can only perform an inline hook once on an address, so multiple modules may not be able to inline hook the same address.

As the module API is still in the draft stage, it may undergo changes in the future. We welcome suggestions from module developers for improving the API.