ykus4/fuin

GitHub: ykus4/fuin

fuin 是一款基于 Web UI、REST API 和 CLI 操作的 Android APK 加固工具,通过 AES-256-GCM 加密字节码和资源来抵御逆向工程与应用篡改。

Stars: 0 | Forks: 1

fuin logo **Android APK Packer — 保护字节码,阻断作弊,抵御逆向工程** [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) [![Python](https://img.shields.io/badge/Python-3.12%2B-blue?logo=python&logoColor=white)](https://www.python.org/) [![Docker](https://img.shields.io/badge/Docker-ready-2496ED?logo=docker&logoColor=white)](https://hub.docker.com/) [![CI](https://static.pigsec.cn/wp-content/uploads/repos/cas/ad/ad5834178f7599af9fdda11629d49cae07f2997beec49821b2920eff5bfd50e7.svg)](https://github.com/ykus4/fuin/actions/workflows/ci.yml) 保护任何 Android APK — Unity、Flutter 或标准应用 — 抵御作弊、盗版和逆向工程。 DEX 字节码、原生库(.so)和资源使用 AES-256-GCM 加密。 防篡改、root 检测和模拟器拦截防御 Frida 和 Xposed 等运行时 instrumentation 工具。 无需修改源码。运行时无需网络。完全离线运行。
## 打包时 fuin 通过 Web UI、REST API 或 CLI 对您的 APK 进行一次性处理。原始 APK 绝不会被原地修改;而是生成一个全新的受保护 APK。 ``` ┌─────────────────────────────────────────────────────────────────┐ │ 📦 PACK TIME (server or CLI) │ │ │ │ your.apk │ │ │ │ │ ├─ 📝 1. Patch AndroidManifest.xml (binary AXML) │ │ │ android:name → com.fuin.stub.StubApplication │ │ │ │ │ ├─ 🔐 2. Encrypt classes.dex (AES-256-GCM) │ │ │ key = os.urandom(32) ← 256-bit, fresh each run│ │ │ nonce = os.urandom(12) ← 96-bit │ │ │ output = nonce ‖ ciphertext ‖ GCM tag (16B) │ │ │ │ │ ├─ 🛡️ 3. Additional protections │ │ │ native libs (.so) → encrypted │ │ │ user assets → encrypted │ │ │ DEX strings → XOR obfuscated (opt-in) │ │ │ cert fingerprint → embedded (anti-tamper) │ │ │ security policy → root/emulator detection │ │ │ │ │ ├─ 🔧 4. Rebuild APK │ │ │ classes.dex ← stub DEX only │ │ │ assets/encrypted.dex ← ciphertext │ │ │ assets/key.bin ← AES key │ │ │ assets/cert_fingerprint.bin ← anti-tamper │ │ │ assets/encrypted_libs/* ← native libs │ │ │ assets/encrypted_res/* ← user assets │ │ │ assets/security_policy.json ← runtime policy │ │ │ │ │ └─ ✅ 5. zipalign → apksigner → report │ │ │ │ 🔒 protected.apk (no plaintext bytecode — only ciphertext) │ └─────────────────────────────────────────────────────────────────┘ ``` ## 运行时 当应用在最终用户设备上启动时,stub 会在内存中静默解密原始字节码 — 无网络调用,无可见延迟。 ``` ┌─────────────────────────────────────────────────────────────────┐ │ 📱 RUNTIME (on-device, no network required) │ │ │ │ StubApplication.attachBaseContext() │ │ │ │ │ ├─ 🛡️ IntegrityCheck — verify APK signing cert │ │ │ │ │ ├─ 🛡️ SecurityCheck — root / emulator detection │ │ │ │ │ ├─ 📖 Read assets/key.bin + assets/encrypted.dex │ │ │ │ │ ├─ 🔧 NativeLibDecryptor — decrypt .so files │ │ │ │ │ ├─ 🔧 DecryptingAssetManager — decrypt user assets │ │ │ │ │ ├─ 🔓 AES-256-GCM decrypt → plaintext DEX │ │ │ written to codeCacheDir (chmod 0600) │ │ │ │ │ ├─ 🔤 StringDecryptor — de-obfuscate DEX strings │ │ │ │ │ ├─ ⚙️ DexClassLoader loads original classes │ │ │ │ │ └─ 🔄 ApplicationSwap (reflection-based hot-swap) │ │ stub Application → original Application │ │ │ │ 🚀 original Application.onCreate() → normal app launch │ └─────────────────────────────────────────────────────────────────┘ ``` ## 演示 ![fuin 演示](https://raw.githubusercontent.com/ykus4/fuin/main/docs/demo.gif) ## 功能特性 ### 反作弊与保护 | | | |---|---| | 🔐 **抗静态分析** | APK 仅包含密文 — 反编译器(jadx、apktool)无法看到任何可运行的字节码 | | 🛡️ **防篡改** | 运行时验证签名证书 — 重新签名或修补过的 APK 拒绝运行 | | 🚫 **root 检测** | 阻止在已 root 的设备上执行 — 击败基于 Magisk 的作弊工具 | | 📵 **模拟器检测** | 阻止在模拟器上运行 — 拦截机器人农场和自动化漏洞测试 | | 🔌 **抗 Frida/Xposed** | root + 模拟器检查提高了对抗动态 instrumentation 框架的门槛 | | 📦 **原生库加密** | 加密 .so 文件(Unity/Unreal 游戏引擎、自定义 C++ 库)— 阻断二进制分析 | | 🗂️ **资源加密** | 游戏配置、关卡数据、数据库在静态存储时加密 — 抵御资源提取 | | 🔤 **字符串混淆** | DEX 字符串常量进行 XOR 加密 — 抵御 `strings` 转储和配置收集 | | 🎮 **支持 Unity 与 Flutter** | 开箱即用地支持 Unity `.so` 库和 Flutter 引擎 — 无需额外配置 | ### 开发者体验 | | | |---|---| | 📴 **完全离线** | 密钥内嵌于 APK 中 — 启动时无网络调用,无外部依赖 | | 🌐 **Web UI + REST API** | 通过浏览器或 `curl` 上传,即时下载受保护的 APK | | ⚡ **支持 CLI** | 使用 `fuin-pack` 实现单条命令本地打包 | | 🐳 **Docker 优先** | 无需本地 Android SDK — 一切均在镜像中运行 | | 🔄 **SSE 进度** | 实时打包进度推流至浏览器 | | 📊 **打包报告** | 显示体积变化、加密目标和元数据的对比报告 | | 🔌 **Gradle 插件** | 在 `assembleRelease` 后通过一个 DSL 块自动打包 | | 🤖 **GitHub Actions** | 用于 CI/CD pipeline 的复合 action | ## 快速开始 ### Docker(推荐) ``` git clone https://github.com/ykus4/fuin.git && cd fuin cp .env.example .env # set FUIN_API_KEY to any secret string docker compose up --build ``` 打开 **http://localhost:8000**,将您的 APK 拖拽进去,即可完成。 ### 本地设置
展开查看本地设置 (macOS) ``` # Dependencies curl -LsSf https://astral.sh/uv/install.sh | sh brew install openjdk@17 # Android build-tools 34 (zipalign + apksigner) mkdir -p ~/android-sdk/build-tools curl -L "https://dl.google.com/android/repository/build-tools_r34-macosx.zip" \ -o /tmp/bt.zip unzip -q /tmp/bt.zip -d /tmp/bt && mv /tmp/bt/android-14 ~/android-sdk/build-tools/34.0.0 # 构建 stub DEX(一次性) cd stub && ./gradlew :app:assembleRelease && cd .. # 开始 uv sync cp .env.example .env # set FUIN_API_KEY uv run fuin-server ``` fuin 会自动从 `~/android-sdk/build-tools/` 发现工具 — 无需更改 `PATH`。
## 用法 ### Web UI 前往 `http://localhost:8000`: 1. 输入您的 API key → **保存** 2. 拖拽一个 `.apk` 3. 观看实时进度条 4. 点击 **下载打包后的 APK** ### REST API ``` # 上传并打包 JOB=$(curl -sX POST http://localhost:8000/pack \ -H "X-API-Key: $FUIN_API_KEY" \ -F "file=@MyApp.apk" | jq -r .job_id) # 流式传输进度 curl -N "http://localhost:8000/jobs/$JOB/stream?api_key=$FUIN_API_KEY" # 下载 curl -OJ http://localhost:8000/apps/{app_id}/download \ -H "X-API-Key: $FUIN_API_KEY" ``` ### CLI ``` # 基本用法 uv run fuin-pack pack input.apk output_protected.apk # 启用所有选项的完整保护 uv run fuin-pack pack input.apk output.apk \ --root-detection \ --emulator-detection \ --encrypt-strings \ --report # 禁用特定保护 uv run fuin-pack pack input.apk output.apk \ --no-native-encrypt \ --no-resource-encrypt ``` **CLI 标志:** | 标志 | 描述 | |------|-------------| | `--report` | 打印人类可读的打包对比报告 | | `--report-json` | 以 JSON 格式打印打包对比报告 | | `--root-detection` | 在运行时启用 root 检测 | | `--emulator-detection` | 在运行时启用模拟器检测 | | `--encrypt-strings` | 启用 DEX 字符串混淆 | | `--no-native-encrypt` | 禁用原生库(.so)加密 | | `--no-resource-encrypt` | 禁用资源加密 | | `--no-strict-manifest-patch` | 当 manifest 补丁无法验证时,允许尽力打包 | | `--verify-signature` | 在签名后运行 `apksigner verify` | | `--keystore` | 签名 keystore 路径 | | `--key-alias` | 密钥别名 | | `--store-pass` | Keystore 密码 | | `--key-pass` | 密钥密码 | ## Gradle 插件 只需一个 DSL 块即可将 fuin 保护添加到您的 Android 构建 pipeline 中。 ``` // settings.gradle.kts pluginManagement { includeBuild("path/to/fuin/gradle-plugin") } // app/build.gradle.kts plugins { id("com.fuin.packer") } fuin { enabled.set(true) // CLI mode (default) cliPath.set("/usr/local/bin/fuin-pack") // OR server mode // serverUrl.set("http://localhost:8000") // apiKey.set("your-api-key") // Signing keystore.set(file("release.keystore").absolutePath) keystoreAlias.set("release") keystorePassword.set(System.getenv("STORE_PASS")) keyPassword.set(System.getenv("KEY_PASS")) // Protection options rootDetection.set(true) emulatorDetection.set(true) encryptStrings.set(false) // opt-in (slight runtime overhead) encryptNativeLibs.set(true) // default: true encryptResources.set(true) // default: true } ``` 配置完成后,打包会在 `assembleRelease` 之后自动进行: ``` ./gradlew assembleRelease # → fuinPack runs automatically ``` ## GitHub Actions ``` - name: Pack APK with fuin uses: ykus4/fuin@main with: input-apk: app/build/outputs/apk/release/app-release.apk output-apk: app/build/outputs/apk/release/app-release-packed.apk keystore-base64: ${{ secrets.KEYSTORE_BASE64 }} keystore-alias: release keystore-password: ${{ secrets.STORE_PASS }} key-password: ${{ secrets.KEY_PASS }} root-detection: "true" emulator-detection: "true" encrypt-strings: "false" ``` ## API 参考 | 方法 | 路径 | 描述 | |--------|------|-------------| | `GET` | `/` | Web UI | | `POST` | `/analyze` | 分析 APK — 列出可加密的文件,但不进行打包 | | `POST` | `/pack` | 上传 APK → 异步任务 → `job_id` | | `GET` | `/jobs/{id}/stream` | SSE 进度 (`text/event-stream`) | | `GET` | `/jobs/{id}` | 轮询任务状态 | | `GET` | `/apps/{id}/download` | 下载受保护的 APK | | `POST` | `/apps/{id}/mapping/upload` | 上传 ProGuard mapping.txt | | `GET` | `/apps/{id}/mapping` | 下载 ProGuard mapping.txt | | `GET` | `/apps` | 列出所有已打包的应用 | | `DELETE` | `/apps/{id}` | 删除一个已打包的应用 | 除 `GET /` 外的所有 endpoint 都需要 `X-API-Key` 请求头(或对于 SSE 使用 `?api_key=`)。 **SSE 事件格式** ``` {"status": "running", "step": "encrypting_dex", "pct": 40} {"status": "done", "step": "done", "pct": 100, "result": {...}} {"status": "error", "step": "error", "pct": 0, "error": "..."} ``` ## 配置 将 `.env.example` 复制为 `.env`,并至少设置 `FUIN_API_KEY`。 | 变量 | 必填 | 默认值 | 描述 | |----------|----------|---------|-------------| | `FUIN_API_KEY` | **是** | — | 用于所有服务器 endpoint 的 API key | | `FUIN_KEYSTORE_PATH` | 否 | debug keystore | 签名 keystore 路径 | | `FUIN_KEYSTORE_ALIAS` | 否 | `fuin` | 密钥别名 | | `FUIN_KEYSTORE_STORE_PASS` | 否 | — | Keystore 密码 | | `FUIN_KEYSTORE_KEY_PASS` | 否 | — | 密钥密码 | | `FUIN_PACKED_DIR` | 否 | `./data/packed_apks` | 打包后 APK 的输出目录 | | `FUIN_DATABASE_URL` | 否 | `sqlite:///./data/fuin.db` | SQLAlchemy 数据库 URL | | `FUIN_STUB_DEX` | 否 | 自动检测 | 预构建的 `stub.dex` 路径 | | `FUIN_MAX_UPLOAD_MB` | 否 | `500` | 最大 APK 上传大小 (MB) | | `FUIN_CLEANUP_DAYS` | 否 | `30` | 自动删除超过 N 天的打包 APK(`0` = 关闭) | | `FUIN_WEBHOOK_URL` | 否 | — | 当打包任务完成时向此 URL 发送 POST 请求 | | `FUIN_ROOT_DETECTION` | 否 | `false` | 启用 root 检测(服务器 pipeline) | | `FUIN_EMULATOR_DETECTION` | 否 | `false` | 启用模拟器检测(服务器 pipeline) | | `FUIN_ENCRYPT_STRINGS` | 否 | `false` | 启用 DEX 字符串加密(服务器 pipeline) | | `FUIN_STRICT_MANIFEST_PATCH` | 否 | `true` | 如果 `StubApplication` 无法插入 manifest 则失败 | | `FUIN_VERIFY_SIGNATURE` | 否 | `false` | 在签名后运行 `apksigner verify` | ## 仓库结构 ``` fuin/ ├── fuin/ # Python package │ ├── config.py # Config (env vars / .env) │ ├── cli.py # fuin-pack CLI │ ├── crypto.py # AES-256-GCM │ ├── manifest.py # Binary AXML patcher │ ├── apk.py # APK repack + zipalign + apksigner │ ├── integrity.py # Anti-tamper: cert fingerprint extraction │ ├── native_lib.py # Native library (.so) encryption │ ├── resource_encrypt.py # Asset/resource encryption │ ├── string_encrypt.py # DEX string XOR obfuscation │ ├── report.py # Pack diff report generation │ ├── stub_dex.py # Stub DEX locator │ └── server/ # FastAPI server │ ├── main.py # HTTP endpoints (fuin-server) │ ├── pipeline.py # Pack pipeline │ ├── jobs.py # Async job store (SSE) │ ├── models.py # Pydantic response models │ └── static/index.html # Web UI ├── tests/ # pytest suite │ ├── conftest.py # Shared fixtures (minimal APK, AXML builder) │ ├── test_crypto.py # AES-256-GCM roundtrip + tamper detection │ ├── test_manifest.py # AXML patcher │ ├── test_apk.py # inject, zipalign │ ├── test_pipeline.py # End-to-end pack pipeline │ └── test_server.py # FastAPI endpoints ├── stub/ # Android stub (Kotlin, minSdk 24) │ └── app/src/main/java/com/fuin/stub/ │ ├── StubApplication.kt # Entry point: orchestrates all decryption │ ├── Crypto.kt # AES-256-GCM decryption │ ├── ApplicationSwap.kt # Reflection-based app hot-swap │ ├── IntegrityCheck.kt # Anti-tamper: cert verification │ ├── SecurityCheck.kt # Root/emulator detection │ ├── NativeLibDecryptor.kt # .so file decryption + lib path patching │ ├── DecryptingAssetManager.kt # Encrypted asset decryption │ └── StringDecryptor.kt # DEX string de-obfuscation ├── gradle-plugin/ # Gradle plugin for build integration │ ├── build.gradle.kts │ └── src/main/kotlin/com/fuin/gradle/ │ ├── FuinPlugin.kt # Plugin entry point │ ├── FuinExtension.kt # DSL configuration │ └── FuinPackTask.kt # Pack task implementation ├── action.yml # GitHub Actions composite action ├── assets/ │ └── stub.dex # pre-built stub DEX (committed) ├── .env.example ├── docker-compose.yml └── Dockerfile ``` ## 保护层 fuin 叠加了多个独立的保护层 — 击破其中一层并不会击破其他的: | 保护层 | 静态分析 | 作弊 / 篡改 | 逆向工程 | |-------|:-:|:-:|:-:| | DEX 加密 (AES-256-GCM) | ✅ 阻断 jadx/apktool | — | 减缓内存转储 | | 原生库加密 | ✅ 阻断 IDA/Ghidra | — | 减缓二进制分析 | | 资源加密 | ✅ 阻断资源提取 | — | 减缓配置收集 | | 字符串混淆 | ✅ 阻断 `strings` 转储 | — | 减缓常量收集 | | 防篡改(证书检查) | — | ✅ 阻断 APK 重打包 | ✅ 阻断修补与重新签名 | | root 检测 | — | ✅ 阻断 Magisk 作弊 | ✅ 阻断 Frida/Xposed | | 模拟器检测 | — | ✅ 阻断机器人农场 | ✅ 阻断自动化漏洞测试环境 | ## 安全说明 - AES 密钥存在于 APK 内部(`assets/key.bin`)。这足以防御**静态分析**,但对于拥有已 root 设备、能在运行时读取应用资源的顽固攻击者无效。 - 防篡改机制会验证签名证书,防止 APK 被重新签名和修改。 - root/模拟器检测为防范动态 instrumentation(Frida、Xposed)提供了基础防御。坚决的攻击者可以通过 Magisk Hide 或自定义 ROM 绕过这些防御。 - 字符串加密会增加每次字符串访问的开销 — 请有选择地将其用于敏感字符串。 - 发布构建请使用真实的签名 keystore(`FUIN_KEYSTORE_*`)。 - 二进制 AXML 修补程序(`fuin/manifest.py`)在无法确认 `StubApplication` 已插入时,默认会以失败关闭。若需更广泛的 manifest 重写支持,请考虑使用 [apktool](https://apktool.org/)。 - 有关确切的保护边界和推荐的发布设置,请参阅[威胁模型](docs/THREAT_MODEL.md)。 ## 许可证 [MIT](LICENSE) © 2026 yotti
标签:APK打包, JS文件枚举, Python, 代码加密, 后台面板检测, 安卓加固, 无后门, 移动应用开发, 请求拦截, 逆向工具, 防篡改