构建Android系统级Frida-Gadget管理工具的全栈实践
在移动安全研究领域,Frida作为动态插桩的瑞士军刀,其系统级持久化方案一直是高阶玩家的核心需求。本文将彻底解析如何从AOSP底层改造到上层管理界面开发,打造一套完整的可视化Frida-Gadget管理系统。不同于常见的单点突破方案,我们采用"系统修改+管理应用"的协同架构,实现从底层注入到上层管控的完整闭环。
1. 系统层架构设计与实现
1.1 AOSP核心注入机制改造
在ActivityThread.handleBindApplication中植入的注入逻辑是整个系统的神经中枢。我们通过扩展标准的应用启动流程,在应用上下文初始化阶段插入动态检测逻辑:
// frameworks/base/core/java/android/app/ActivityThread.java public final class ActivityThread { private void handleBindApplication(AppBindData data) { // 原始初始化代码... String pkgName = data.appInfo.packageName; int uid = Process.myUid(); if (uid > 10000) { // 过滤系统进程 Persist.LOGD("检测到应用启动: " + pkgName); if (Persist.isEnablePersist(pkgName)) { Persist.doXiaojianbangPersist(appContext, pkgName); } } // 继续正常初始化流程... } }关键设计要点:
- 进程UID过滤:避免对系统关键进程造成干扰
- 线程安全:确保注入操作不会阻塞主线程
- 失败隔离:单个应用注入失败不应影响系统稳定性
1.2 持久化服务模块开发
Persist类作为系统服务核心,需要处理以下关键任务:
| 功能模块 | 实现方法 | 关键路径 |
|---|---|---|
| 配置检测 | isEnablePersist() | /data/system/xsettings/xiaojianbang/persist/[pkg] |
| 脚本管理 | copyJSFile() | 源JS → 应用私有目录 |
| 环境配置 | genGadgetConfig() | 生成JSON格式的Frida配置 |
| 库文件加载 | copySoFile() | 系统库目录 → 应用私有目录 |
配置文件采用JSON格式实现灵活扩展:
{ "interaction": { "type": "script", "path": "/data/data/[pkg]/files/config.js", "on_message": "callback_handler" } }1.3 系统目录权限规划
为确保安全隔离,需要精心设计文件系统权限结构:
/data/system/xsettings/xiaojianbang/ ├── persist/ # 持久化开关目录 │ └── [pkg]/ # 各应用独立子目录 │ └── xiaojianbang_persist # 启用标志文件 └── jscfg/ # 脚本配置目录 └── [pkg]/ └── config.js # 各应用的Hook脚本通过init.rc在启动阶段创建目录并设置权限:
# system/core/rootdir/init.rc mkdir /data/system/xsettings 0775 system system mkdir /data/system/xsettings/xiaojianbang 0775 system system chmod 0750 /data/system/xsettings/xiaojianbang2. 管理应用开发实战
2.1 系统权限获取方案
获取system权限有两种实现路径:
方案A:独立编译部署
- 在AndroidManifest中声明共享UID:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.xiaojianbang.manager" android:sharedUserId="android.uid.system"> - 使用平台签名密钥签名APK
- 通过
mmm命令单独编译后刷入系统镜像
方案B:整机系统集成
- 在
handheld_product.mk中添加模块:PRODUCT_PACKAGES += \ XiaojianbangManager - 实现完整的Android.mk构建脚本
2.2 核心功能模块实现
管理应用需要实现三大核心功能矩阵:
应用列表展示
- 使用
PackageManager.getInstalledPackages() - 过滤系统应用和当前管理应用自身
- 实时同步文件系统状态
- 使用
脚本管理引擎
public class ScriptManager { private static final String JS_DIR = "/data/system/xsettings/xiaojianbang/jscfg/"; public static void saveScript(String pkg, String script) { File dir = new File(JS_DIR + pkg); if (!dir.exists()) dir.mkdirs(); File config = new File(dir, "config.js"); try (FileWriter writer = new FileWriter(config)) { writer.write(script); } } }持久化开关控制
- 通过检查
/data/system/xsettings/xiaojianbang/persist/[pkg]目录存在性 - 采用文件观察者(FileObserver)实现实时状态同步
- 通过检查
2.3 安全防护机制
为防止未授权访问,需要实现以下防护措施:
Binder权限验证:
public class ManagerService extends Service { @Override public IBinder onBind(Intent intent) { if (Binder.getCallingUid() != Process.SYSTEM_UID) { throw new SecurityException("Unauthorized access"); } return mBinder; } }文件访问审计:
# 在init.rc中添加SELinux策略 seclabel u:r:system_app:s0 /data/system/xsettings/xiaojianbang
3. 系统集成与编译体系
3.1 模块化集成方案
将整个方案拆分为三个独立模块:
核心注入模块
- 位置:
frameworks/base/core/java/android/app/ - 依赖:
Persist.java工具类
- 位置:
资源部署模块
# build/make/target/product/handheld_system.mk PRODUCT_COPY_FILES += \ device/xiaojianbang/gadget/libfrida-gadget.so:system/lib/libxiaojianbang.so管理应用模块
- 标准APK结构
- 需要平台签名
3.2 自定义编译配置
针对Android 9的特殊处理:
白名单配置:
# build/make/core/tasks/check_boot_jars/package_whitelist.txt com\.xiaojianbang资源部署调整:
# build/make/target/product/sdk_base.mk PRODUCT_PACKAGES += \ libxiaojianbang
3.3 持续集成方案
建议采用以下CI流程:
- 代码审核 → 2. 模块编译 → 3. 系统镜像构建 → 4. 自动化测试
关键测试用例:
- 多应用并发注入测试
- 系统稳定性压力测试
- 权限边界测试
4. 高级功能扩展
4.1 脚本版本管理
实现多版本脚本共存与快速切换:
/data/system/xsettings/xiaojianbang/jscfg/[pkg]/ ├── v1.0/ │ └── config.js ├── v1.1/ │ └── config.js └── current -> v1.1 # 符号链接指向当前版本4.2 远程管理接口
通过Android的CommandReceiver实现远程控制:
public class AdminReceiver extends DeviceAdminReceiver { @Override public void onReceive(Context context, Intent intent) { String action = intent.getStringExtra("action"); if ("UPDATE_SCRIPT".equals(action)) { String pkg = intent.getStringExtra("package"); String script = intent.getStringExtra("script"); ScriptManager.saveScript(pkg, script); } } }4.3 性能优化策略
针对高频操作进行优化:
文件监控优化:
FileObserver observer = new FileObserver(JS_DIR, CLOSE_WRITE) { @Override public void onEvent(int event, String path) { // 使用延迟合并策略 handler.removeCallbacks(updateTask); handler.postDelayed(updateTask, 500); } };内存缓存策略:
private LruCache<String, Boolean> persistCache = new LruCache<>(20); // 缓存最近20个应用状态
在实际项目中,这种系统级方案需要特别注意兼容性测试。不同厂商的ROM可能会修改AOSP的启动流程,建议在Persist类中添加详细的日志记录功能,便于问题排查。