Xposed
介绍
xp是一种针对 Android 系统的模块化框架,通过模块的方式修改应用程序的行为,主要通过修改 Android 系统的运行时环境来实现动态插桩。
xp注入机制
Xposed 的注入是通过修改 Android 系统的 Zygote 进程实现的
Zygote 是 Android 系统中所有应用程序进程的父进程
工作原理:
Xposed 在系统启动时修改 /system/bin/app_process 文件,将其替换为自己的版本,使其加载Xposed的核心模块
XposedBridge.jar
当 Zygote 进程启动时,会加载 Xposed 框架
所有从 Zygote fork 出来的应用进程都会包含 Xposed 框架
Xposed 通过修改 ART/Dalvik 虚拟机,实现了对 Java 方法的 hook
特点
需要 ROOT 权限
系统级别的注入,稳定性好
只能 hook Java 层代码
需要重启设备才能生效
EdXposed
EdXposed 是一款基于 Xposed 框架的增强工具,基于Riru框架开发,使用 yahfa (Yet Another Hook Framework for ART) 和 SandHook 作为 Hook 框架,它的出现是为了解决 Xposed 在 ART 环境下的兼容性问题。
注入方式:在 Android 系统启动时,所有应用进程均由 Zygote 进程 fork 而来。EdXposed 通过注入 Zygote 进程,确保所有应用进程都能加载 EdXposed 的功能。
LSPosed
注入机制的改进
采用 Riru/Zygisk 作为注入框架
不需要修改系统文件
支持 Zygote 重启生效(软重启)
通过 Magisk 模块方式安装,更加安全和灵活
兼容性改进
完整支持 Android 8.0-14
适配了 Android Runtime (ART)
支持 64 位架构
对各种定制 ROM 有更好的兼容性
Zygisk
介绍
Zygisk 是 Magisk 的一个模块
运行在 Zygote 进程中
提供了一个在 Zygote 进程中注入代码的框架
是 Riru 的继任者
工作原理
注入原理:Zygisk加载是通过替换app_process,修改LD_PRELOAD,再执行原app_process实现的,用LD_PRELOAD注入的。
启动流程:
- Magisk 守护进程启动
- Zygisk 模块加载
- 注入到 Zygote 进程
- 子进程继承注入代码
- 模块在应用进程中执行
Frida
介绍
Frida 是一个动态二进制插桩工具,可以在程序运行时向目标进程注入自定义的代码,修改程序的行为来获取信息。
frida注入机制
Frida 主要通过 ptrace 系统调用实现注入
工作原理
使用 ptrace attach 到目标进程
在目标进程中注入一个动态链接库(frida-agent.so)
通过修改进程内存和寄存器状态,实现代码执行
建立与注入进程的通信通道
具体步骤
- 使用 ptrace 附加到目标进程
- 暂停目标进程的执行
- 在目标进程中分配内存空间
- 写入 loader 代码
- 修改寄存器状态,使进程执行注入的代码
- 加载 frida-agent
特点
支持 Native 层和 Java 层的 hook
动态注入,不需要重启设备
跨平台支持(iOS、Android、Windows 等)
提供了强大的 JavaScript 脚本引擎
可以实时调试和修改
注入进程的两种方式
attach
附加到已有进程
1 | 步骤1: 进程附加 |
spawn
创建进程,在进程初始化之前进行注入
1 | 步骤1: 创建进程 |
Frida核心组件
Frida-core(核心引擎)
功能职责
提供核心注入引擎
管理进程间通信
处理跨平台兼容
提供底层 API 接口
主要模块
gum:底层指令插桩引擎
gumjs:JavaScript 绑定层
gumpp:C++ 绑定层
内存管理模块
进程控制模块
Frida-server(服务端)
基本功能
运行在目标设备上
监听来自客户端的连接
执行进程注入操作
管理注入的 agents
工作流程
1. 启动并监听端口(默认 27042)
2. 接收客户端连接请求
3. 处理注入命令
4. 管理目标进程
5. 转发通信数据
Frida-agent(注入模块)
核心功能
运行在目标进程内
执行 JavaScript 代码
提供 API 接口
处理 Hook 操作
主要组件
- JavaScript 引擎
- Native Bridge
- Hook 引擎
- 内存操作接口
工作机制
1. 被注入到目标进程
2. 初始化 JavaScript 运行环境
3. 加载用户脚本
4. 执行 Hook 操作
5. 与 frida-server 通信
Frida-client(客户端)
主要功能
连接 frida-server
发送控制命令
管理脚本执行
处理返回数据
工具集
- frida-cli:交互式命令行
- frida-ps:进程管理
- frida-trace:函数追踪
- frida-discover:API 发现
javahook
hook java要借助libart.so
frida hook java的时候会修改ArtMethod::PrettyMethod,在内存中检测该字段是否一致即可判断是否被hook了。
inlinehook原理
Inline hook的核心思想是在目标函数的入口处覆盖写入跳转指令,将执行流程重定向到我们的hook处理函数。
备份原始指令
在修改目标函数前,Frida会先保存目标函数开头的若干字节的原始指令
保存的长度必须足够放置一个跳转指令(比如x86上至少5字节,ARM上至少8字节)
覆盖写入跳转指令
- 在目标函数开头写入跳转指令(JMP/B),指向我们的hook处理函数
检测
inline hook实现会修改.text段内容,crc32比较对比。
Xp与Frida
主要区别
注入时机:
Xposed:系统启动时,通过修改 Zygote进行注入
Frida:运行时,通过 ptrace 动态注入
作用范围:
Xposed:全局性,影响所有应用
Frida:可以针对特定进程进行注入
功能范围:
Xposed:主要针对 Java 层
Frida:同时支持 Native 层和 Java 层
使用场景:
Xposed:适合需要持久化修改的场景
Frida:适合动态调试和分析的场景
安全性考虑
Xposed 需要修改系统文件,风险较大
Frida 的 ptrace 注入可能被一些应用的反调试机制检测到
两种方式都可能被应用的完整性校验机制发现
这两种注入技术各有优势,在实际应用中可以根据具体需求选择:
如果需要持久化的系统级修改,选择 Xposed
如果需要灵活的动态分析和调试,选择 Frida
Android系统启动流程
App启动流程
加解密
抓包
混淆
改机
改机ROM
一般都是定制ROM实现改机效果,但是改机操作一般需要借助manager app,一般检测这个为主,其次会配合大数据筛选系统中特定的文件,诸如framework、libc.so等md5值。
收集设备型号、品牌、android版本、内核版本、内核libc文件md5值,收集后交由后端做数据模型分析。
软改机
一般是xposed插件Hook实现改机效果,所以检测xposed相关信息,以及相应的模块名,并且需要结合Java API返回值与native 获取相应值进行比对。