frida-mobile-security · diff
git:20260803.71f8be9 to git:20260804.8e42194
134 added, 608 removed. Audit C to A.
- # Frida Mobile Security Skill
+ ---
+ name: frida-mobile-security
+ description: 用于 Android/iOS 移动应用安全逆向分析:Frida 动态插桩、绕过反调试/反注入/加固壳、脱壳、加密与 native SO 层 hook、运行时行为分析、jadx-mcp 静态攻击面分析。用户提到"绕过检测/闪退/脱壳/加密/抓包/行为摸底/内存扫描/分析 so/检查证书"等意图时使用。
+ ---
- **模块优先,决策树驱动。** `scripts/` 下的可拼接模块覆盖 95% 的常规分析需求。面对问题时,先匹配决策树 → 按树加载模块 → 根据输出信号判断下一步。硬性规则:`utils.js` **必须**作为第一个 `-l` 参数加载。
+ # Frida Mobile Security — 逆向分析总控
+ **模块优先,决策树驱动。** 本文件是总控:任务路由 + 决策树导航 + 模块目录。各技巧域的详细打法在 `references/` 分域文件,按需读取。
+
+ **硬性规则:`scripts/core/utils.js` 必须作为第一个 `-l` 参数加载。**
+
---
## 快速命令卡片
```bash
# 加解密自吐
- frida -U -f com.app -l utils.js -l crypto_monitor.js
+ frida -U -f com.app -l scripts/core/utils.js -l scripts/monitors/crypto_monitor.js
# 行为摸底
- frida -U -f com.app -l utils.js -l file_monitor.js -l network_monitor.js -l thread_monitor.js
+ frida -U -f com.app -l scripts/core/utils.js -l scripts/monitors/file_monitor.js -l scripts/monitors/network_monitor.js -l scripts/monitors/thread_monitor.js
- # 反检测 (Phase 1: 保活 + 定位检测 so)
- frida -U -f com.app -l utils.js -l exit_blocker.js -l so_loader_tracer.js
+ # 反检测 Phase 1 (保活 + 定位检测 so)
+ frida -U -f com.app -l scripts/core/utils.js -l scripts/bypass/exit_blocker.js -l scripts/bypass/so_loader_tracer.js
# HTTP 明文拦截
- frida -U -f com.app -l utils.js -l ssl_plaintext.js
+ frida -U -f com.app -l scripts/core/utils.js -l scripts/monitors/ssl_plaintext.js
# Native 函数发现
- frida -U -f com.app -l utils.js -l native_hooker.js
+ frida -U -f com.app -l scripts/core/utils.js -l scripts/monitors/native_hooker.js
# 跨组件 Intent 污点追踪
- frida -U -f com.app -l utils.js -l intent_tracker.js
+ frida -U -f com.app -l scripts/core/utils.js -l scripts/monitors/intent_tracker.js
# 内存敏感数据扫描 + 密码输入监听
- frida -U -f com.app -l utils.js -l memory_scanner.js
-
- # 完整攻击链 (组件跳转 + 文件 + 网络)
- frida -U -f com.app -l utils.js -l intent_tracker.js -l file_monitor.js -l network_monitor.js
+ frida -U -f com.app -l scripts/core/utils.js -l scripts/monitors/memory_scanner.js
```
- 运行时配置通过 `-e 'var CONFIG_OVERRIDE={...}'` 注入,详见 §5。
+ 运行时配置通过 `-e 'var CONFIG_OVERRIDE={...}'` 注入,见 §五。
---
## 一、任务路由
- 匹配用户意图 → 跳转对应章节,不要逐章浏览。
+ 匹配用户意图 → 加载对应 references 分域 → 按决策树执行。**不要逐章浏览。**
- ### 1.1 前置判断:检测是否已绕过
+ | 意图关键词 | 手法域名 | 加载 |
+ |-----------|---------|------|
+ | "绕过检测" "过掉反调试" "挂上就闪退" "防注入" "加固壳" "SVC" "TracerPid" "GDB" | 环境对抗 | `references/anti-detection.md` |
+ | "脱壳" "加固解密" "提取 dex" "so 提取" | 脱壳 | `references/unpacking.md`(**默认 `scripts/utils/unpack.py` 一键跑;深挖/异常才用底层脚本**) |
+ | "加密明文" "算法" "密钥" "AES" "hook 方法" "修改参数" "伪造返回值" "SSL 证书" "TrustManager" "onReceivedSslError" | 加密/功能 hook | `references/crypto-hook.md` |
+ | "看网络请求" "抓包" "还原协议" "行为摸底" "全程监控" "污点追踪" "内存扫描" "Intent" "Serializable" | 行为分析 | `references/behavior-analysis.md` |
+ | "分析这个类" "攻击面" "序列化" "WebView" "深链" "Provider" "反序列化" | 静态分析 | `references/static-analysis.md` |
+ | "分析这个 so" "native 函数" "so 里的加密" "字符串引用" "交叉引用" "逆向 so" "找不到导出" | SO 层分析 | `references/native-analysis.md` |
+ | "模块无输出" "闪退" "ANR" "hook 不生效" "报错" | 故障诊断 | `references/troubleshooting.md` |
+ | "写自定义 hook" "API 用法" "Stalker" "RegisterNatives" "内存搜索" | API 参考 | `references/api-reference.md` |
+ ### 前置判断:检测是否已绕过
+
```
用户是否已能稳定挂载 Frida?
- ├─ [否] "挂上就闪退" → §四 反检测 Pipeline
- ├─ [是] 用了 hluda/魔改 frida/已跑过 exit_blocker → 跳过 §四,直接匹配下方任务
- └─ [不确定] → 快速探路:
- 模块: utils + exit_blocker + so_loader_tracer
+ ├─ [否] "挂上就闪退" → 加载 anti-detection.md
+ ├─ [是] 已用 hluda/魔改 frida/已跑过 exit_blocker → 跳过反检测,直接匹配任务
+ └─ [不确定] → 快速探路:utils + exit_blocker + so_loader_tracer
├─ exit_blocker 有 BLOCKED → 存在检测但已被保活 → 可继续
└─ exit_blocker 无日志且进程正常 → 无检测 → 可继续
```
- ### 1.2 意图 → 路径映射
-
- | 关键词 | 任务 | 跳转 |
- |-------|------|------|
- | "绕过检测" "过掉反调试" | 绕过 | §四 Pipeline |
- | "检测防调试" "防调试" "ptrace" "TracerPid" "GDB" "有没有反调试" | 防调试检测 | §九 → `debug-gdb.bat` |
- | "检测防注入" "防注入" "注入测试" "能否注入" "anti-injection" | 防注入检测 | §九 → `check-anti-inject.bat` |
- | "APK 信息" "Janus" "签名漏洞" "APK 签名" "加固检测" "包名版本" | APK 元数据 | §九 → `check-janus.bat` |
- | "找到加密明文" "明文在哪" "加密前数据" | 定位明文 | §2.1 Step 1 crypto_monitor(showStack) |
- | "分析加密算法" "什么加密" "密钥是什么" | 识别算法 | §2.1 完整决策树 |
- | "看网络请求" "还原协议" "抓包" | 协议分析 | §2.2 |
- | "native 函数" "so 里的加密" "找不到导出" | Native 分析 | §2.1 → native_hooker |
- | "全程监控" "不知道做了什么" "摸一下行为" | 行为摸底 | §2.3 |
- | "分析这个类" "hook 某个方法" | 通用 Java 逆向 | §三 Java Hook 模板 |
- | "hook OkHttp" "拦截请求" "SSL 明文" | HTTP 明文 | ssl_plaintext 模块 |
- | "SSL 证书" "忽略 SSL" "证书校验" "TrustManager" "HostnameVerifier" "onReceivedSslError" "proceed" "WebView 安全" | SSL/TLS 忽略检测 | §十 |
- | "修改参数" "伪造返回值" "替换数据" | 修改数据 | §三 — 在 implementation 中改 return 值 |
- | "NOP 掉" "跳过校验" "patch 这个偏移" | 已知偏移 patch | `function_patcher.patchBatch([...])` |
- | "so 加载顺序" "追踪 so" | SO 追踪 | dl_monitor 或 so_loader_tracer |
- | "建分析脚本" "用 Python" | Python 入口 | §3.3 |
- | "污点追踪" "跨组件" "Intent跟踪" "source to sink" "数据流" "攻击链" | 跨组件污点追踪 | §2.6 → intent_tracker |
- | "Serializable" "Parcelable" "反序列化" "readObject" "createFromParcel" | 序列化攻击面扫描 | §2.7 → JADX 搜索 `readObject` / `createFromParcel` |
- | "内存扫描" "敏感数据" "密钥泄露" "密码输入" "内存搜索" "AES key" "硬编码密钥" "API key" "token" "令牌" | 内存敏感数据扫描 | §2.8 → memory_scanner |
-
---
- ## 二、分析决策树
-
- ### 2.1 加密算法分析
-
- ```
- Step 1: crypto_monitor(Java 层自吐)
- 模块: utils + crypto_monitor
- │
- ├── [有输出] → 拿到算法、密钥(hex/base64)、IV、明文/密文
- │ 配置 showStack:true 从调用栈定位业务代码 → 结束
- │
- └── [无输出] → 加密不在 Java 层,判因下钻
- ├── Java.available = false → 纯 native 进程/iOS → Step 2-Native
- ├── 自定义 ClassLoader/反射 → hook ClassLoader.loadClass 定位类名
- └── 加密在 native 层(OpenSSL/BoringSSL/自实现)→ Step 2-Native
-
- Step 2-Native: native_hooker
- 模块: utils + native_hooker(targetLibs:["libencrypt","libssl","libcrypto"])
- ├── [命中] → 自动打印参数(hexdump)/返回值/调用栈
- ├── [STRIPPED] → 追加 dlsym_tracer 看运行时解析
- ├── [没找到明显 crypto so] → 清空 targetLibs 扫描全部 /data/ so
- └── Step 3: network_monitor 字节级兜底
- 模块: utils + network_monitor(showPayload:true) + syscall_tracer
- 密文必经 write/sendto 发出 → backtrace → so+offset
- ```
-
- ### 2.2 网络协议分析
-
- ```
- Step 1: network_monitor
- 模块: utils + network_monitor
- ├── [明文 HTTP/JSON/Protobuf] → 结束
- └── [密文/TCP 字节流] →
- ├── 标准 TLS (端口 443) → SSL Pinning 绕过
- ├── 自定义加密 TCP → §2.1 先分析加密层
- └── 多通道(WebSocket/Binder/Unix Socket)→ proc_monitor + syscall_tracer
- ```
-
- ### 2.3 行为摸底
-
- ```
- Step 1: 全量监控
- 模块: utils + file_monitor + network_monitor + thread_monitor
- ├── [file_monitor 看到 .dat/.json/.xml] → 追加 crypto_monitor
- ├── [network_monitor 看到陌生 IP 或大量 DNS] → 追加 dl_monitor + crypto_monitor
- ├── [thread_monitor 看到周期性 pthread_create] → 追加 syscall_tracer
- └── [所有模块无输出] → 追加 syscall_tracer(traceAll:true)
- ```
-
- ### 2.4 反 Frida 检测(入口 → ANTI-DETECTION.md)
-
- > **前置快速检测**(无需 Frida,独立工具,详见 §九):
- > - `debug-gdb.bat <包名>` — ptrace 反调试检测(TracerPid + 进程存活)
- > - `check-anti-inject.bat <包名>` — SO 注入检测(ptrace + mem 注入)
-
- ```
- Step 1: 保活 + 定位检测 so
- 模块: utils + exit_blocker + so_loader_tracer
- exit_blocker: Interceptor.replace 替换 exit_group/_exit/abort/kill/tgkill
- so_loader_tracer: 记录 do_dlopen 路径+基址
- │
- ├── [exit_blocker BLOCKED + 调用栈来自 pthread_create]
- │ → 分支 A(线程检测):thread_blocker 或 function_patcher
- │ → 详见 ANTI-DETECTION.md "分支 A"
- │
- ├── [exit_blocker BLOCKED + 调用栈来自 init_array]
- │ → 分支 B(init_array 检测):init_hook + feature_hider
- │ → 详见 ANTI-DETECTION.md "分支 B"
- │
- └── [exit_blocker 无 BLOCKED,进程直接消失]
- → SVC #0 内联 exit_group,完全绕过 libc
- → 分支 B:llvm-objdump linker64 → init_hook + hasSvc0
- ```
-
- ### 2.5 症状速查
-
- | 症状 | 模式 | 模块组合 |
- |------|------|---------|
- | exit_blocker BLOCKED + 调用栈来自 pthread_create | 线程检测 | `thread_blocker(blockCallers)` 或 `thread_monitor(callerFilter)` → `function_patcher` |
- | 已知 IDA so+offset | 已分析目标 | `function_patcher.patchBatch([...])` |
- | 加固壳延迟加载 so + 检测线程 | 壳多阶段 | `thread_blocker(blockCallers)` + `waitForModule` |
- | exit_blocker 无 BLOCKED 但进程退出 | init_array SVC | `init_hook` + `hasSvc0` |
-
- ### 2.6 跨组件污点追踪(Source → Flow → Sink)
-
- ```
- 攻击链模型:
- Source(不可信数据入口)→ Flow(跨组件传递)→ Sink(危险操作)
-
- Step 1: intent_tracker — 追踪数据在组件间流动
- 模块: utils + intent_tracker
- │
- ├── [有输出] → 看到完整的组件跳转链 + Intent extras 内容
- │ ├── 结合 file_monitor 看是否对应文件操作
- │ ├── 结合 network_monitor 看是否对应网络请求
- │ └── 三链路对齐 → 确认完整攻击链 (source→flow→sink)
- │
- └── [无输出] → 组件通信不走标准 Intent API
- ├── 可能是 Binder 直接调用 → 下钻到 syscall_tracer
- └── 可能是 Unix Socket → proc_monitor
-
- Step 2: 组合攻击链验证
- 模块: utils + intent_tracker + file_monitor + network_monitor
- 操作: 触发 deeplink / 发送 Intent → 观察三模块日志:
- │
- ├── intent_tracker: ExportedActivity → InternalActivity (extras:{url: "evil.com"})
- ├── file_monitor: InternalActivity.openat /data/data/.../secret.db
- └── network_monitor: InternalActivity.connect evil.com:443
- │
- └── 三条日志时间戳对齐 → 攻击链确认
- ```
-
- ### 2.7 序列化攻击面扫描(Serializable / Parcelable)
-
- ```
- Android 中所有 Serializable/Parcelable 类都可从 Intent 反序列化。
- 攻击者构造恶意对象塞入 Intent extras → 触发 readObject()/createFromParcel() 中的危险 sink。
-
- Step 1: 搜索候选类(JADX)
- 方法1: 搜索方法名 "readObject" → 找到所有自定义反序列化入口
- 方法2: 搜索方法名 "createFromParcel" → 找到所有 Parcelable 工厂方法
- 方法3: 搜索类声明 "implements Serializable" / "implements Parcelable"
-
- Step 2: 逐个检查反序列化链
- 对每个 readObject(ObjectInputStream) 方法,追踪数据流:
- ois.readObject() / readUTF() / readInt() 等 ← SOURCE
- → 赋值给 this.xxx 字段 ← FLOW
- → 后续方法使用 this.xxx 做了什么? ← SINK?
-
- Step 3: 重点 sink 模式
- ├── Class.forName(字段).newInstance() → 任意类实例化(Google Auth bug)
- ├── Class.forName(字段).getMethod().invoke() → 任意方法反射调用
- ├── new FileInputStream(字段) / new File(字段) → 路径遍历文件读取
- ├── Runtime.exec(字段) / ProcessBuilder(字段) → 命令注入
- ├── loadUrl(字段) / loadData(字段) → WebView URL 注入
- ├── startActivity(字段) / startService(字段) → Intent 重定向
- └── SQLiteDatabase.execSQL(字段) → SQL 注入
-
- Step 4: 确认字段外部可控
- 只要满足任一条件,字段即外部可控:
- ├── 类本身实现了 Serializable → 可直接 Intent.putExtra()
- ├── 类是某个 Intent extra 的成员字段 → 间接可控
- └── 类通过 Bundle.putSerializable() 传递 → 间接可控
- ```
-
- ### 2.8 内存敏感数据扫描 + 密码输入监听
-
- ```
- memory_scanner.js 做三件事:
- 1. 自动扫描预设高价值数据(AES key、JWT、私钥、API key、URL 凭证)
- 2. 实时监听密码输入框的输入内容
- 3. 通过 Frida console 提供交互式搜索 API
-
- Step 1: 加载模块
- frida -U -f com.app -l utils.js -l memory_scanner.js
- → 3 秒后自动扫描一次,输出所有匹配
-
- Step 2: 交互式搜索(Frida console 中执行)
- MemoryScanner.search("password") 搜索所有 rw- 内存区域
- MemoryScanner.searchJava("api_key") 搜索 Java 堆 String 对象
- MemoryScanner.searchMod("libnative.so", "secret") 搜索指定模块
- MemoryScanner.dump("0x7a12345678", 256) hexdump 指定地址
- MemoryScanner.stats() 查看扫描统计
- MemoryScanner.scanNow() 手动触发一次完整扫描
- MemoryScanner.addPattern("MY_KEY", "sk-[a-z]{24}") 添加自定义模式
+ ## 二、决策树导航
- Step 3: 密码输入捕获(Frida console 中启动,无需 -e 参数)
- MemoryScanner.startPasswordCapture() 启动密码输入监听
- MemoryScanner.passwordCaptureStatus() 查看状态
- → 自动检测 EditText 的 password 类型字段
- → 用户输入时实时输出到 console
+ 每种技巧在对应 references 有完整决策树,此处只给入口:
- Step 4: 预设模式说明
- ├── AES-128/192/256 key: 32/48/64 位 hex 字符串
- ├── JWT Token: eyJ... 格式
- ├── PEM Private Key: -----BEGIN...PRIVATE KEY-----
- ├── PEM Public Key / Certificate
- ├── AWS Access Key (AKIA...), AWS Secret Key
- ├── Google API Key (AIza...)
- ├── GitHub Token (ghp_...), Slack Token (xox...)
- ├── Stripe API Key (sk_live_...)
- ├── Firebase URL
- └── URL with credentials (https://user:pass@host)
- ```
+ | 技巧域 | 入口决策树 | 详细 |
+ |-------|-----------|------|
+ | 加密算法 | Step 1 crypto_monitor → Step 2 native_hooker → Step 3 network_monitor | crypto-hook.md |
+ | 网络协议 | Step 1 network_monitor → 明文/密文分流 | behavior-analysis.md |
+ | 行为摸底 | file + network + thread 三模块画像 → 按信号追加 | behavior-analysis.md |
+ | 反检测 | Phase 1 保活 → 分支 A/B → Phase 2-6 | anti-detection.md |
+ | 跨组件污点 | intent_tracker → 三链路对齐 | behavior-analysis.md |
+ | 内存敏感数据 | memory_scanner 自动扫描 + 交互式搜索 | crypto-hook.md |
+ | SO 层分析 | 分层下钻:Java → JNI → .so → libc → syscall → svc | native-analysis.md |
+ | 静态攻击面 | 攻击面枚举 → 逐类审查 → 序列化链路 | static-analysis.md |
---
- ## 三、模块目录与用法
-
- ### 3.1 目录结构
-
- ```
- scripts/
- ├── core/ utils.js ← 始终首个加载
- ├── monitors/ crypto_monitor, file_monitor, 被动观察模块
- │ network_monitor, thread_monitor, 只观测,不修改
- │ dl_monitor, proc_monitor,
- │ syscall_tracer, ssl_plaintext,
- │ native_hooker, intent_tracker,
- │ native_crypto_monitor, memory_scanner
- ├── bypass/ exit_blocker, thread_blocker, 主动干预模块
- │ frida_feature_hider, function_patcher, 修改 app 行为
- │ init_hook, dlsym_tracer,
- │ so_loader_tracer, shellcode_detector
- ├── checklist/ (Frida 动态检测脚本,预留) 按需扩展
- └── templates/ analysis.py, custom_hook.js 模板文件
-
- tools/ check-anti-inject.bat, debug-gdb.bat, 独立检测工具(详见 §九)
- check-janus.bat, GetAPKInfo.jar Frida 挂载前跑
- ```
+ ## 三、模块目录
- ### 3.2 Java Hook 模板
+ `scripts/` 下全部模块,按用途分类。`utils.js` 始终首个加载。
- ```bash
- # 枚举已加载的类(按关键词过滤)
- frida -U -f com.app -e 'Java.perform(function(){Java.enumerateLoadedClasses({onMatch:function(n){if(n.indexOf("keyword")!==-1)console.log(n);},onComplete:function(){}});});'
+ ### core/
- # Hook 指定方法并打印返回值
- frida -U -f com.app -l utils.js \
- -e 'Java.perform(function(){var C=Java.use("com.example.Class");C.method.implementation=function(){var r=this.method();console.log("[*]",r);return r;};});'
- ```
+ | 模块 | 用途 |
+ |------|------|
+ | `utils.js` | 公共工具(日志格式化/hexdump/backtrace),**必须首个加载** |
- 详细 API 参考(Java.use / Interceptor / Stalker / Memory / ObjC)见 `API-REFERENCE.md`。
+ ### monitors/(被动观察,不修改行为)
- ### 3.3 Python 工作流(推荐)
+ | 模块 | 用途 | 归属 |
+ |------|------|------|
+ | `crypto_monitor.js` | Java 层加解密自吐(算法/密钥/IV/明文) | crypto-hook |
+ | `native_crypto_monitor.js` | OpenSSL/BoringSSL 加密监控 | crypto-hook |
+ | `native_hooker.js` | 任意 native 函数 hook(加密/发送/校验) | native-analysis |
+ | `ssl_plaintext.js` | OkHttp/Retrofit HTTP 明文 | crypto-hook |
+ | `memory_scanner.js` | 内存敏感数据扫描 + 密码输入监听 | crypto-hook |
+ | `file_monitor.js` | 文件读写监控 | behavior-analysis |
+ | `network_monitor.js` | 网络连接/收发监控 | behavior-analysis |
+ | `thread_monitor.js` | 线程创建监控 | behavior-analysis |
+ | `dl_monitor.js` | SO 加载/卸载监控 | native-analysis |
+ | `proc_monitor.js` | 子进程/命令执行监控 | behavior-analysis |
+ | `syscall_tracer.js` | syscall 层追踪 | native-analysis |
+ | `svc_tracer.js` | SVC #0 指令追踪(Stalker) | native-analysis |
+ | `intent_tracker.js` | 跨组件 Intent 污点追踪 | behavior-analysis |
- 避免手敲超长 CLI 命令。使用 `scripts/templates/analysis.py`:
+ ### bypass/(主动干预,修改行为)
- ```
- 1. 复制 analysis.py → <包名>/analysis.py
- 2. 修改 TARGET_PACKAGE / LOAD_MODULES / CONFIG_OVERRIDE
- 3. 在 CUSTOM_HOOK_SCRIPT 中写入 app 专属逻辑
- 4. 运行: python analysis.py
- ```
+ | 模块 | 用途 | 归属 |
+ |------|------|------|
+ | `exit_blocker.js` | 拦截 exit_group/_exit/abort/kill/tgkill 保活 | anti-detection |
+ | `thread_blocker.js` | 阻断检测线程 pthread_create | anti-detection |
+ | `init_hook.js` | call_constructors 抢时机(init_array 检测) | anti-detection |
+ | `frida_feature_hider.js` | 隐藏 Frida 特征(/proc/线程/内存) | anti-detection |
+ | `function_patcher.js` | 已知偏移 NOP patch | anti-detection |
+ | `shellcode_detector.js` | 定位 mmap+PROT_EXEC shellcode | anti-detection |
+ | `dlsym_tracer.js` | 追踪运行时符号解析 | anti-detection |
+ | `so_loader_tracer.js` | 记录 do_dlopen 路径+基址 | anti-detection |
+ | `root_bypass.js` | Root 检测绕过(File.exists/系统属性) | anti-detection |
- 模板自动处理模块加载顺序(utils.js 首加载 → monitors → bypass → 自定义脚本)。`CONFIG_OVERRIDE` 以 Python dict 形式配置,无需 CLI 字符串拼接。
+ ### utils/(SO/DEX 静态工具)
- **交互模式**(需要用户在 app 上点击按钮):设 `TIMEOUT=0`(手动 Ctrl+C 停止)和 `LOG_TO_FILE=True`,详见 §七。
+ | 工具 | 用途 | 归属 |
+ |------|------|------|
+ | `unpack.py` | **脱壳一键入口**(线性流水线:回填+补充+自动pull+fix-checksum+去重+方法体标记) | unpacking |
+ | `so_dump.js` | 内存 dump SO(脱壳提取) | unpacking |
+ | `dex_cache_dump.js` | DexCache 精确 dump(免疫假 DEX/抹 magic) | unpacking |
+ | `dex_finder.js` | 内存搜索 + 指纹校验 + 去重(**备选**:frida-dexdump 不可用时直接用) | unpacking |
+ | `dex_defineclass_dump.js` | DefineClass 被动拦截 dump | unpacking |
+ | `codeitem_dump.js` | 二代壳提取:主动 loadClass 触发回填 + 整 DEX dump | unpacking |
+ | `dex_rebuilder.py` | ① `--fix-checksum` 重算 checksum(默认操作)② CodeItem 离线重组回填 | unpacking |
+ | `dex_dedupe.py` | 产物去重/校验 | unpacking |
+ | `find_strref.py` | 字符串引用定位 | native-analysis |
+ | `find_branch_callers.py` | 交叉引用/调用者定位 | native-analysis |
+ | `fix_elf.py` | 修复 ELF header | unpacking |
+ | `patch_gadget_threadnames.py` | patch gadget 线程名 | native-analysis |
+ | `scan_inline_svc.py` | 扫描内联 SVC 指令 | native-analysis |
+ | `scan_register_natives.js` | 定位 native 方法实现(Dex2C 按需分析) | native-analysis |
- ### 3.4 常用组合速查
+ ### templates/ + checklist/
- | 分析目标 | 模块组合 | 说明 |
- |---------|---------|------|
- | 加解密自吐 | `utils + crypto_monitor` | 第一步总是 crypto_monitor;无输出则加密在 native |
- | Native 加密 | `utils + native_hooker` | 默认模式: encrypt/decrypt/aes/rsa/des/sha/hmac/base64/xor |
- | HTTP 明文 | `utils + ssl_plaintext` | OkHttp/Retrofit/HttpsURLConnection |
- | 字节级协议 | `utils + network_monitor(showPayload:true)` | 发出/接收原始 hex 字节 |
- | 行为摸底 | `utils + file_monitor + network_monitor + thread_monitor` | 三模块快速画像 |
- | SO 加载追踪 | `utils + dl_monitor` | 加载/卸载/符号解析全生命周期 |
- | 子进程监控 | `utils + proc_monitor` | 命令执行、进程创建 |
- | 反检测 Phase 1 | `utils + exit_blocker + so_loader_tracer` | 保活 + 定位检测 so |
- | 反检测 Phase 2 | `utils + frida_feature_hider(indirectHook) + init_hook(onModuleInit) + exit_blocker` | 抢时机 + 隐藏特征 |
- | 反检测线程阻断 | `utils + thread_blocker(blockCallers)` | 拦截检测 so 的 pthread_create |
- | 全量覆盖 | `utils + file + thread + network + syscall + dl + proc + crypto` | 盲区全覆盖,日志量大 |
- | 跨组件污点追踪 | `utils + intent_tracker` | 跟踪数据在 Activity/Service/Broadcast/Provider 间的流动 |
- | 完整攻击链 | `utils + intent_tracker + file_monitor + network_monitor` | web→sink 全路径:source(Intent) → flow(组件跳转) → sink(文件/网络) |
- | 内存敏感数据 | `utils + memory_scanner` | 自动扫描 AES key/JWT/API key/私钥 + 密码输入监听 + 交互式搜索 |
+ | 文件 | 用途 |
+ |------|------|
+ | `templates/analysis.py` | Python 工作流模板(推荐,自动处理模块加载顺序) |
+ | `templates/custom_hook.js` | 自定义 hook 模板 |
+ | `checklist/webview_ssl_check.js` | WebView SSL 检测清单 |
+ | `checklist/fridainject.js` | **frida 环境检测项**:注入后弹窗不出现/进程被杀 = 存在检测(验证注入是否成功) |
---
## 四、分层分析原则
- 当上层 hook 失效时,按此递推下钻到更底层:
+ 当上层 hook 失效时,按此递推下钻(完整方法见 native-analysis.md):
```
- Java/ObjC → Java.use / ObjC.classes
- ↓ 被绕过时
- JNI Bridge → RegisterNatives 劫持
- ↓
- Native .so → Interceptor.attach(导出函数)
- ↓
- libc → Interceptor.attach(libc 函数)
- ↓
- syscall → Interceptor.attach(syscall)
- ↓
- SVC #0 → Stalker / inline hook
+ Java/ObjC → JNI/Runtime → Native .so → libc → syscall → SVC #0
```
- 完整调用链:`Java/ObjC → JNI/Runtime → Native .so → libc → syscall → svc`
-
- ### 常见下钻场景
-
- | 现象 | 原因 | 下钻到 |
- |------|------|--------|
- | crypto_monitor 无输出 | 非 Java 层 | native_hooker |
- | file_monitor 无输出 | 函数内联 | syscall_tracer |
- | network_monitor 无 connect | 使用 sendto(UDP) | 检查 recvfrom |
- | network_monitor 无输出 | Binder/Unix Socket | syscall_tracer(traceAll:true) |
- | dl_monitor 无输出 | 自定义 linker | syscall_tracer (mmap+PROT_EXEC) |
- | native_hooker 无输出 | SO 尚未加载 | spawn 模式或 dl_monitor |
- | native_hooker [STRIPPED] | 去符号 | dlsym_tracer |
- | ssl_plaintext 无输出 | 非标准 HTTP 库 | network_monitor(showPayload:true) |
+ 常见下钻:crypto_monitor 无输出→native_hooker;file_monitor 无输出→syscall_tracer;network_monitor 无 connect→检查 recvfrom;dl_monitor 无输出→syscall_tracer(mmap+PROT_EXEC)。
---
## 五、运行时配置(CONFIG_OVERRIDE)
- **两个修改层级**:
- - **编辑模块文件**(持久生效):直接改 `scripts/monitors/xxx.js` 或 `scripts/bypass/xxx.js` 中的 `var CONFIG = { ... }`
- - **命令行注入**(临时覆盖):使用 Frida `-e` 参数注入 `CONFIG_OVERRIDE`
-
- 所有模块都接受 `CONFIG_OVERRIDE`,通过 Frida `-e` 或 Python dict 注入:
+ 所有模块接受 `CONFIG_OVERRIDE`,通过 `-e` 或 Python dict 注入:
```javascript
var CONFIG_OVERRIDE = {
- file_monitor: { showBacktrace: true, filterPath: ["/data/data/com.target/"] },
- network_monitor: { showPayload: true, showBacktrace: false },
+ file_monitor: { filterPath: ["/data/data/com.target/"] },
+ network_monitor: { showPayload: true },
crypto_monitor: { showStack: true },
- native_hooker: { targetLibs: ["libencrypt.so"], hookPatterns: ["encrypt", "aes", "xor"] },
+ native_hooker: { targetLibs: ["libencrypt.so"] },
ssl_plaintext: { urlFilter: ["api.example.com"] },
exit_blocker: { showBacktrace: false },
init_hook: { onModuleInit: [{ moduleName: "libDetect.so" }], probeCallers: true, autoHideFrida: true },
thread_blocker: { blockCallers: ["libmsaoaidsec.so"] },
frida_feature_hider: { indirectHook: true },
};
```
- ### 常用覆盖场景
-
- | 场景 | CONFIG_OVERRIDE |
- |------|----------------|
- | 只看目标路径 | `file_monitor: { filterPath: ["/data/data/com.target/"] }` |
- | 关闭调用栈(降噪) | `file_monitor: { showBacktrace:false }, network_monitor: { showBacktrace:false }` |
- | 打印发出字节 | `network_monitor: { showPayload:true }` |
- | 限定 native hook 库 | `native_hooker: { targetLibs:["libencrypt"] }` |
- | 阻断检测线程 | `thread_blocker: { blockCallers:["libDetect.so"] }` |
- | indirectHook 模式 | `frida_feature_hider: { indirectHook:true }` |
- | 只看特定 URL | `ssl_plaintext: { urlFilter:["api.example.com"] }` |
- | 交互模式 | `analysis.py` 中 `TIMEOUT=0`、`LOG_TO_FILE=True` |
+ 各模块特有配置见对应 references 文件。
---
- ## 六、故障诊断
-
- ### Hook 不生效 / 模块无输出
-
- | 现象 | 可能原因 | 排查 |
- |------|---------|------|
- | crypto_monitor 无输出 | Java.available=false | §2.1 → native_hooker |
- | crypto_monitor 无输出 | 自定义 ClassLoader | hook ClassLoader.loadClass |
- | crypto_monitor 无输出 | 加密在 native 层 | dl_monitor 确认 crypto so |
- | file_monitor 无输出 | 函数内联 | syscall_tracer |
- | network_monitor 无 connect | UDP (sendto) | 检查 recvfrom |
- | network_monitor 无输出 | Binder/Unix Socket | syscall_tracer(traceAll:true) |
- | dl_monitor 无输出 | 自定义 linker | syscall_tracer (mmap+PROT_EXEC) |
- | native_hooker 无输出 | SO 尚未加载 | spawn 模式或 dl_monitor |
- | ssl_plaintext 无输出 | 非标准 HTTP 库 | network_monitor(showPayload:true) |
+ ## 六、独立检测工具(前置,无需 Frida)
- ### 进程闪退 / 不稳定
+ `tools/` 下 bat 脚本,Agent 不能代跑,输出命令让用户自行执行(方便截图取证)。
- | 现象 | 可能原因 | 排查 |
+ | 工具 | 检测目标 | 用法 |
|------|---------|------|
- | 加载 Frida 后闪退 | Frida 被检测 | 加载 exit_blocker → ANTI-DETECTION.md |
- | exit_blocker 后仍闪退 | sigaction(SIGKILL)+raise | 额外 hook signal + kill/tgkill |
- | exit_blocker 后仍闪退 | 内联 _exit() | syscall_tracer (syscall 93/94) |
- | hook 后 ANR/卡死 | onEnter 耗时操作 | 改为异步 send() |
- | Interceptor.replace 崩溃 | 参数签名不匹配 | 检查 NativeFunction 参数类型 |
- | TypeError: not a function | replace/attach 冲突 | exit_blocker(blockSyscall:false) 或 indirectHook |
- | 进程退出但无 BLOCKED | SVC #0 内联 exit_group | ANTI-DETECTION.md 分支 B |
-
- ### 环境版本
+ | `check-anti-inject.bat` | 防注入(ptrace + /proc/pid/mem) | `tools/check-anti-inject.bat <包名>` |
+ | `debug-gdb.bat` | 防调试(ptrace / TracerPid) | `tools/debug-gdb.bat <包名>` |
+ | `check-janus.bat` | APK 元数据提取 | `tools/check-janus.bat <apk路径>` |
- | 现象 | 原因 | 排查 |
- |------|------|------|
- | frida -U 连不上 | frida-server 未启动或版本不匹配 | `adb shell "frida-server -D"` |
- | Java.perform 报错 | 非 JVM 进程 | `frida-ps -U` 确认进程类型 |
- | ARM64 vs ARM32 符号不匹配 | 64位设备 32位 so | `file` 命令检查架构 |
- | iOS arm64e PAC 崩溃 | 指针认证 | 见 API-REFERENCE.md |
- | Android 高版本 linker64 符号消失 | linker 重构 | `Module.enumerateExports("linker64")` |
+ 首次分析新 App:check-janus → debug-gdb → check-anti-inject → Frida Phase 1。所有工具前置条件:root + SELinux Permissive。
---
## 七、交互式协作流程
- 当目标行为需要用户在 app 上手动点击按钮/切换页面时才触发时,使用此流程。
-
- **循环模式**:配置 analysis.py → 运行 → 用户操作 app → Ctrl+C 停止 → AI 读 `.txt` 日志 → 改 CUSTOM_HOOK_SCRIPT → 再运行。
-
- **关键配置**:`TIMEOUT=0`(手动停止)、`LOG_TO_FILE=True`(日志落盘供 AI 读取)。
-
- **日志分析**:AI 直接读日志文件,按 §八交叉分析模式关联多模块信号与时间戳,输出「已确认 → 推断 → 下一步建议」。用户只需告知操作的大致时间点(如"14:32:15 点了登录"),AI 据此锚定窗口过滤日志。
-
- 运行时也可实时读取日志(`.flush()` 确保写入),但推荐停止后再分析,日志更完整。
-
- ---
-
- ## 八、模块间交叉分析
-
- 单个模块的日志提供**纵向**信号(某种行为是否发生),多模块日志交叉分析提供**横向**关联(行为之间的因果关系)。以下模式帮助 LLM 在分析日志时做出正确路由判断。
-
- ### 8.1 配置文件解密识别
-
- ```
- 信号组合: file_monitor 看到 read /data/.../config.dat
- + crypto_monitor 随后出现 AES/ECB/PKCS5Padding 解密
- 时间窗口: file_monitor 时间戳 < crypto_monitor 时间戳 < 1ms
- 结论: config.dat 是加密配置文件,算法为 AES/ECB
- 操作: 用 crypto_monitor 输出的密钥和 IV 离线解密 config.dat
- ```
-
- ### 8.2 Native 层网络初始化识别
-
- ```
- 信号组合: dl_monitor 看到加载 libnetwork.so
- + network_monitor 随后出现 connect(... 443)
- 时间窗口: dl_monitor < network_monitor < 500ms
- 结论: libnetwork.so 负责网络初始化,可能在 .init_array 中执行
- 操作: 对该 so 追加 init_hook — 配置 onModuleInit:libnetwork.so
- ```
-
- ### 8.3 检测 so 定位(Phase 1 核心决策)
-
- ```
- 信号组合: so_loader_tracer 看到加载 libDetect.so
- + exit_blocker 随后立即 BLOCKED exit_group
- 时间窗口: so_loader_tracer < exit_blocker < 10ms
- 结论: libDetect.so 的 init_array 触发了退出(典型反 Frida 检测)
- 操作: → Phase 2: 追加 init_hook + dlsym_tracer 获取检测逻辑
- → Phase 5: 追加 shellcode_detector 定位闪退偏移
- → Phase 6: function_patcher NOP 掉闪退函数
- ```
-
- ### 8.4 加密函数 native 层定位
-
- ```
- 信号组合: network_monitor 看到 sendto(... 密文 payload, length=256)
- + syscall_tracer 看到 write(fd, len=256) 在同一线程、同一时间戳
- 时间窗口: |network_monitor 时间戳 - syscall_tracer 时间戳| < 2ms
- 结论: write() 的调用者就是加密/发送函数
- 操作: 在 write() hook 中执行 Thread.backtrace() → 第2-3帧即加密函数地址
- → Process.findModuleByAddress 解析为 libxxx.so+0xoffset
- ```
-
- ### 8.5 其他关联模式
-
- | 信号组合 | 结论 | 时间窗口 |
- |---------|------|---------|
- | file_monitor `read /data/.../config.dat` → crypto_monitor `AES/ECB` | (详见 8.1) | <1ms |
- | dl_monitor `libnetwork.so` → network_monitor `connect(...443)` | (详见 8.2) | <500ms |
- | so_loader_tracer `libDetect.so` → exit_blocker `BLOCKED exit_group` | (详见 8.3) | <10ms |
- | network_monitor `sendto(密文,256)` + syscall_tracer `write(fd,256)` 同线程同时 | (详见 8.4) | <2ms |
- | intent_tracker `ExportedActivity → WebViewActivity` + file_monitor `openat .../secret.db` | 跨组件攻击链:deeplink source → 组件跳转 flow → 文件读取 sink | <500ms |
- | intent_tracker extras 含 `Serializable` + file_monitor 读到私有文件 | 反序列化攻击链:Intent 携带恶意序列化对象 → 触发路径遍历 | 看 intent_tracker 先于 file_monitor |
-
- ### 8.6 反向推断:用缺失信号做排除
-
- 当某一模块无输出但不确定原因时,用已知正常模块的状态做排除法:
+ 需要用户在 app 上手动操作时(点击按钮/切换页面触发行为):
```
- 场景: 你 hook javax.crypto.Cipher 但无输出
- 交叉验证: 同时加载 file_monitor
- → file_monitor 有输出 → utils.js 正常、Frida 正常、进程正常 — 问题锁定在 Java hook 层
- → file_monitor 也无输出 → 可能:
- - app 在 Frida attach 前就退出了 → 检查 exit_blocker
- - 目标进程不是 JVM 进程 → 检查 Java.available
- - Frida 没有正确注入 → 检查 frida-ps -U 确认进程可见
- ```
-
- ---
-
- ## 九、独立检测工具
-
- `tools/` 目录下的自动化检测脚本,**无需 Frida 即可运行**,是 Frida 分析的前置步骤。
-
- > **Agent 使用规则**:三个 bat 是 Windows 批处理,Agent 不能代跑,应输出完整命令让用户自行执行(方便截图)。用户提到"检测反调试"、"检测防注入"、"看 APK 信息"时,Agent 按 §1.2 路由表匹配对应工具,输出命令。
-
- | 工具 | 检测目标 | 用法 |
- |------|---------|------|
- | `check-anti-inject.bat` | 防注入(ptrace + /proc/pid/mem) | `check-anti-inject.bat <包名>` |
- | `debug-gdb.bat` | 防调试(ptrace / TracerPid) | `debug-gdb.bat <包名>` |
- | `check-janus.bat` | APK 元数据提取 | `check-janus.bat <apk路径>` |
-
- ### 9.1 check-anti-inject.bat — 防注入检测
-
- **原理**:通过 AndKittyInjector 向目标进程注入 `libhello64.so`(ptrace + /proc/pid/mem 方式),然后检查 `/proc/pid/maps` 确认注入是否成功。
-
- **前置条件**:
- - 设备已 root,SELinux 设为 Permissive(脚本自动执行 `setenforce 0`)
- - `/data/local/tmp/AndKittyInjector` — 注入器二进制
- - `/data/local/tmp/libhello64.so` — 测试用 SO
-
- **流程**(5 步):
- 1. 检查 ADB 设备连接
- 2. 启动目标 App 并获取 PID
- 3. 注入前检查 maps(确认干净)
- 4. 执行 AndKittyInjector 注入
- 5. 注入后检查 maps 验证结果
-
- **输出判读**:
- - `Injection SUCCESS` + maps 中找到 `libhello64.so` → **无防注入保护**
- - `Injection FAILED` + maps 中无 `libhello64.so` → **存在防注入保护**
-
- **局限**:仅测试 ptrace + mem 注入方式,不覆盖 LD_PRELOAD、Zygote 注入、Magisk 模块注入等。
-
- ### 9.2 debug-gdb.bat — 防调试检测(ptrace)
-
- **原理**:通过 gdbserver64 附加到目标进程,读取寄存器/内存/线程列表,然后检查进程是否存活(反调试会杀死进程)。全程监控 TracerPid 变化。
-
- **前置条件**:
- - 设备已 root,SELinux 设为 Permissive
- - `/data/local/tmp/gdbserver64` — GDB 服务端
- - 本机已安装 Android NDK(`gdb-aarch64.cmd` 中配置路径,默认 NDK 21.4)
-
- **流程**(7 步):
- 1. 检查 ADB 设备连接
- 2. 获取目标进程 PID + 调试前 TracerPid(应为 0)
- 3. 启动 gdbserver64 附加(端口 5039)+ 调试中 TracerPid(应为 gdbserver PID)
- 4. 端口转发 `tcp:5039`
- 5. GDB 批量执行(`debug.gdb` 脚本):寄存器转储 → PC 内存读取 → 线程列表 → detach
- 6. 反调试等待 5 秒 → 检查进程是否存活
- 7. 调试后 TracerPid(应恢复为 0)
-
- **输出判读**:
- - TracerPid: `0 → gdbserver PID → 0` + 进程存活 → **无 ptrace 反调试**
- - 进程消失 / gdbserver 连接失败 → **存在 ptrace 反调试**
-
- **辅助文件**:
- - `gdb-aarch64.cmd` — NDK GDB 包装器,自动设置 PATH 指向 aarch64 GDB
- - `debug.gdb` — GDB 批处理脚本(寄存器/内存/线程/detach)
-
- ### 9.3 check-janus.bat — APK 元数据提取
-
- **原理**:使用 `GetAPKInfo.jar` 提取 APK 的包名、版本号、版本代码等元数据。
-
- **前置条件**:
- - 本机已安装 Java Runtime
-
- **用法**:
- ```bat
- check-janus.bat path/to/app.apk
+ 配置 analysis.py(TIMEOUT=0 手动停止、LOG_TO_FILE=True 日志落盘)
+ → 运行 → 用户操作 app → 停止 → 读日志 → 改 CUSTOM_HOOK_SCRIPT → 再运行
```
- **输出**:APK 包名、版本号、版本代码等(中文输出,GBK 编码)。
-
- ### 9.4 与 Frida 检测的配合
-
- | 场景 | 推荐流程 |
- |------|---------|
- | 首次分析新 App | `check-janus.bat` 提取 APK 信息 → `debug-gdb.bat` 测 ptrace → `check-anti-inject.bat` 测注入 → Frida Phase 1 |
- | Frida 挂载闪退 | `debug-gdb.bat` 确认 ptrace 反调试 → 再决定 Frida 策略(§2.4 Pipeline) |
- | Frida 挂载成功但行为异常 | `check-anti-inject.bat` 确认注入能力 → 交叉验证 Frida 检测结果 |
- | 需要截图证据 | 三个 bat 均有结构化输出,适合截图存档 |
-
- > **执行注意**:`tools/` 脚本是 `.bat` 文件,需在 Windows 宿主机上双击运行或命令行执行,不能在 Kilo 内直接运行。Agent 应输出让用户自行执行的命令,方便截图取证。`debug-gdb.bat` 和 `check-anti-inject.bat` 均依赖 `su`(root 权限)。
+ 日志分析:读 `.txt` 日志,按时间戳锚定用户操作窗口,关联多模块信号。详见 `references/behavior-analysis.md` 交叉分析。
---
- ## 十、SSL/TLS 忽略检测 — 全层参考
-
- Android App 的网络通信分 5 层架构,每层 SSL 忽略的检测 API 不同。**`onReceivedSslError` 是 WebView 专属,不能用于检测 OkHttp。**
-
- ### 10.1 检测判定标准速查
-
- | 层 | 框架 | 检测点 | 漏洞特征 |
- |----|------|--------|---------|
- | Java HTTP | OkHttp 3/4 | `X509TrustManager.checkServerTrusted()` | 方法体为空 |
- | Java HTTP | OkHttp 3/4 | `HostnameVerifier.verify()` | `return true;` |
- | Java HTTP | Retrofit | 同上(底层即 OkHttp) | 查 `OkHttpClient` 构造处 |
- | Java HTTP | HttpURLConnection | `HttpsURLConnection.setDefaultSSLSocketFactory()` | 注入 TrustAll SSLSocketFactory |
- | Java HTTP | HttpURLConnection | `HttpsURLConnection.setDefaultHostnameVerifier()` | `return true;` |
- | Java HTTP | Volley | `HurlStack` 自定义 `SSLSocketFactory` | 查 `Volley.newRequestQueue` 的 stack 参数 |
- | WebView | 系统 WebView | `WebViewClient.onReceivedSslError()` | 调用了 `handler.proceed()` |
- | WebView | 腾讯 X5 | `IX5WebViewClient.onReceivedSslError()` | 同上,`com.tencent.smtt.sdk` |
- | WebView | UC | `com.uc.webview.export.WebViewClient` | 同上 |
- | Native | OpenSSL/BoringSSL | `SSL_CTX_set_verify(ctx, mode, ...)` | `mode` = `SSL_VERIFY_NONE` (0x00) |
- | Native | OpenSSL | `SSL_set_verify(ssl, mode, ...)` | 同上 |
- | Native | libcurl | `curl_easy_setopt(handle, CURLOPT_SSL_VERIFYPEER, 0L)` | 参数为 0 |
- | Native | MbedTLS | `mbedtls_ssl_conf_authmode()` | 设为 `MBEDTLS_SSL_VERIFY_NONE` |
- | WebSocket | OkHttp WS | 继承 OkHttp SSL 配置 | 同上 OkHttp 检测点 |
- | WebSocket | Java-WebSocket | 自定义 `SSLSocketFactory` | TrustAll 工厂 |
- | 全局配置 | Network Security Config | `res/xml/network_security_config.xml` | `<certificates src="user" />` 信任用户证书 |
- | 全局配置 | Network Security Config | 同上 XML | `<domain-config cleartextTrafficPermitted="true">` |
-
- ### 10.2 静态检测方法 (JADX)
-
- | 目标 | JADX 搜索关键字 |
- |------|----------------|
- | OkHttp TrustAll | `checkServerTrusted` → 方法体为空 |
- | OkHttp HostnameVerifier | `HostnameVerifier` → `return true` |
- | OkHttp Builder 注入 | `sslSocketFactory` + `hostnameVerifier` |
- | WebView SSL 忽略 | `onReceivedSslError` → 含 `proceed()` |
- | X5 WebView | `com.tencent.smtt` + `onReceivedSslError` |
- | Native SSL_VERIFY_NONE | 搜索字符串 `SSL_VERIFY_NONE` |
- | Network Security Config | `jadx_get_resource_file("res/xml/network_security_config.xml")` |
-
- ### 10.3 动态检测方法 (Frida)
-
- | 目标 | Hook 点 | 模块 |
- |------|--------|------|
- | OkHttp SSLContext Init | `javax.net.ssl.SSLContext.init()` → 检查 `TrustManager[]` 是否 TrustAll | `ssl_plaintext.js` |
- | OkHttp HostnameVerifier | `javax.net.ssl.HostnameVerifier.verify()` → 日志 `return true` | `ssl_plaintext.js` |
- | WebView SSL 忽略 | `android.webkit.SslErrorHandler.proceed()` | 自定义 hook |
- | X5 WebView SSL | `com.tencent.smtt.sdk.SslErrorHandler.proceed()` | 自定义 hook |
- | Native SSL_CTX_set_verify | `libssl.so` → `SSL_CTX_set_verify` → 打印 `mode` 参数 | `native_hooker.js` |
- | Native curl | `libcurl.so` → `curl_easy_setopt` → `CURLOPT_SSL_VERIFYPEER` | `native_hooker.js` |
-
- ### 10.4 检测优先级(金融 App 视角)
-
- | 优先级 | 检测层 | 原因 |
- |--------|--------|------|
- | **P0** | OkHttp `X509TrustManager` + `HostnameVerifier` | 覆盖率 90%+,API 全量暴露 |
- | **P0** | WebView `onReceivedSslError` → `proceed()` | H5 页面含敏感操作 |
- | **P1** | X5 WebView 同等接口 | 金融 App 高占比 |
- | **P1** | Native `SSL_CTX_set_verify` | 核心交易/加密常走 Native |
- | **P2** | Network Security Config 信任用户证书 | 配合抓包利用 |
- | **P2** | HttpURLConnection / Volley / libcurl | 老项目残留 |
-
- ### 10.5 常见误判
+ ## references 指引
- | 误判 | 纠正 |
+ | 场景 | 读取 |
|------|------|
- | 在 OkHttp 层搜索 `onReceivedSslError` | 这是 WebView API,OkHttp 不适用 |
- | 在 WebView 层搜索 `checkServerTrusted` | 这是 OkHttp API,WebView 不适用 |
- | 看到 `SSLSocketFactory` 自定义就判漏洞 | 需确认 TrustManager 是否 TrustAll,正常自定义 TLS 协议版本是安全的 |
- | 看到 `onReceivedSslError` 重写就判漏洞 | 必须确认内部调用了 `handler.proceed()`,仅 log 不调用是安全的 |
-
- ---
-
- ## 注意事项
- - Frida 16.x 与 15.x/14.x 有 API 差异
- - ARM64 有指针认证(PAC),iOS arm64e 需特殊处理
- - Android 不同 API Level 的 libart.so 内部符号可能不同
- - `tools/` 下的 `.bat` 脚本为独立检测工具,无需 Frida 即可运行,详见 §九
- - `exit_blocker` 替换退出后检测线程可能空转 — 正常,阻止了退出操作
- - 详细 API 用法:`API-REFERENCE.md`
- - 反检测 Pipeline 详情:`ANTI-DETECTION.md`
-
+ | 反检测 Pipeline / 经验模式 / 检测工具 | `references/anti-detection.md` |
+ | 脱壳流程 / 壳识别 / 提取修复 | `references/unpacking.md` |
+ | 加密决策树 / SSL/TLS / Hook 模板 / Python 工作流 | `references/crypto-hook.md` |
+ | 行为摸底 / 网络协议 / 污点追踪 / 交叉分析 | `references/behavior-analysis.md` |
+ | 攻击面枚举 / 序列化 / WebView / jadx-mcp | `references/static-analysis.md` |
+ | SO 层分析 / Ghidra / unidbg / 分层下钻 / 字符串引用 | `references/native-analysis.md` |
+ | 故障排查(无输出/闪退/init_hook 陷阱) | `references/troubleshooting.md` |
+ | Frida API 手册(写自定义 hook 时) | `references/api-reference.md` |
+ | 参考文章索引(脱壳原理/攻击面方法论) | `references/articles.md` |