Magisk Zygisk Hook 项目使用文档
一、项目概述
本项目用于验证云手机的 Magisk 是否正常工作。包含两部分:
- hook-target-app:目标 APP,包含 Java 和 Native (C++) 两部分代码,提供被 Hook 的方法
- zygisk-module-sample:Zygisk 模块,注入目标 APP 进程,拦截并替换 native 方法的返回值
示例项目下载:magisk-zygisk-hook-sample.zip
二、项目结构
Magisk/
├── hook-target-app/ # 目标 APP(Android Studio 项目)
│ ├── app/src/main/java/ # Java 代码
│ │ └── com/example/hooktarget/
│ │ ├── MainActivity.java # 主界面,调用各种方法并显示结果
│ │ └── SecurityManager.java # 安全管理类,含 native 方法
│ └── app/src/main/jni/
│ └── native-lib.cpp # C++ 代码,实现 native 方法
│
└── zygisk-module-sample/ # Zygisk Hook 模块(ndk-build 项目)
├── src/
│ ├── main.cpp # 模块入口,Zygisk 生命周期处理
│ └── hook/
│ ├── java_hook.cpp # Java 层 Hook 实现
│ └── native_hook.cpp # Native 层 Hook 实现
└── module/ # Magisk 模块文件(module.prop 等)三、Hook 目标方法
| 类 | 方法 | 原始返回值 | Hook 后返回值 |
|---|---|---|---|
MainActivity | nativeEncrypt(String) | ENC[输入内容] | [HOOKED] encrypt intercepted |
MainActivity | nativeCheckLicense(String) | false | true |
SecurityManager | isPremium() | false | true |
SecurityManager | getDeviceToken(String) | TOKEN_用户ID_时间戳 | HOOKED_TOKEN_intercepted |
四、编译与打包
4.1 编译目标 APP
- 用 Android Studio 打开
hook-target-app/目录 - 等待 Gradle 同步完成
- 菜单 Build → Build Bundle(s) / APK(s) → Build APK(s)
- APK 输出路径:
hook-target-app/app/build/outputs/apk/debug/app-debug.apk
4.2 编译 Zygisk 模块
在解压后的项目根目录下执行(需已安装 Android NDK,并将 ndk-build 所在目录加入 PATH):
cd Magisk/zygisk-module-sample
ndk-build编译产物在 libs/ 目录下(按 ABI 分目录存放 libhook_module.so)。
4.3 打包 Magisk 模块 ZIP
模块 ZIP 需要包含以下结构:
hook_module.zip
├── module.prop # 模块描述文件
├── install.sh # 安装脚本
├── uninstall.sh # 卸载脚本
├── zygisk/
│ ├── arm64-v8a.so # 从 libs/arm64-v8a/libhook_module.so 复制
│ ├── armeabi-v7a.so # 从 libs/armeabi-v7a/libhook_module.so 复制
│ ├── x86.so # 从 libs/x86/libhook_module.so 复制
│ └── x86_64.so # 从 libs/x86_64/libhook_module.so 复制注意: ZIP 内 .sh 文件必须设置 Unix 权限 0755,其他文件 0644,否则 Magisk 会静默加载失败。
五、安装与使用
5.1 安装目标 APP
adb install -r hook-target-app/app/build/outputs/apk/debug/app-debug.apk安装后在桌面上找到 "HookTarget" 图标,打开即可看到方法调用结果。
5.2 安装 Zygisk 模块
将模块 ZIP 推送到设备:
bashadb push hook_module_v5.zip //sdcard/Download/注意:Git Bash 中
/sdcard需要写成//sdcard(双斜杠)打开 Magisk Manager APP
进入 模块 页面,此时显示 "No module installed":

点击 Install from storage(从本地安装):

