muhammadrizwan87/frida-bridge

GitHub: muhammadrizwan87/frida-bridge

一个无需 root 和 APK 重打包即可在 Android 容器/虚拟空间中加载 Frida Gadget 的原生 JNI 桥接库。

Stars: 14 | Forks: 7

# Frida Bridge ## 📖 概述 frida-bridge 是一个原生的 JNI 库,只需最少的配置即可将 Frida Gadget 加载到宿主 Android 进程中。它会自动解析磁盘上的真实路径——包括在重新映射文件系统的容器中——等待 Android Runtime 可用,并将 gadget 的配置和脚本文件准确放置在 Frida 预期的位置。 无需 root,无需重打包目标 APK。 只需两步,您就可以让任何容器/虚拟空间支持 Frida 模式。 ## 📋 目录 1. [特殊优势](#-1-special-advantages) 2. [Gadget 文件与目录布局](#-2-gadget-files--directory-layout) 3. [延迟配置](#%EF%B8%8F-3-delay-configuration) 4. [使用指南](#-4-usage-guide) 5. [安全视角](#%EF%B8%8F-5-security-perspective) 6. [故障排除](#-6-troubleshooting) ## 🚀 1. 特殊优势 ## 📁 2. Gadget 文件与目录布局 所有文件均位于 `/frida/` 下: | 文件 | 用途 | |---|---| | `libfrida-gadget.so` | Frida Gadget 共享库(由您提供) | | `libfrida-gadget.config.so` | Gadget 配置 JSON —— 由 bridge 自动管理 | | `libfrida-gadget.script.so` | 编译后的 JS agent(由您提供,用于脚本模式) | | `frida-bridge.cfg` | Bridge 配置 —— 目前支持 `delay=` | **自动路径解析** 无论您在配置的 `"path"` 字段中填入什么内容(绝对、相对、真实或逻辑路径),bridge 都会在运行时对其进行修复。它会将脚本文件复制到真实的 gadget 目录中,并将 `"path"` 重写为单纯的文件名 `libfrida-gadget.script.so`。这保证了 gadget 始终能找到脚本,即使文件系统被容器重新映射也是如此。 ## ⏱️ 3. 延迟配置 在相同的 `frida/` 目录中创建 `frida-bridge.cfg`: ``` delay=3 ``` | 值 | 行为 | |---|---| | 缺省 / `0`(默认) | 无额外延迟。一旦 `Application` 准备就绪,Gadget 就会加载。 | | `1`–`60` | 在 `Application` 准备就绪后,Bridge 会休眠相应的秒数,然后再加载 gadget。 | 当您的脚本需要宿主应用先完成其自身的初始化(例如特定的 `Activity` 或 `Service`),然后再激活 hook 时,此功能非常有用。 ## 💡 4. 使用指南 ### 📝 前置条件 - Android NDK(用于原生编译) - Termux app(用于在设备上构建),或桌面工具链 ### 🛠️ 构建说明 ``` # Clone the repository git clone https://github.com/muhammadrizwan87/frida-bridge.git cd frida-bridge # 设置 NDK path export NDK_HOME=/path/to/your/ndk # export NDK_HOME=/data/data/com.termux/files/home/android-sdk/ndk/24.0.8215888 # Build for all architectures $NDK_HOME/ndk-build NDK_PROJECT_PATH=. NDK_APPLICATION_MK=./jni/Application.mk # Output will be in libs/ ls libs/ # armeabi-v7a/ arm64-v8a/ x86/ x86_64/ ``` ### 🚩 构建标志 | 标志 | 效果 | |---|---| | (无,默认) | Release 构建 —— 仅输出 `LOGI`/`LOGW`/`LOGE` | | `-DFRIDA_BRIDGE_DEBUG` | 详细的 `LOGD` 输出:maps 转储、真实目录列表、JNI 等待进度 | 通过在 `jni/Android.mk` 中取消注释相应行来启用。 ### 🔀 实施说明 **📌 重要提示:** 本节是对独立的容器 APK 进行补丁操作,而不是针对目标 app。目标 app 的完整性和代码保持 100% 不变。如果您是直接将其集成到自己的容器源代码中,请跳至选项 B。 #### 选项 A:补丁现有的容器 APK (Smali) 确保在容器自定义 Application 子类的类初始化器中加载原生库 ``` .method static constructor ()V .registers 1 const-string v0, "frida-bridge" invoke-static {v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V return-void .end method ``` 为每种架构添加 `lib//libfrida-bridge.so`,并按照第 2 节的说明将 gadget 文件放在 `files/frida/` 下。 #### 选项 B:集成到您自己的容器项目中 ``` public class MyApp extends Application { static { System.loadLibrary("frida-bridge"); } } ``` ``` android { sourceSets { main { jniLibs.srcDirs = ['libs'] } } } ``` ## 🛡️ 5. 安全视角 ### 🔑 本库可以访问的内容 该库**完全在宿主进程现有的安全边界内**运作。它: - ✅ 读取 `/proc/self/maps` 和 `/proc/self/cmdline` —— 系统设计上允许每个进程访问 - ✅ 在 app 自己的文件目录内进行读写 —— 这是进程已经拥有的存储空间 - ✅ 使用 app 自己的 `JavaVM` 进行 JNI 调用 —— 标准的 Android API - ✅ 对由集成者提供的、已存在于磁盘上的库文件调用 `dlopen()` **不会发起任何 app 自身无法发起的系统调用。** ### ❎ 本库不会执行的操作 - ❌ 不提升权限 - ❌ 不自行通过网络进行通信 - ❌ 不访问其他 app 的数据 - ❌ 不下载或获取 gadget 二进制文件 —— 必须在本地提供 - ❌ 不请求额外的 Android 权限 ### 🏛️ 策略合规 该库作为宿主 app 自身进程的一部分加载,运行于 app 的 UID 下,并完全在 Android 标准的应用沙箱内运作。 ## 🔧 6. 故障排除 ### 🪵 首先查看日志 大多数问题都可以通过 `logcat` 进行诊断。过滤标签 `FridaBridge`。 一次正常的运行会显示以下序列: ``` I/FridaBridge: Bridge started I/FridaBridge: Files dir: /data/… I/FridaBridge: ART detected via maps: … I/FridaBridge: Gadget loaded I/FridaBridge: Bridge done ``` 如果您看到 `Gadget loaded` 和 `Bridge done`,**说明 bridge 本身正在工作** —— 问题出在 gadget 配置、脚本或环境上。 ### ❗ 脚本未生效? - **脚本质量**:导致静默失败的最常见原因是脚本本身的错误——调用了缺失的方法、使用了已被移除的 API,或者是在应用 hook 之前就导致 agent 崩溃的逻辑错误。请在非容器环境(真机/模拟器)中测试脚本,以确认其可以独立运行。 - **脚本编译**:如果您的脚本需要编译,请使用 `frida-compile` 并确保输出的文件名为 `libfrida-gadget.script.so`。 - **配置模式**:bridge 会重写 `"path"` 字段;请验证配置的其余部分(尤其是 `"interaction"` 块)是否正确。 - **二次启动行为**:在首次启动(或清除 app 数据后),bridge 会在 gadget 初始化*之后*将配置和脚本复制到真实路径。gadget 仅在**下一次**启动时才会读取它们。请运行 app 两次 —— 第二次运行应该就能生效了。 - **时序/ hook 缺失**:如果某些 hook 未触发,请增加 `frida-bridge.cfg` 中的 `delay` 值。这为 app 提供了更多时间,以便在脚本运行之前到达目标代码。 ### 🧪 提交 Issue 前的检查事项 - 提供从 `Bridge started` 到 `Bridge done` 的完整 `logcat`(或者至少是相关的 `FridaBridge` 行)。 - 注明 Frida Gadget 版本、Android 版本,以及您是否处于容器/VM 环境中。 - 尝试在非容器环境中进行相同的设置,以排查问题原因。
标签:Android, Docker支持, DSL, Frida, UML, 云资产清单, 客户端加密, 目录枚举, 移动安全, 逆向工程