Skip to main content

app-reverse

移动端(Android/iOS)加密参数逆向 — 当 Web 抓包发现某 sign/token/加密参数其实由配套 App 生成、JS 端根本找不到时,下沉到 App 层定位加密函数。覆盖 jadx/apktool 反编译、smali 阅读、Frida hook 关键加密函数(Cipher/Mac/MessageDigest/自定义 native)提取密钥与输入输出样本、SSL Pinning 绕过、native .so 用 IDA/Ghidra 分析、JNI 桥追踪;iOS 砸壳/class-dump/objection 思路。目标=拿到「函数位置 + 一组输入→输出样本 + 密钥来源」,再转交 param-encryptor 纯算复现、reverse-parity-gate 对齐。触发词:「App 生成的签名」「抓包参数 JS 里找不到」「下沉到 App 层」「jadx」「frida」「smali」「so 逆向」「移动端加密」「SSL Pinning」「砸壳」。边界:只负责「从 App 定位到加密函数 + 拿样本」,算法复现转交 param-encryptor,交付前对齐转交 reverse-parity-gate。

Quellinformationen

Repository
woxiangyangzhimao/skills
Letzte Quellaktivität
2. Juli 2026 um 04:14
Erkannte Sprache von SKILL.md
Chinesisch
Sterne
14
Forks
8

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
app-reverse
description_zh
移动端逆向(Android/iOS)— 抓包参数 JS 里找不到、其实由 App 生成时,jadx/Frida hook 提密钥+样本,转 param-encryptor
description
移动端(Android/iOS)加密参数逆向 — 当 Web 抓包发现某 sign/token/加密参数其实由配套 App 生成、JS 端根本找不到时,下沉到 App 层定位加密函数。覆盖 jadx/apktool 反编译、smali 阅读、Frida hook 关键加密函数(Cipher/Mac/MessageDigest/自定义 native)提取密钥与输入输出样本、SSL Pinning 绕过、native .so 用 IDA/Ghidra 分析、JNI 桥追踪;iOS 砸壳/class-dump/objection 思路。目标=拿到「函数位置 + 一组输入→输出样本 + 密钥来源」,再转交 param-encryptor 纯算复现、reverse-parity-gate 对齐。触发词:「App 生成的签名」「抓包参数 JS 里找不到」「下沉到 App 层」「jadx」「frida」「smali」「so 逆向」「移动端加密」「SSL Pinning」「砸壳」。边界:只负责「从 App 定位到加密函数 + 拿样本」,算法复现转交 param-encryptor,交付前对齐转交 reverse-parity-gate。
# App Reverse · 移动端加密参数逆向 > 核心场景:Web 抓包定位到某个 `sign`/`token`/`X-Sign` 加密参数,但翻遍 JS 都找不到生成位置——因为它其实是配套 **App**(Android/iOS)算出来后塞进请求的。此时 Web 链路走不通,必须下沉到 App 层。 > 核心理念:**定位加密函数(位置) → Hook 拿一组输入→输出样本 → 摸清密钥来源 → 转交 param-encryptor 纯算复现 → reverse-parity-gate 逐字节对齐**。 > 不在 App 里硬扣算法、不重打包跑业务、不绕风控——只把「黑盒加密」变成「已知输入输出 + 已知密钥」的纯算问题。 --- ## 一、Scope 与授权(与 web-reverse-master 同口径) - 只对**你被授权测试的系统、你自有的应用、公开学习目标、或防御/调试研究**作业。 - 不协助:账号滥用、绕过访问控制、凭据窃取、大规模抓取、对第三方服务的隐蔽规避、击穿生产反滥用系统。遇到这类请求,改写为防御性分析、插桩、限速设计或合规调试。 - 每一个算法结论在拿到**源码位置 / Hook 输出 / 真实样本 / 可复现本地测试**之前,一律视为「待验证」。 - 目标是第三方真实 App 时:完成定位与取样后先给 Plan,征得用户确认再写 Phase 4 生产代码。 - 本技能聚焦**读与观测**:反编译阅读、动态 Hook 观测、密钥取样。重打包/patch smali/绕 root 等**修改设备或应用**的动作,仅在用户明确要求且授权范围内进行,且默认不触碰。 --- ## 二、角色规则 **此 Skill 激活后,以移动端逆向工程师身份工作。** - 加密方式、密钥、IV 必须通过**动态 Hook 实证确认**,禁止从函数名猜测。 - 优先静态读懂逻辑(jadx/smali),读不动再上动态 Hook;能 Java 层 Hook 就不碰 native。 - 核心逻辑沉到 `.so`/native 时,明确切到 IDA/Ghidra,不在 Java 层死磕。 - 不做自动安装、不联网 bootstrap、不依赖任何 MCP server;所有工具均为**本机命令行**直连(adb/frida/jadx/apktool/objection)。工具缺失时给手动安装指引,由用户自行安装。 - **本技能不负责算法复现**。定位到加密函数并拿到样本后,产出交接物转交 `param-encryptor`;交付前用 `reverse-parity-gate` 对齐。 --- ## 三、环境与工具(均需手动安装,不自动装) > Windows + PowerShell。Python 一律用 `python3.11`(本机 `python`/`python3`/`py` 是坏的 Store stub)。 > 默认 **No-MCP 路由**:不依赖 `ida-pro-mcp` / `frida-mcp` 等;全部用命令行直连。若当前会话恰好暴露了对应 MCP 工具,可作为可选加速,但主路径始终是命令行。 | 工具 | 用途 | 手动安装 | 验证 | |------|------|---------|------| | `adb` | 设备连接 / 进程 / 日志 / 拉文件 | winget `Google.PlatformTools` 或官网 Android Platform-Tools 解压 | `adb devices` | | `jadx` | APK → Java 反编译阅读 | 官网 github.com/skylot/jadx Release 解压 | `jadx --version` | | `apktool` | APK 解包/看 smali/看 Manifest | github.com/iBotPeaches/Apktool 下 jar + bat | `apktool --version` | | `frida` / `frida-ps` | 动态 Hook(Java/native) | `python3.11 -m pip install frida-tools` | `frida-ps -U` | | `objection` | Frida 增强 REPL(免写脚本绕 pinning) | `python3.11 -m pip install objection` | `objection version` | | `ghidra` | `.so`/Mach-O 反编译(免费) | github.com/NationalSecurityAgency/ghidra Release | GUI 启动 | | IDA | `.so`/Mach-O 深度分析(商业) | hex-rays.com 官网 | GUI 启动 | | `unidbg` | 把 Android native `.so` 拉进 JVM **模拟执行**算 sign(无需真机) | github.com/zhkl0228/unidbg 源码 + `gradle build`(JDK 8+) | 跑通自带示例 | > 设备端还需 `frida-server`(与本机 frida 版本一致的对应架构二进制,从 frida GitHub Release 取)推到设备 `/data/local/tmp/` 并以 root 运行。这一步需要用户自备 root 设备/模拟器,本技能不代为安装。 **PowerShell 常用命令:** ```powershell # 设备 / 进程 adb devices frida-ps -U # 列出 USB 设备上的进程 frida-ps -Uai # 仅列已安装应用 # 反编译阅读 jadx -d .\jadx_out app.apk # Java 反编译落盘 jadx --deobf -d .\jadx_out app.apk # 混淆名时加去混淆 apktool d app.apk -o .\apktool_out # 解包看 smali + Manifest # 动态 Hook frida -U -f com.example.app -l hook.js --no-pause # spawn 注入 frida -U -n com.example.app -l hook.js # attach 到已运行进程 frida-trace -U -n com.example.app -j "javax.crypto.Cipher!*" # 快速追 Cipher # 拉 native 库出来分析 adb shell pm path com.example.app # 找 base.apk 路径 adb pull /data/app/.../base.apk . # 拉下来后解包取 lib/arm64-v8a/*.so ``` --- ## 四、纪律化流程(从 Web 下沉到 App,六步) > 每步带 CHECKPOINT 的必须达成后才能进入下一步。禁止跳步直接扣算法。 ### Step 0 — 确认「确实在 App 层」(下沉判据) 由 Web 抓包侧(`reverse-traffic-triage` / `web-reverse-master`)转入。进入本技能前先确认: - 目标参数在 **App 发出的请求**里出现,但同站 H5/Web 的 JS 调用栈里**写不出该参数**(initiator 追不到、断点打不上)。 - 或该参数只在 App 原生请求里有,H5 请求里压根没有。 🔴 **CHECKPOINT**:能说清「这个 `sign` 在 Web JS 里找不到、确属 App 生成」才下沉;否则退回 `reverse-traffic-triage` 继续在 Web 侧定位,别白拆 App。 ### Step 1 — Triage:摸清 App 构成 不急着 Hook。先建立地图。 ```powershell jadx -d .\jadx_out app.apk apktool d app.apk -o .\apktool_out ``` 看四样: - `AndroidManifest.xml`:主 `package`、`application` 类、入口 `activity`、网络相关 service。 - 主包结构:业务包名、第三方 SDK(okhttp/retrofit/网络库)。 - `lib/` 下是否有 `.so`(`arm64-v8a`/`armeabi-v7a`)——决定后面要不要切 native。 - 是否**加壳**(360/腾讯乐固/梆梆/爱加密):jadx 打开几乎全是空壳类 / `attachBaseContext` 里解密 dex → 已加固。加固需先脱壳(用户授权范围内),本技能不展开脱壳工具链,仅标注「需脱壳」。 🔴 **CHECKPOINT**:记录 `包名 + 入口类 + 有无 .so + 是否加固`。加固未脱壳 → 静态读不动,直接走 Step 3 动态 Hook。 ### Step 2 — 静态定位候选加密函数 在 `jadx_out` 里搜目标参数名 + 加密关键词,缩小到几个候选函数。 常见关键词:`sign` `token` `encrypt` `cipher` `getInstance` `doFinal` `Mac` `digest` `MessageDigest` `secretKey` `IvParameterSpec` `base64` + 你的**参数名本身**(如 `X-Sign`、`mtgsig`)。 读到这些就是命中: - `javax.crypto.Cipher.getInstance("AES/CBC/PKCS5Padding")` → 对称加密。 - `javax.crypto.Mac.getInstance("HmacSHA256")` → HMAC 签名。 - `java.security.MessageDigest.getInstance("MD5"/"SHA-256")` → 哈希。 - `System.loadLibrary("xxx")` + `native` 方法 → 核心在 `.so`,Java 只是 JNI 壳。 🔴 **CHECKPOINT**:列出 ≥1 个候选函数(类名+方法名+文件)。混淆严重读不出 → 不硬读,转 Step 3 用 Hook 反向定位。 ### Step 3 — 动态 Hook 拿密钥 + 输入输出样本(本技能核心产出) 无论静态是否读懂,都用 Frida hook **标准加密 API**,直接截获算法、密钥、明文、密文。这是把黑盒变白盒的关键一步。 把下面脚本存为 `hook_crypto.js`,`frida -U -f <包名> -l hook_crypto.js --no-pause` 注入,然后在 App 里触发那个请求: ```javascript // hook_crypto.js — 截获 Java 层标准加密 API 的算法/密钥/输入/输出 function hex(bytes) { if (bytes === null) return "null"; return Java.array('byte', bytes).map(b => ('0' + (b & 0xff).toString(16)).slice(-2)).join(''); } function utf8(bytes) { try { return Java.use('java.lang.String').$new(bytes); } catch (e) { return '<bin>'; } } Java.perform(function () { // ── 对称加密 Cipher:拿算法 + 密钥 + IV ── var Cipher = Java.use('javax.crypto.Cipher'); Cipher.getInstance.overload('java.lang.String').implementation = function (algo) { console.log('[Cipher.getInstance] ' + algo); return this.getInstance(algo); }; var SecretKeySpec = Java.use('javax.crypto.spec.SecretKeySpec'); SecretKeySpec.$init.overload('[B', 'java.lang.String').implementation = function (k, a) { console.log('[Key] algo=' + a + ' key(hex)=' + hex(k) + ' key(utf8)=' + utf8(k)); return this.$init(k, a); }; var IvSpec = Java.use('javax.crypto.spec.IvParameterSpec'); IvSpec.$init.overload('[B').implementation = function (iv) { console.log('[IV] ' + hex(iv)); return this.$init(iv); }; Cipher.doFinal.overload('[B').implementation = function (input) { var out = this.doFinal(input); console.log('[Cipher.doFinal] in(hex)=' + hex(input) + '\n in(utf8)=' + utf8(input) + '\n out(hex)=' + hex(out)); return out; }; // ── HMAC / Mac:拿密钥 + 输入 + 输出 ── var Mac = Java.use('javax.crypto.Mac'); Mac.getInstance.overload('java.lang.String').implementation = function (a) { console.log('[Mac.getInstance] ' + a); return this.getInstance(a); }; Mac.doFinal.overload('[B').implementation = function (input) { var out = this.doFinal(input); console.log('[Mac.doFinal] in=' + utf8(input) + '\n out(hex)=' + hex(out)); return out; }; // ── MessageDigest:哈希签名常见 ── var MD = Java.use('java.security.MessageDigest'); MD.digest.overload('[B').implementation = function (input) { var out = this.digest(input); console.log('[MD.digest] algo=' + this.getAlgorithm() + '\n in=' + utf8(input) + '\n out(hex)=' + hex(out)); return out; }; }); ``` 如果 Step 2 发现核心是**自定义 native 方法**(Java 只是 `native` 声明),改 hook 它的 JNI 导出: ```javascript // hook 自定义 native 函数(先用 frida-trace 或读 .so 导出表确定名字/模块) Interceptor.attach(Module.findExportByName('libsign.so', 'Java_com_example_Sign_sign'), { onEnter: function (args) { // args[0]=JNIEnv, args[1]=jclass/this;后续是入参,需按签名读 this.start = Date.now(); console.log('[native sign] called'); }, onLeave: function (retval) { console.log('[native sign] returned in ' + (Date.now() - this.start) + 'ms'); } }); ``` > 取样要求(交给 param-encryptor 前必须够用): > - **≥3 组** 输入→输出样本,覆盖典型输入、空输入、边界输入。 > - 明确记录:算法字符串(如 `AES/CBC/PKCS5Padding`)、key(hex+utf8)、IV、输入编码、输出格式(hex/base64)。 > - **密钥来源**:是硬编码常量、接口下发、还是设备指纹派生?这决定能否纯算复现。 🔴 **CHECKPOINT · 关键门控**:拿到 `算法 + 密钥 + 密钥来源 + ≥3 组 输入→输出样本` → 进入交接。任一缺失 → 不要宣称定位完成,继续 Hook 或回 Step 2/4。 ### Step 4 — 排障:Hook 不到时 请求带加密参数发出了,但上面脚本没打印 → 多半是**没走标准 JCE API**,或被 SSL Pinning / root 检测挡在前面。对照「失败模式表」处理。常用绕过(仅授权范围内): ```powershell # objection 一键绕 SSL Pinning + root 检测,便于先抓到明文请求确认参数确实在这个流程里生成 objection -g com.example.app explore # 进入 REPL 后: # android sslpinning disable # android root disable # 或 Frida 通用 pinning bypass 脚本 frida -U -f com.example.app -l ssl_pinning_bypass.js --no-pause ``` 绕过 pinning 的目的只有一个:**让你能用代理(Burp/mitmproxy)看清楚 App 到底发了什么、加密参数长什么样**,从而回到 Step 2/3 精确定位。不是为了篡改业务。 ### Step 5 — native 分流(核心在 `.so` 时) Java 层只是 JNI 包装、`System.loadLibrary` 后逻辑消失、签名在 `.so` 里 → 切静态反汇编: ```powershell # 从设备/APK 取出目标 .so adb pull /data/app/.../lib/arm64-v8a/libsign.so . ``` - 用 **Ghidra**(免费)或 **IDA** 打开 `.so`,看导出表(`Java_*` JNI 函数)、字符串(密钥常量、算法名常常以明文字符串躺在 `.rodata`)。 - 目标不是读懂整个 `.so`,而是:**确认算法 + 找出密钥/盐/常量**,再回 Step 3 用 Frida hook 该 native 函数拿 运行时输入输出样本对账。 - 静态(看常量)+ 动态(Hook 取样)**双向印证**,比纯静态啃汇编快得多。 - **第三条路 — 模拟执行**:不想上真机 Hook、或想要可移植纯算时,用 **unidbg**(`zhkl0228/unidbg`,见上方工具表)把 `.so` 拉进 JVM 模拟跑,喂输入拿输出、按报错补齐缺失的 JNI/syscall,即可脱离设备复现 sign。适合"算法在 native、又要纯算落地"的场景。 🔴 **CHECKPOINT**:`.so` 里能定位到算法 + 关键常量,且 Frida 能 hook 到该函数拿样本 → 回 Step 3 的取样标准收口。 ### Step 6 — iOS(简述思路,同样产出「函数位置 + 样本 + 密钥」) iOS 流程与 Android 对称,工具不同: - **砸壳**:App Store 下载的二进制是加密的,先解密。Hook/分析前必须砸壳。常用 `frida-ios-dump`(需越狱设备或可注入环境)拿到解密 IPA。 - **class-dump**:对解密后的二进制 `class-dump` 导出 ObjC 头文件,定位疑似签名/加密类与方法名(`-sign`、`-encrypt`、`-hmac`)。 - **Frida hook**:hook `CommonCrypto` 的 `CCCrypt`(对称加密)、`CCHmac`(HMAC),onEnter 时 `hexdump` 读 key/iv/明文,拿算法 + 密钥 + 输入输出。 - **objection**:`objection -g <bundleid> explore` → `ios sslpinning disable` / `ios jailbreak disable`,同样为了先抓到明文请求确认参数来源。 - Swift 符号用 `swift-demangle` 还原;`.dylib`/Mach-O 深度分析用 Ghidra/IDA/Hopper。 🔴 **CHECKPOINT**:iOS 侧同样要收口到 `算法 + 密钥 + 密钥来源 + ≥3 组样本`,标准与 Android 一致。 --- ## 五、失败模式表 | 症状 | 原因 | 一线修复 | 仍失败兜底 | |------|------|---------|----------| | 触发请求了,Cipher/Mac/MD hook 全无打印 | 没走标准 JCE,用了自研/native 加密 | 读 Step 2 候选找 `native` 方法 / `.so` | Step 5 反汇编 `.so` + hook JNI 导出 | | frida 注入即闪退 / 进程消失 | App 有 frida-server / root 检测 | objection `android root disable`;改 attach 而非 spawn | 自定义 anti-frida bypass 脚本(端口/字符串检测) | | `frida-ps -U` 列不出进程 | frida-server 没起/版本不符/无 root | 推对应架构 frida-server 到 `/data/local/tmp` 并 root 运行,版本对齐本机 frida | 换 root 模拟器 / frida-gadget 注入(需重签) | | 抓不到明文请求,全是 TLS 密文 | SSL Pinning | objection `android sslpinning disable` | Frida 通用 pinning bypass / 系统证书 | | jadx 打开几乎全是空类 | App 加固(壳) | 标注「需脱壳」,直接走动态 Hook | 用户授权下脱壳(本技能不含脱壳链) |
Auf GitHub ansehen
Diese SKILL.md ist sehr gross, daher zeigt SkillsMP hier nur den ersten Abschnitt. Auf GitHub ansehen