选择
hook_module_v5.zip安装完成后 重启设备
5.3 卸载模块
在 Magisk Manager → 模块页面,找到对应模块,点击 卸载,重启设备。
六、验证方法
6.1 方法一:Logcat 日志(推荐)
这是最直接的验证方式。模块的 Hook 函数内置了日志打印,通过 logcat 过滤关键词即可判断。
操作步骤:
# 清空旧日志并开始实时监听
adb logcat -c && adb logcat | findstr /I "NativeHook JavaHook HookTargetNative"然后打开 hook-target-app,观察日志输出。
Hook 成功的标志:
日志中出现以下内容说明 Hook 生效:
I/JavaHook: [Java Hook][RegisterNatives] SecurityManager.isPremium()
I/JavaHook: [Java Hook] Returning: true (original: false)
I/JavaHook: [Java Hook][RegisterNatives] SecurityManager.getDeviceToken("user_1")
I/JavaHook: [Java Hook] Returning: HOOKED_TOKEN_intercepted
I/JavaHook: [Java Hook][RegisterNatives] nativeEncrypt("hello_world_1")
I/JavaHook: [Java Hook] Returning modified value: [HOOKED] encrypt intercepted
I/JavaHook: [Java Hook][RegisterNatives] nativeCheckLicense("ABCDEF-1")
I/JavaHook: [Java Hook] Returning: true (original: false)Hook 失败的标志:
如果看到 [Original] 开头的日志(来自 APP 本身的 native-lib),说明调用走的是原始方法:
I/HookTargetNative: [Original] SecurityManager.isPremium()
I/HookTargetNative: [Original] nativeEncrypt("hello_world_1")6.2 方法二:APP 界面观察
hook-target-app 界面上会实时显示各方法的返回值。
Hook 成功时界面应显示:
| 项目 | 显示内容 |
|---|---|
| isPremium | true |
| getDeviceToken | HOOKED_TOKEN_intercepted |
| nativeEncrypt | [HOOKED] encrypt intercepted |
| nativeCheckLicense | true |
Hook 失败时界面会显示:
| 项目 | 显示内容 |
|---|---|
| isPremium | false |
| getDeviceToken | TOKEN_user_N_1234567890(带时间戳) |
| nativeEncrypt | ENC[hello_world_N] |
| nativeCheckLicense | false |
6.3 方法三:对比法(最可靠)
分别在不装模块和装模块的情况下采集日志,对比差异。
# 第一步:不装模块,采集原始行为
adb logcat -c && adb logcat | findstr /I "HookTargetNative" > original.log
# 第二步:安装模块并重启,采集 Hook 后行为
adb logcat -c && adb logcat | findstr /I "JavaHook NativeHook" > hooked.log对比两个日志文件:
original.log应包含[Original]开头的日志hooked.log应包含[Java Hook]或[Native Hook]开头的日志- 两者不应同时出现
七、技术原理
7.1 Zygisk 注入流程
Magisk 启动 → 加载 Zygisk → 注入 Zygote 进程
↓
Zygote fork 出 APP 进程
↓
模块 onLoad() 被调用
↓
preAppSpecialize() — 判断是否为目标包名
↓
postAppSpecialize() — 启动后台线程安装 Hook
↓
后台线程:AttachCurrentThread → 获取 ClassLoader → 安装 Hook7.2 Hook 技术:RegisterNatives
本模块使用 JNI 的 RegisterNatives 机制替换 native 方法:
- 通过
ClassLoader.loadClass()加载目标类 - 调用
UnregisterNatives()取消原有的 native 方法注册 - 调用
RegisterNatives()重新注册,指向我们自己的函数
关键约束:
UnregisterNatives只能取消通过RegisterNatives手动注册的方法- JNI 命名约定(
Java_xxx_yyy)自动注册的方法无法被UnregisterNatives取消 - 因此目标 APP 的
SecurityManager使用了手动registerNatives()方式注册
7.3 为什么需要后台线程
postAppSpecialize() 执行时,APP 的 ClassLoader 尚未就绪。因此需要启动后台线程,轮询等待 ActivityThread 初始化完成后才能获取 ClassLoader 并加载目标类。
八、常见问题
Q1:模块安装后重启,APP 没有变化
- 检查 Magisk Manager 中模块是否已启用
- 检查 Zygisk 是否已开启(Magisk Manager → 设置 → Zygisk)
- 查看 logcat 中是否有
HookSample: Module loaded in Zygote日志
Q2:MainActivity 的 Hook 成功但 SecurityManager 失败
- 确认 APP 版本是否包含
SecurityManager.registerNatives()手动注册逻辑 - 查看 logcat 中
UnregisterNatives的返回值,-2表示方法是自动注册的,无法取消
Q3:logcat 中没有任何 Hook 相关日志
- 确认
adb logcat -c执行成功(清空了旧日志) - 确认 APP 包名是
com.example.hooktarget - 检查
findstr过滤条件是否正确(Windows 下没有grep命令)
Q4:Git Bash 中 adb push 报错找不到路径
- Git Bash 中
/sdcard会被解释为本地路径 - 需要使用双斜杠:
adb push file.zip //sdcard/Download/
九、DeviceSpoofLab 改机模块验证
9.1 模块简介
DeviceSpoofLab 是一个 Magisk 改机模块,用于伪造设备信息(机型、品牌、型号、Android 版本等),常用于:
- 隐私保护(隐藏真实设备信息)
- 应用兼容性测试(模拟不同设备)
- 绕过设备绑定限制
GitHub 仓库: https://github.com/yubunus/DeviceSpoofLab-Magisk
9.2 安装步骤
下载 DeviceSpoofLab 模块 ZIP 文件
推送到设备:
bashadb push DeviceSpoofLab-Magisk.zip //sdcard/Download/打开 Magisk Manager → 进入 模块 页面,此时显示 "No module installed":

点击 Install from storage(从本地安装):

选择
DeviceSpoofLab-Magisk.zip安装完成后 重启设备
9.3 配置改机参数
DeviceSpoofLab 通常通过配置文件或内置界面设置伪造的设备信息。常见配置项:
| 配置项 | 说明 | 示例值 |
|---|---|---|
ro.product.brand | 品牌 | Samsung |
ro.product.model | 型号 | SM-G9980 |
ro.product.name | 设备名 | p3s |
ro.build.display.id | 系统版本 | TP1A.220624.014 |
ro.build.version.release | Android 版本 | 13 |
ro.build.version.security_patch | 安全补丁日期 | 2023-08-01 |
配置方式(根据模块版本可能不同):
- 方式一:修改模块目录下的
config.prop文件 - 方式二:通过 Magisk Manager 中的模块设置界面
- 方式三:使用配套的 LSPosed 模块(DeviceSpoofLab-Hooks)进行更细粒度的控制
9.4 使用 DevCheck 验证改机是否生效
DevCheck 是一款专业的设备信息检测 APP,可以读取系统属性、硬件信息、传感器数据等,是验证改机效果的理想工具。
DevCheck 下载: https://play.google.com/store/apps/details?id=flar2.devcheck
验证步骤:
安装 DevCheck
bashadb install devcheck.apk打开 DevCheck,查看以下关键信息:
① 设备信息页面(Device)
- Brand(品牌):应显示伪造的品牌(如
Samsung) - Model(型号):应显示伪造的型号(如
SM-G9980) - Product(产品名):应显示伪造的产品名
- Device(设备代号):应显示伪造的设备代号
② 系统信息页面(System)
- Android Version(Android 版本):应显示伪造的版本(如
13) - Security Patch(安全补丁):应显示伪造的补丁日期
- Build ID(构建 ID):应显示伪造的构建 ID
③ 硬件信息页面(Hardware)
- CPU ABI:应保持不变(改机通常不修改 CPU 架构)
- Hardware(硬件平台):可能显示伪造值
- Brand(品牌):应显示伪造的品牌(如
对比验证
验证项 改机前(真实值) 改机后(伪造值) 判断标准 Brand OPPOSamsung不一致说明改机生效 Model CPH2325SM-G9980不一致说明改机生效 Android Version 1313(可能相同)需结合其他字段判断 Security Patch 2026-09-242023-08-01不一致说明改机生效
命令行验证(可选)
也可以通过 adb 命令快速检查系统属性:
# 查看品牌
adb shell getprop ro.product.brand
# 查看型号
adb shell getprop ro.product.model
# 查看 Android 版本
adb shell getprop ro.build.version.release
# 查看安全补丁日期
adb shell getprop ro.build.version.security_patch注意: 某些 APP 可能通过 JNI 层直接读取硬件信息,绕过系统属性。DeviceSpoofLab-Hooks(LSPosed 模块)可以 Hook 这些底层调用,实现更彻底的改机。
9.5 常见问题
Q1:DevCheck 显示的值没有变化
- 确认 DeviceSpoofLab 模块已启用并重启
- 检查配置文件是否正确
- 某些系统属性可能被多个来源覆盖,需要重启多次
Q2:部分 APP 仍然检测到真实设备
- 这些 APP 可能使用了更深层的检测(如读取
/sys/文件系统) - 需要配合 LSPosed 模块(DeviceSpoofLab-Hooks)进行 Java 层 Hook
- 或者使用更强大的改机方案(如 XPrivacyLua)
Q3:改机后某些 APP 闪退
- 某些 APP 会校验设备一致性(如品牌与型号不匹配)
- 确保配置的品牌、型号、设备代号是真实存在的组合
- 参考真实设备的 build.prop 配置
