feat(dfp): 🔑 RC4 key=APK内嵌appkey常量(datadiv@3912240), 全流程零设备依赖闭环 (R38-R39)
This commit is contained in:
@@ -1599,3 +1599,34 @@ full: 7c da | 11 | 69 c9 f5 28 9c 4d 46 | 95 6f 21 | 10 bb 80
|
|||||||
|
|
||||||
### 端到端伪造路径 (已无阻塞)
|
### 端到端伪造路径 (已无阻塞)
|
||||||
JSON 构造 → gzip_wrap → RC4(捕获 key) → wire body → POST. 密钥每轮经 hook_hy.js 一挂即得.
|
JSON 构造 → gzip_wrap → RC4(捕获 key) → wire body → POST. 密钥每轮经 hook_hy.js 一挂即得.
|
||||||
|
|
||||||
|
## §11.67 R38-R39: 🏆 密钥溯源定案 — RC4 key = APK 内嵌常量, 全流程零设备依赖 (2026-08-29)
|
||||||
|
|
||||||
|
### 追踪过程 (教训先行)
|
||||||
|
- spawn 存活问题: 必须用两阶段配方三脚本 (bypass_msaoaid_maps_art_callsite + mask_frida_maps_only + 11s 后 patch_guard_block_termination) — 单挂 skip_cleanup 会在登录态路径秒死 (用户指正!)
|
||||||
|
- 登录 md5 正确姿势: udbauthunify!0x32e71c = md5_sret(out&, in), x0 是输出槽 onEnter 必空 (R34 误读根源); 输入 = k1(32hex) + getkey(nonce) → AESkey 派生 (R14 已知链, 本次活体复证 in1 hex 直接可见 "865a4924..." 前缀!)
|
||||||
|
|
||||||
|
### 密钥来源定案 (三层排除 → 实锤)
|
||||||
|
1. 排除落盘: /data/data 全 grep hex 文本 + turing 文件原始字节 = 无
|
||||||
|
2. 排除设备派生: md5(hdid/guid/signature/...) 全否; 跨天跨重注册稳定 → 非会话随机
|
||||||
|
3. **实锤: evidence/dfp_datadiv_full.json 字符串表 @3912240 = "865a4924a40897ac1fcfe6b4c2abc798", 紧邻 "dfpReport"/"appid"/"terminal"/"huyaudbnimoui"** — libhydeviceid .data (datadiv 加密) 内嵌 turing appkey 常量!
|
||||||
|
|
||||||
|
### 865a49 家族全景 (三个兄弟, 各属一个子系统)
|
||||||
|
| 常量 | 尾 6 hex | 来源 | 用途 |
|
||||||
|
|---|---|---|---|
|
||||||
|
| RC4 key | abc798 | libhydeviceid .data 常量 (datadiv) | **dfpReport 报文加密** |
|
||||||
|
| k1 | cbb0e3 | BusinessCfg+0x10 (datadiv) | appSign=md5("5008_ver_k1") + AESkey=md5_char16(k1+getkey) |
|
||||||
|
| channelKey | cbb045 | resinfo (AES-ECB, HuyaUdb... 密钥) 服务端下发 | t1 设备指纹 |
|
||||||
|
|
||||||
|
### 全链终态 (每一步都有代码级证据)
|
||||||
|
```
|
||||||
|
APK 内嵌: appkey 865a..c798 (datadiv 加密 .data) ──运行时解密──┐
|
||||||
|
指纹 JSON 采集 (Athena/Hebe/terminal/version) │
|
||||||
|
→ gzip (1f8b08, level9) │
|
||||||
|
→ RC4(appkey) keystream XOR ────────────────────────────────┘
|
||||||
|
→ wire body (前10B=keystream⊕gzip头, 即"magic")
|
||||||
|
→ taf/wup 封装 → POST wsapi.huya.com /dfpReport
|
||||||
|
```
|
||||||
|
- 登录链 (已破): uid+getkey → xxtea/AES-OTP (§11.44); appSign=md5("5008_ver_k1") (R15)
|
||||||
|
- 会话链: Perseus SecureRandom 16字符 → RSA 信封 (R34) — 独立通道, 与 dfpReport 无关
|
||||||
|
- **端到端伪造 = 纯离线**: JSON 构造 + tools/dfp_rc4.py (key 为常量), 无需设备!
|
||||||
|
|||||||
@@ -0,0 +1,379 @@
|
|||||||
|
{
|
||||||
|
"script-loaded": [
|
||||||
|
{
|
||||||
|
"event": "script-loaded"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"java-md5-hooked": [
|
||||||
|
{
|
||||||
|
"event": "java-md5-hooked"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"java-digest": [
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "a255b00458d1a5c548aaf768e9f5b959",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "1aeb7bdcd488671fe3561207696d77bf",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "2e5f190dcb08d31b7c833a5c2f9172e1",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "c2d705043d7ca0f8842702eeef30b6a4",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "71ee9b2f9c6819caa86764ece8950905",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "a255b00458d1a5c548aaf768e9f5b959",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "1aeb7bdcd488671fe3561207696d77bf",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "2e5f190dcb08d31b7c833a5c2f9172e1",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "c2d705043d7ca0f8842702eeef30b6a4",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "71ee9b2f9c6819caa86764ece8950905",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "a255b00458d1a5c548aaf768e9f5b959",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "1aeb7bdcd488671fe3561207696d77bf",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "2e5f190dcb08d31b7c833a5c2f9172e1",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "c2d705043d7ca0f8842702eeef30b6a4",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "71ee9b2f9c6819caa86764ece8950905",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "a255b00458d1a5c548aaf768e9f5b959",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "1aeb7bdcd488671fe3561207696d77bf",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "2e5f190dcb08d31b7c833a5c2f9172e1",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "c2d705043d7ca0f8842702eeef30b6a4",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "71ee9b2f9c6819caa86764ece8950905",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "a255b00458d1a5c548aaf768e9f5b959",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "1aeb7bdcd488671fe3561207696d77bf",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "2e5f190dcb08d31b7c833a5c2f9172e1",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "c2d705043d7ca0f8842702eeef30b6a4",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "71ee9b2f9c6819caa86764ece8950905",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "a255b00458d1a5c548aaf768e9f5b959",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "1aeb7bdcd488671fe3561207696d77bf",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "2e5f190dcb08d31b7c833a5c2f9172e1",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "c2d705043d7ca0f8842702eeef30b6a4",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "71ee9b2f9c6819caa86764ece8950905",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "a255b00458d1a5c548aaf768e9f5b959",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "1aeb7bdcd488671fe3561207696d77bf",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "2e5f190dcb08d31b7c833a5c2f9172e1",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "c2d705043d7ca0f8842702eeef30b6a4",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "71ee9b2f9c6819caa86764ece8950905",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "a255b00458d1a5c548aaf768e9f5b959",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "1aeb7bdcd488671fe3561207696d77bf",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "2e5f190dcb08d31b7c833a5c2f9172e1",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "c2d705043d7ca0f8842702eeef30b6a4",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "71ee9b2f9c6819caa86764ece8950905",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "a255b00458d1a5c548aaf768e9f5b959",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "1aeb7bdcd488671fe3561207696d77bf",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "2e5f190dcb08d31b7c833a5c2f9172e1",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "c2d705043d7ca0f8842702eeef30b6a4",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "71ee9b2f9c6819caa86764ece8950905",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "a255b00458d1a5c548aaf768e9f5b959",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "1aeb7bdcd488671fe3561207696d77bf",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "2e5f190dcb08d31b7c833a5c2f9172e1",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "c2d705043d7ca0f8842702eeef30b6a4",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "71ee9b2f9c6819caa86764ece8950905",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "a255b00458d1a5c548aaf768e9f5b959",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "1aeb7bdcd488671fe3561207696d77bf",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "2e5f190dcb08d31b7c833a5c2f9172e1",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "c2d705043d7ca0f8842702eeef30b6a4",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "71ee9b2f9c6819caa86764ece8950905",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "46c8591368de4c8f19f8668b45b80e31",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "4fcb130eb3b47f0d3916d1cd92a5b4be",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "93cfd7f6e97ff8df4e1a255cb9bf8dac",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "6d50d5b8412eba4daa4363bac3fd4cbc",
|
||||||
|
"in_parts": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "0708f0ba839c2be70fd0a39d8bb6fb03",
|
||||||
|
"in_parts": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"hy-armed": [
|
||||||
|
{
|
||||||
|
"event": "hy-armed"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,379 @@
|
|||||||
|
{
|
||||||
|
"script-loaded": [
|
||||||
|
{
|
||||||
|
"event": "script-loaded"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"hy-armed": [
|
||||||
|
{
|
||||||
|
"event": "hy-armed"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"java-md5-hooked": [
|
||||||
|
{
|
||||||
|
"event": "java-md5-hooked"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"java-digest": [
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "37fe6db03febc05f6966dfc84c19a8ab"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "46c8591368de4c8f19f8668b45b80e31"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "4fcb130eb3b47f0d3916d1cd92a5b4be"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "93cfd7f6e97ff8df4e1a255cb9bf8dac"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "a255b00458d1a5c548aaf768e9f5b959"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "1aeb7bdcd488671fe3561207696d77bf"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "5cb4c302204a8fbc8dad11a838a3d2ba"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "c2d705043d7ca0f8842702eeef30b6a4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "a255b00458d1a5c548aaf768e9f5b959"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "1aeb7bdcd488671fe3561207696d77bf"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "2e5f190dcb08d31b7c833a5c2f9172e1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "c2d705043d7ca0f8842702eeef30b6a4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "71ee9b2f9c6819caa86764ece8950905"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "a255b00458d1a5c548aaf768e9f5b959"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "a255b00458d1a5c548aaf768e9f5b959"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "1aeb7bdcd488671fe3561207696d77bf"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "c9a4f4089e6493d7e4cb4ba8df7e40fe"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "c2d705043d7ca0f8842702eeef30b6a4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "8bedcda6f084bfd2d1ebfe397aff0e8f"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "a255b00458d1a5c548aaf768e9f5b959"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "a255b00458d1a5c548aaf768e9f5b959"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "1aeb7bdcd488671fe3561207696d77bf"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "2e5f190dcb08d31b7c833a5c2f9172e1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "c2d705043d7ca0f8842702eeef30b6a4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "71ee9b2f9c6819caa86764ece8950905"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "34887b39dfd812a2f9b4ffecdfca5a15"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "a255b00458d1a5c548aaf768e9f5b959"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "1aeb7bdcd488671fe3561207696d77bf"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "2e5f190dcb08d31b7c833a5c2f9172e1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "c2d705043d7ca0f8842702eeef30b6a4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "71ee9b2f9c6819caa86764ece8950905"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "e91a91301fa53aa2d15c999739a58e44"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "a255b00458d1a5c548aaf768e9f5b959"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "1aeb7bdcd488671fe3561207696d77bf"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "2e5f190dcb08d31b7c833a5c2f9172e1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "c2d705043d7ca0f8842702eeef30b6a4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "71ee9b2f9c6819caa86764ece8950905"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "a255b00458d1a5c548aaf768e9f5b959"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "1aeb7bdcd488671fe3561207696d77bf"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "2e5f190dcb08d31b7c833a5c2f9172e1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "c2d705043d7ca0f8842702eeef30b6a4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "71ee9b2f9c6819caa86764ece8950905"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "a255b00458d1a5c548aaf768e9f5b959"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "1aeb7bdcd488671fe3561207696d77bf"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "2e5f190dcb08d31b7c833a5c2f9172e1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "c2d705043d7ca0f8842702eeef30b6a4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "71ee9b2f9c6819caa86764ece8950905"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "a255b00458d1a5c548aaf768e9f5b959"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "1aeb7bdcd488671fe3561207696d77bf"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "2e5f190dcb08d31b7c833a5c2f9172e1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "c2d705043d7ca0f8842702eeef30b6a4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "71ee9b2f9c6819caa86764ece8950905"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "a255b00458d1a5c548aaf768e9f5b959"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "1aeb7bdcd488671fe3561207696d77bf"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "2e5f190dcb08d31b7c833a5c2f9172e1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "c2d705043d7ca0f8842702eeef30b6a4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "71ee9b2f9c6819caa86764ece8950905"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "a255b00458d1a5c548aaf768e9f5b959"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "1aeb7bdcd488671fe3561207696d77bf"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "2e5f190dcb08d31b7c833a5c2f9172e1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "c2d705043d7ca0f8842702eeef30b6a4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "71ee9b2f9c6819caa86764ece8950905"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "a255b00458d1a5c548aaf768e9f5b959"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "1aeb7bdcd488671fe3561207696d77bf"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "2e5f190dcb08d31b7c833a5c2f9172e1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "c2d705043d7ca0f8842702eeef30b6a4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "71ee9b2f9c6819caa86764ece8950905"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "a255b00458d1a5c548aaf768e9f5b959"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "1aeb7bdcd488671fe3561207696d77bf"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "2e5f190dcb08d31b7c833a5c2f9172e1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "c2d705043d7ca0f8842702eeef30b6a4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "java-digest",
|
||||||
|
"algo": "MD5",
|
||||||
|
"out": "71ee9b2f9c6819caa86764ece8950905"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"script-loaded": [
|
||||||
|
{
|
||||||
|
"event": "script-loaded"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"script-loaded": [
|
||||||
|
{
|
||||||
|
"event": "script-loaded"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,58 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""R36: hook libz deflate/inflate — 抓 XXTEA 输入明文 + 隐藏加密路径 backtrace."""
|
||||||
|
import json, subprocess, time
|
||||||
|
from pathlib import Path
|
||||||
|
import frida
|
||||||
|
|
||||||
|
REMOTE="127.0.0.1:31878"; ADB="5dd8c93f"; PACKAGE="com.duowan.kiwi"
|
||||||
|
RE=Path("/Users/yml/codes/Reverse-Engineering-Agent-Universal-v3.0")
|
||||||
|
HERE=Path(__file__).resolve().parent.parent
|
||||||
|
OUT=HERE/"evidence"/("keytrace_"+time.strftime("%H%M%S")+".json")
|
||||||
|
|
||||||
|
def clear_turing():
|
||||||
|
for d in ("app_turingdfp","app_turingfd"):
|
||||||
|
subprocess.run(["adb","-s",ADB,"shell","su","-c",f"rm -rf /data/data/{PACKAGE}/{d}/*"],capture_output=True)
|
||||||
|
subprocess.run(["adb","-s",ADB,"shell","su","-c",f"find /data/data/{PACKAGE} -name 'resinfo*' -delete"],capture_output=True)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
clear_turing()
|
||||||
|
d=frida.get_device_manager().add_remote_device(REMOTE)
|
||||||
|
subprocess.run(["adb","-s",ADB,"shell","am","force-stop",PACKAGE],capture_output=True)
|
||||||
|
time.sleep(1.5)
|
||||||
|
pid=d.spawn([PACKAGE]); print(f"[*] spawn pid={pid}",flush=True)
|
||||||
|
s=d.attach(pid)
|
||||||
|
try:
|
||||||
|
b=s.create_script((RE/"evidence/scripts/bypass_msaoaid_maps_skip_cleanup.js").read_text()); b.load()
|
||||||
|
except Exception as e: print(f"[*] bypass err {e}",flush=True)
|
||||||
|
d.resume(pid)
|
||||||
|
result={}; got={"post":False,"out":False}
|
||||||
|
seen_fns=set()
|
||||||
|
def events_ok(p):
|
||||||
|
seen_fns.add(p.get('fn')); return True
|
||||||
|
def on(m,_):
|
||||||
|
if m.get("type")=="error":
|
||||||
|
txt=str(m)
|
||||||
|
if "ClassNotFoundException" in txt: return
|
||||||
|
print(f"[JS] {txt[:160]}",flush=True); return
|
||||||
|
p=m.get("payload") or {}
|
||||||
|
ev=p.get("event")
|
||||||
|
if ev=="post": got["post"]=True; print(f"[+] POST {p['num']}B",flush=True)
|
||||||
|
elif ev=="armed-hy": print("[*] hy chain armed",flush=True)
|
||||||
|
elif ev=="call":
|
||||||
|
if len(seen_fns)<99: pass
|
||||||
|
elif ev=="call" and events_ok(p): got["out"]=True
|
||||||
|
elif ev=="deflate-found": print(f"[*] deflate export in {p['mod']}",flush=True)
|
||||||
|
elif ev=="inflate-in": print(f"[+] inflate-in {p['len']}B via {p['mod']}",flush=True)
|
||||||
|
result.setdefault(ev or "misc",[]).append(p)
|
||||||
|
sc=s.create_script((HERE/"tools/frida/hook_keytrace.js").read_text())
|
||||||
|
sc.on("message",on); sc.load()
|
||||||
|
t0=time.time()
|
||||||
|
while time.time()-t0<150:
|
||||||
|
time.sleep(2)
|
||||||
|
if got["out"] and got["post"]: time.sleep(4); break
|
||||||
|
json.dump(result,open(OUT,"w"),indent=2)
|
||||||
|
print(f"[*] saved {OUT}",flush=True)
|
||||||
|
try: s.detach()
|
||||||
|
except Exception: pass
|
||||||
|
|
||||||
|
if __name__=="__main__": main()
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""R38b: RC4 key 诞生点追踪 (MD5 transform 消息积累)."""
|
||||||
|
import json, subprocess, time
|
||||||
|
from pathlib import Path
|
||||||
|
import frida
|
||||||
|
|
||||||
|
REMOTE="127.0.0.1:31878"; ADB="5dd8c93f"; PACKAGE="com.duowan.kiwi"
|
||||||
|
RE=Path("/Users/yml/codes/Reverse-Engineering-Agent-Universal-v3.0")
|
||||||
|
HERE=Path(__file__).resolve().parent.parent
|
||||||
|
OUT=HERE/"evidence"/("keytrace2_"+time.strftime("%H%M%S")+".json")
|
||||||
|
|
||||||
|
def clear_turing():
|
||||||
|
for d in ("app_turingdfp","app_turingfd"):
|
||||||
|
subprocess.run(["adb","-s",ADB,"shell","su","-c",f"rm -rf /data/data/{PACKAGE}/{d}/*"],capture_output=True)
|
||||||
|
subprocess.run(["adb","-s",ADB,"shell","su","-c",f"find /data/data/{PACKAGE} -name 'resinfo*' -delete"],capture_output=True)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
clear_turing()
|
||||||
|
d=frida.get_device_manager().add_remote_device(REMOTE)
|
||||||
|
subprocess.run(["adb","-s",ADB,"shell","am","force-stop",PACKAGE],capture_output=True)
|
||||||
|
time.sleep(1.5)
|
||||||
|
pid=d.spawn([PACKAGE]); print(f"[*] spawn pid={pid}",flush=True)
|
||||||
|
s=d.attach(pid)
|
||||||
|
try:
|
||||||
|
b=s.create_script((RE/"evidence/scripts/bypass_msaoaid_maps_skip_cleanup.js").read_text()); b.load()
|
||||||
|
except Exception as e: print(f"[*] bypass err {e}",flush=True)
|
||||||
|
d.resume(pid)
|
||||||
|
result={}; state={"post":False,"key":False}
|
||||||
|
def on(m,_):
|
||||||
|
if m.get("type")=="error":
|
||||||
|
t=str(m)
|
||||||
|
if "ClassNotFoundException" not in t: print(f"[JS] {t[:150]}",flush=True)
|
||||||
|
return
|
||||||
|
p=m.get("payload") or {}
|
||||||
|
ev=p.get("event")
|
||||||
|
if ev=="post": state["post"]=True; print("[+] POST fired",flush=True)
|
||||||
|
elif ev=="key-site": state["key"]=True; print(f"[+] KEY ARRIVED: {p.get('key')} md5calls={p.get('md5calls')} states={p.get('nstates')}",flush=True)
|
||||||
|
elif ev=="hy-armed": print("[*] hy armed",flush=True)
|
||||||
|
elif ev=="java-md5-hooked": print("[*] java digest hooked",flush=True)
|
||||||
|
elif ev=="key-copies-done": print(f"[*] key copies: {p.get('n')}",flush=True)
|
||||||
|
result.setdefault(ev or "misc",[]).append(p)
|
||||||
|
sc=s.create_script((HERE/"tools/frida/hook_keytrace2.js").read_text())
|
||||||
|
sc.on("message",on); sc.load()
|
||||||
|
t0=time.time()
|
||||||
|
while time.time()-t0<220:
|
||||||
|
time.sleep(3)
|
||||||
|
if state["key"] and state["post"]: time.sleep(5); break
|
||||||
|
json.dump(result,open(OUT,"w"),indent=2)
|
||||||
|
print(f"[*] saved {OUT} post={state['post']} key={state['key']}",flush=True)
|
||||||
|
try: s.detach()
|
||||||
|
except Exception: pass
|
||||||
|
|
||||||
|
if __name__=="__main__": main()
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""R39: 登录流程 md5 输入捕获 — 两阶段配方 (与 hook_final_capture.py 同款):
|
||||||
|
spawn挂起 -> 双bypass装载 -> resume -> 稳定11s -> patch_guard -> 业务钩子
|
||||||
|
"""
|
||||||
|
import json, time
|
||||||
|
from pathlib import Path
|
||||||
|
import frida
|
||||||
|
|
||||||
|
REMOTE="127.0.0.1:31878"; PACKAGE="com.duowan.kiwi"
|
||||||
|
RE=Path("/Users/yml/codes/Reverse-Engineering-Agent-Universal-v3.0")
|
||||||
|
HERE=Path(__file__).resolve().parent.parent
|
||||||
|
OUT=HERE/"evidence"/("loginmd5_"+time.strftime("%H%M%S")+".json")
|
||||||
|
|
||||||
|
def main():
|
||||||
|
d=frida.get_device_manager().add_remote_device(REMOTE)
|
||||||
|
pid=d.spawn([PACKAGE])
|
||||||
|
print(f"[*] spawned {pid}",flush=True)
|
||||||
|
s=d.attach(pid)
|
||||||
|
# 双重防护: callsite bypass + maps 掩盖
|
||||||
|
s.create_script((RE/"evidence/scripts/bypass_msaoaid_maps_art_callsite.js").read_text()).load()
|
||||||
|
s.create_script((RE/"evidence/scripts/mask_frida_maps_only.js").read_text()).load()
|
||||||
|
d.resume(pid)
|
||||||
|
print("[*] resumed, 稳定 11s...",flush=True)
|
||||||
|
time.sleep(11)
|
||||||
|
s.create_script((RE/"evidence/scripts/patch_guard_block_termination.js").read_text()).load()
|
||||||
|
print("[*] patch_guard on",flush=True)
|
||||||
|
|
||||||
|
result={}; state={"udb":0}
|
||||||
|
def on(m,_):
|
||||||
|
if m.get("type")=="error":
|
||||||
|
t=str(m)
|
||||||
|
if "ClassNotFoundException" not in t: print(f"[JS] {t[:150]}",flush=True)
|
||||||
|
return
|
||||||
|
p=m.get("payload") or {}
|
||||||
|
ev=p.get("event")
|
||||||
|
if ev=="udb-md5":
|
||||||
|
state["udb"]+=1
|
||||||
|
print(f"[+] udb-md5 #{state['udb']} in1={str(p.get('in1'))[:100]} out={str(p.get('out'))[:80]}",flush=True)
|
||||||
|
elif ev=="udb-armed": print("[*] udb md5 armed",flush=True)
|
||||||
|
elif ev=="java-digest":
|
||||||
|
out=p.get('out','')
|
||||||
|
if out.startswith('865a') or out.startswith('') and False: pass
|
||||||
|
print(f"[J] digest {p.get('algo')} out={out[:16]} in={repr((p.get('in_parts') or ''))[:70]}",flush=True)
|
||||||
|
result.setdefault(ev or "misc",[]).append(p)
|
||||||
|
sc=s.create_script((HERE/"tools/frida/hook_login_md5.js").read_text())
|
||||||
|
sc.on("message",on); sc.load()
|
||||||
|
print("[*] 请在 App 中: 退出登录 -> 账号密码重新登录 (窗口 8 分钟)",flush=True)
|
||||||
|
t0=time.time()
|
||||||
|
while time.time()-t0<480:
|
||||||
|
time.sleep(5)
|
||||||
|
if state["udb"]>=12: time.sleep(6); break
|
||||||
|
json.dump(result,open(OUT,"w"),indent=2)
|
||||||
|
print(f"[*] saved {OUT} udb={state['udb']}",flush=True)
|
||||||
|
try: s.detach()
|
||||||
|
except Exception: pass
|
||||||
|
|
||||||
|
if __name__=="__main__": main()
|
||||||
+5
-2
@@ -8,8 +8,11 @@
|
|||||||
不是魔数! 密钥同则 magic 同)
|
不是魔数! 密钥同则 magic 同)
|
||||||
-> 尾部 10B 为 gzip 流之后的附加段 (decompressobj unused_data)
|
-> 尾部 10B 为 gzip 流之后的附加段 (decompressobj unused_data)
|
||||||
|
|
||||||
密钥 = 32 字符 hex ASCII 串 (如 865a4924a40897ac1fcfe6b4c2abc798), 每注册轮换.
|
密钥 = 32 字符 hex ASCII 串 = **APK 内嵌静态常量** (非随机、非设备派生!):
|
||||||
捕获点: libhydeviceid.so!0x60e6c onEnter x1 = 密钥串 (tools/frida/hook_hy.js).
|
libhydeviceid.so .data (datadiv 加密) 字符串表 @offset 3912240, 紧邻 "dfpReport"/"appid"/"terminal":
|
||||||
|
[3912240] "865a4924a40897ac1fcfe6b4c2abc798" ← turing appkey/通道密钥 (R39 实锤)
|
||||||
|
同族兄弟: k1=...cbb0e3 (BusinessCfg+0x10), channelKey=...cbb045 (resinfo 服务端下发)
|
||||||
|
新版本 APK 离线重提取: unidbg hydev harness 跑 datadiv 解密, 或 0x60e6c x1 一次抓取.
|
||||||
XXTEA/静态密钥 f15e... 与 dfpReport 无关 (那是 hdid 子系统) — 45 函数零调用之谜即此.
|
XXTEA/静态密钥 f15e... 与 dfpReport 无关 (那是 hdid 子系统) — 45 函数零调用之谜即此.
|
||||||
"""
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|||||||
@@ -0,0 +1,143 @@
|
|||||||
|
// R38: 追踪 RC4 key (32hex) 的诞生点 — Java MessageDigest + udb md5 + 0x60e6c 反查副本
|
||||||
|
'use strict';
|
||||||
|
function emit(o){ try{ send(o); }catch(e){} }
|
||||||
|
function hexb(p,n){ try{ return Array.from(new Uint8Array(p.readByteArray(n))).map(b=>('0'+b.toString(16)).slice(-2)).join(''); }catch(e){ return ''; } }
|
||||||
|
var nEvents = 0;
|
||||||
|
|
||||||
|
// ---- 1) Java MessageDigest 全量 (md5/sha1) ----
|
||||||
|
setImmediate(function(){
|
||||||
|
Java.perform(function(){
|
||||||
|
try {
|
||||||
|
var MD = Java.use('java.security.MessageDigest');
|
||||||
|
MD.digest.overload().implementation = function(){
|
||||||
|
var algo = this.getAlgorithm();
|
||||||
|
var out = this.digest();
|
||||||
|
try {
|
||||||
|
var hex = Array.prototype.map.call(out, function(b){ return ('0'+(b&0xff).toString(16)).slice(-2); }).join('');
|
||||||
|
nEvents++;
|
||||||
|
emit({event:'java-digest', algo: algo, out: hex});
|
||||||
|
} catch(e){}
|
||||||
|
return out;
|
||||||
|
};
|
||||||
|
MD.digest.overload('[B').implementation = function(inp){
|
||||||
|
var algo = this.getAlgorithm();
|
||||||
|
var out = this.digest(inp);
|
||||||
|
try {
|
||||||
|
var hex = Array.prototype.map.call(out, function(b){ return ('0'+(b&0xff).toString(16)).slice(-2); }).join('');
|
||||||
|
var inHex = Array.prototype.map.call(inp, function(b){ return ('0'+(b&0xff).toString(16)).slice(-2); }).join('');
|
||||||
|
nEvents++;
|
||||||
|
emit({event:'java-digest', algo: algo, out: hex, in_hex: inHex.substring(0,2048)});
|
||||||
|
} catch(e){}
|
||||||
|
return out;
|
||||||
|
};
|
||||||
|
emit({event:'java-md5-hooked'});
|
||||||
|
} catch(e){ emit({event:'java-e', e:String(e).substring(0,150)}); }
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// ---- 2) udbauthunify md5 (0x32e71c) 原始参数 ----
|
||||||
|
function armUdb(){
|
||||||
|
var u = Process.findModuleByName('libudbauthunify.so');
|
||||||
|
if (!u) return false;
|
||||||
|
try {
|
||||||
|
Interceptor.attach(u.base.add(0x32e71c), {
|
||||||
|
onEnter(args){
|
||||||
|
this.a = [];
|
||||||
|
for (var i=0;i<4;i++) this.a.push({x:String(args[i]), h:hexb(args[i],96)});
|
||||||
|
this.lr = this.returnAddress;
|
||||||
|
},
|
||||||
|
onLeave(){
|
||||||
|
try {
|
||||||
|
var outs = [];
|
||||||
|
for (var i=0;i<2;i++) outs.push(hexb(this.a[i].x ? ptr(this.a[i].x) : ptr(0), 96));
|
||||||
|
nEvents++;
|
||||||
|
emit({event:'udb-md5', args:this.a, out_re:outs, lr: String(this.lr)});
|
||||||
|
} catch(e){}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
emit({event:'udb-armed'});
|
||||||
|
return true;
|
||||||
|
} catch(e){ return false; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---- 3) 0x60e6c 到位点 + 全内存反查 key 副本 ----
|
||||||
|
function armHy(){
|
||||||
|
var h = Process.findModuleByName('libhydeviceid.so');
|
||||||
|
if (!h) return false;
|
||||||
|
try {
|
||||||
|
Interceptor.attach(h.base.add(0x60e6c), {
|
||||||
|
onEnter(args){
|
||||||
|
try {
|
||||||
|
var s = '';
|
||||||
|
try { s = args[1].readCString(64); } catch(e){}
|
||||||
|
nEvents++;
|
||||||
|
emit({event:'key-site', x1:String(args[1]), key:s});
|
||||||
|
if (s && s.length === 32) {
|
||||||
|
setTimeout(function(){
|
||||||
|
var pat = '';
|
||||||
|
for (var i=0;i<16;i++) pat += s.substr(i,2).split('').join('')+' ' ;
|
||||||
|
pat = s.substring(0,16).split('').map(function(c){ return ('0'+c.charCodeAt(0).toString(16)).slice(-2); }).join(' ');
|
||||||
|
var n=0;
|
||||||
|
for (var r of Process.enumerateRanges('rw-')) {
|
||||||
|
if (r.size > 96*1024*1024) continue;
|
||||||
|
var ms=[];
|
||||||
|
try { ms = Memory.scanSync(r.base, r.size, pat); } catch(e){ continue; }
|
||||||
|
for (var m of ms){
|
||||||
|
if (n>=10) break;
|
||||||
|
n++;
|
||||||
|
emit({event:'key-copy', addr:String(m.address), src: r.file? r.file.path : String(r.base), around: hexb(m.address.sub(160), 352)});
|
||||||
|
}
|
||||||
|
if (n>=10) break;
|
||||||
|
}
|
||||||
|
emit({event:'key-copies-done', n:n});
|
||||||
|
}, 50);
|
||||||
|
}
|
||||||
|
} catch(e){ emit({event:'key-e', e:String(e).substring(0,150)}); }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// 4) JNI 边界 0x20e924 参数
|
||||||
|
Interceptor.attach(h.base.add(0x20e924), {
|
||||||
|
onEnter(args){
|
||||||
|
if (nEvents > 3000) return;
|
||||||
|
var rows=[];
|
||||||
|
for (var i=0;i<3;i++) rows.push({x:String(args[i]), h:hexb(args[i],48)});
|
||||||
|
nEvents++;
|
||||||
|
emit({event:'jni-boundary', args:rows});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
emit({event:'hy-armed'});
|
||||||
|
return true;
|
||||||
|
} catch(e){ emit({event:'hy-e', e:String(e).substring(0,150)}); return false; }
|
||||||
|
}
|
||||||
|
|
||||||
|
var udb=false, hy=false;
|
||||||
|
var poll = setInterval(function(){
|
||||||
|
if (!udb) udb = armUdb();
|
||||||
|
if (!hy) hy = armHy();
|
||||||
|
if (udb && hy) clearInterval(poll);
|
||||||
|
}, 200);
|
||||||
|
|
||||||
|
// ---- 5) SSL_write 同轮密文 ----
|
||||||
|
var done = false;
|
||||||
|
for (var mod of Process.enumerateModules()){
|
||||||
|
var addr = null;
|
||||||
|
try { addr = mod.getExportByName('SSL_write'); } catch(e){}
|
||||||
|
if (!addr) continue;
|
||||||
|
Interceptor.attach(addr, {
|
||||||
|
onEnter(args){
|
||||||
|
if (done) return;
|
||||||
|
try {
|
||||||
|
var num = args[2].toInt32();
|
||||||
|
if (num < 60 || num > 60000) return;
|
||||||
|
var u = new Uint8Array(args[1].readByteArray(num));
|
||||||
|
var s = '';
|
||||||
|
for (var i=0;i<u.length;i++) s += (u[i]>=32 && u[i]<127) ? String.fromCharCode(u[i]) : '.';
|
||||||
|
if (s.indexOf('dfpReport') < 0) return;
|
||||||
|
done = true;
|
||||||
|
var hex = Array.prototype.map.call(u, function(x){return ('0'+x.toString(16)).slice(-2)}).join('');
|
||||||
|
emit({event:'post', num:num, hex:hex});
|
||||||
|
} catch(e){}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
emit({event:'script-loaded'});
|
||||||
@@ -0,0 +1,137 @@
|
|||||||
|
// R38b: RC4 key 诞生点终极追踪 — MD5 transform 消息积累 + 到位点反查 + Java digest 输入
|
||||||
|
'use strict';
|
||||||
|
function emit(o){ try{ send(o); }catch(e){} }
|
||||||
|
function hexb(p,n){ try{ return Array.from(new Uint8Array(p.readByteArray(n))).map(b=>('0'+b.toString(16)).slice(-2)).join(''); }catch(e){ return ''; } }
|
||||||
|
var nEvents = 0;
|
||||||
|
var CAP = 2500;
|
||||||
|
|
||||||
|
// ---- 1) MD5 transform 消息积累 (libhydeviceid!0xc37c0, ror#7 核心) ----
|
||||||
|
var md5msgs = {}; // state -> [blockHex,...]
|
||||||
|
var md5order = [];
|
||||||
|
var md5calls = 0;
|
||||||
|
|
||||||
|
function armHy(){
|
||||||
|
var h = Process.findModuleByName('libhydeviceid.so');
|
||||||
|
if (!h) return false;
|
||||||
|
try {
|
||||||
|
Interceptor.attach(h.base.add(0xc37c0), {
|
||||||
|
onEnter(args){
|
||||||
|
if (md5calls > 1200) return;
|
||||||
|
md5calls++;
|
||||||
|
var st = args[0].toString();
|
||||||
|
var blk = hexb(args[1], 64);
|
||||||
|
if (!md5msgs[st]) { md5msgs[st] = []; md5order.push(st); if (md5order.length>60) {} }
|
||||||
|
md5msgs[st].push(blk);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// ---- 2) 0x60e6c 到位点 ----
|
||||||
|
Interceptor.attach(h.base.add(0x60e6c), {
|
||||||
|
onEnter(args){
|
||||||
|
try {
|
||||||
|
var s = '';
|
||||||
|
try { s = args[1].readCString(64); } catch(e){}
|
||||||
|
if (s.length !== 32) return;
|
||||||
|
nEvents++;
|
||||||
|
emit({event:'key-site', key:s, md5calls: md5calls, nstates: md5order.length});
|
||||||
|
// 倒出全部 MD5 消息 (每 state 拼接 blocks, 截 512B)
|
||||||
|
var dumped = 0;
|
||||||
|
for (var st of md5order){
|
||||||
|
if (dumped >= 40) break;
|
||||||
|
var full = md5msgs[st].join('');
|
||||||
|
nEvents++;
|
||||||
|
emit({event:'md5-msg', state: st, nblk: md5msgs[st].length, hex: full.substring(0, 1024)});
|
||||||
|
dumped++;
|
||||||
|
}
|
||||||
|
// 内存反查 key 副本
|
||||||
|
setTimeout(function(){
|
||||||
|
var pat = s.substring(0,16).split('').map(function(c){ return ('0'+c.charCodeAt(0).toString(16)).slice(-2); }).join(' ');
|
||||||
|
var n=0;
|
||||||
|
for (var r of Process.enumerateRanges('rw-')){
|
||||||
|
if (r.size > 96*1024*1024) continue;
|
||||||
|
var ms=[];
|
||||||
|
try { ms = Memory.scanSync(r.base, r.size, pat); } catch(e){ continue; }
|
||||||
|
for (var m of ms){
|
||||||
|
if (n>=10) break;
|
||||||
|
n++; nEvents++;
|
||||||
|
emit({event:'key-copy', addr:String(m.address), src: r.file? r.file.path : String(r.base), around: hexb(m.address.sub(192), 448)});
|
||||||
|
}
|
||||||
|
if (n>=10) break;
|
||||||
|
}
|
||||||
|
emit({event:'key-copies-done', n:n});
|
||||||
|
}, 30);
|
||||||
|
} catch(e){ emit({event:'key-e', e:String(e).substring(0,150)}); }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
emit({event:'hy-armed'});
|
||||||
|
return true;
|
||||||
|
} catch(e){ return false; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---- 3) Java MessageDigest: update 输入积累 ----
|
||||||
|
setImmediate(function(){
|
||||||
|
Java.perform(function(){
|
||||||
|
try {
|
||||||
|
var MD = Java.use('java.security.MessageDigest');
|
||||||
|
var pend = {}; // hashcode -> [hexchunks]
|
||||||
|
MD.update.overload('[B').implementation = function(b){
|
||||||
|
try {
|
||||||
|
var k = this.hashCode();
|
||||||
|
if (!pend[k]) pend[k]=[];
|
||||||
|
if (pend[k].length < 8) {
|
||||||
|
pend[k].push(Array.prototype.map.call(b, function(x){return ('0'+(x&0xff).toString(16)).slice(-2);}).join('').substring(0,2048));
|
||||||
|
}
|
||||||
|
} catch(e){}
|
||||||
|
return this.update(b);
|
||||||
|
};
|
||||||
|
MD.digest.overload().implementation = function(){
|
||||||
|
var algo = this.getAlgorithm();
|
||||||
|
var out = this.digest();
|
||||||
|
try {
|
||||||
|
var k = this.hashCode();
|
||||||
|
var hex = Array.prototype.map.call(out, function(b){ return ('0'+(b&0xff).toString(16)).slice(-2); }).join('');
|
||||||
|
if (nEvents < CAP) { nEvents++; emit({event:'java-digest', algo:algo, out:hex, in_parts:(pend[k]||[]).join('')}); }
|
||||||
|
delete pend[k];
|
||||||
|
} catch(e){}
|
||||||
|
return out;
|
||||||
|
};
|
||||||
|
MD.digest.overload('[B').implementation = function(b){
|
||||||
|
var algo = this.getAlgorithm();
|
||||||
|
var out = this.digest(b);
|
||||||
|
try {
|
||||||
|
var hex = Array.prototype.map.call(out, function(b2){ return ('0'+(b2&0xff).toString(16)).slice(-2); }).join('');
|
||||||
|
var inHex = Array.prototype.map.call(b, function(x){return ('0'+(x&0xff).toString(16)).slice(-2);}).join('');
|
||||||
|
if (nEvents < CAP) { nEvents++; emit({event:'java-digest', algo:algo, out:hex, in_parts:inHex.substring(0,4096)}); }
|
||||||
|
} catch(e){}
|
||||||
|
return out;
|
||||||
|
};
|
||||||
|
emit({event:'java-md5-hooked'});
|
||||||
|
} catch(e){ emit({event:'java-e', e:String(e).substring(0,150)}); }
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// ---- 4) SSL_write 同轮标记 ----
|
||||||
|
var done = false;
|
||||||
|
for (var mod of Process.enumerateModules()){
|
||||||
|
var addr = null;
|
||||||
|
try { addr = mod.getExportByName('SSL_write'); } catch(e){}
|
||||||
|
if (!addr) continue;
|
||||||
|
Interceptor.attach(addr, {
|
||||||
|
onEnter(args){
|
||||||
|
if (done) return;
|
||||||
|
try {
|
||||||
|
var num = args[2].toInt32();
|
||||||
|
if (num < 60 || num > 60000) return;
|
||||||
|
var u = new Uint8Array(args[1].readByteArray(num));
|
||||||
|
var s = '';
|
||||||
|
for (var i=0;i<u.length;i++) s += (u[i]>=32 && u[i]<127) ? String.fromCharCode(u[i]) : '.';
|
||||||
|
if (s.indexOf('dfpReport') < 0) return;
|
||||||
|
done = true;
|
||||||
|
nEvents++;
|
||||||
|
emit({event:'post', num:num});
|
||||||
|
} catch(e){}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
var armed=false;
|
||||||
|
var poll = setInterval(function(){ if (armHy()){ armed=true; clearInterval(poll);} }, 200);
|
||||||
|
emit({event:'script-loaded'});
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
// R39: 登录时 udbauthunify md5 正确捕获 — sret 约定: x0=out槽, x1=in
|
||||||
|
'use strict';
|
||||||
|
function emit(o){ try{ send(o); }catch(e){} }
|
||||||
|
function hexb(p,n){ try{ return Array.from(new Uint8Array(p.readByteArray(n))).map(b=>('0'+b.toString(16)).slice(-2)).join(''); }catch(e){ return ''; } }
|
||||||
|
function rdStr(p){
|
||||||
|
// libc++ std::string: b0&1==0 -> SSO (len=b0>>1, data=+1); else heap (len@+8, data@*+16)
|
||||||
|
try {
|
||||||
|
var b0 = p.readU8();
|
||||||
|
if ((b0 & 1) === 0){
|
||||||
|
var l = b0 >> 1;
|
||||||
|
if (l > 22) return {t:'susp', len:l, v: hexb(p.add(1), 48)};
|
||||||
|
return {t:'s', len:l, v: p.add(1).readUtf8String(l)};
|
||||||
|
}
|
||||||
|
var hl = p.add(8).readU64().toNumber();
|
||||||
|
if (hl > 8192) return {t:'err', v:'too long '+hl};
|
||||||
|
return {t:'b64h', len:hl, v: hexb(p.add(16).readPointer(), Math.min(hl, 512))};
|
||||||
|
} catch(e){ return {t:'err', v:String(e)}; }
|
||||||
|
}
|
||||||
|
var n = 0;
|
||||||
|
function armUdb(){
|
||||||
|
var u = Process.findModuleByName('libudbauthunify.so');
|
||||||
|
if (!u) return false;
|
||||||
|
try {
|
||||||
|
Interceptor.attach(u.base.add(0x32e71c), {
|
||||||
|
onEnter(args){
|
||||||
|
this.outp = args[0];
|
||||||
|
this.in1 = rdStr(args[1]);
|
||||||
|
this.in2 = rdStr(args[2]);
|
||||||
|
this.raw = [hexb(args[1], 64), hexb(args[2], 64)];
|
||||||
|
this.lr = String(this.returnAddress);
|
||||||
|
},
|
||||||
|
onLeave(){
|
||||||
|
if (n > 300) return;
|
||||||
|
n++;
|
||||||
|
emit({event:'udb-md5', in1:this.in1, in2:this.in2, raw:this.raw,
|
||||||
|
out: rdStr(this.outp), lr:this.lr});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
emit({event:'udb-armed'});
|
||||||
|
return true;
|
||||||
|
} catch(e){ emit({event:'udb-e', e:String(e).substring(0,150)}); return false; }
|
||||||
|
}
|
||||||
|
var armed = false;
|
||||||
|
var poll = setInterval(function(){ if (armUdb()){ armed=true; clearInterval(poll); } }, 200);
|
||||||
|
// Java digest 带输入 (登录 Java 侧可能也算)
|
||||||
|
setImmediate(function(){
|
||||||
|
Java.perform(function(){
|
||||||
|
try {
|
||||||
|
var MD = Java.use('java.security.MessageDigest');
|
||||||
|
var pend = {};
|
||||||
|
MD.update.overload('[B').implementation = function(b){
|
||||||
|
try {
|
||||||
|
var k=this.hashCode();
|
||||||
|
if(!pend[k]) pend[k]=[];
|
||||||
|
if (pend[k].length<8) pend[k].push(Array.prototype.map.call(b,function(x){return ('0'+(x&0xff).toString(16)).slice(-2);}).join('').substring(0,2048));
|
||||||
|
} catch(e){}
|
||||||
|
return this.update(b);
|
||||||
|
};
|
||||||
|
MD.digest.overload().implementation = function(){
|
||||||
|
var out=this.digest();
|
||||||
|
try {
|
||||||
|
var k=this.hashCode();
|
||||||
|
var oh=Array.prototype.map.call(out,function(b){return ('0'+(b&0xff).toString(16)).slice(-2);}).join('');
|
||||||
|
emit({event:'java-digest', algo:this.getAlgorithm(), out:oh, in_parts:(pend[k]||[]).join('')});
|
||||||
|
delete pend[k];
|
||||||
|
} catch(e){}
|
||||||
|
return out;
|
||||||
|
};
|
||||||
|
MD.digest.overload('[B').implementation = function(b){
|
||||||
|
var out=this.digest(b);
|
||||||
|
try {
|
||||||
|
var oh=Array.prototype.map.call(out,function(b2){return ('0'+(b2&0xff).toString(16)).slice(-2);}).join('');
|
||||||
|
var ih=Array.prototype.map.call(b,function(x){return ('0'+(x&0xff).toString(16)).slice(-2);}).join('');
|
||||||
|
emit({event:'java-digest', algo:this.getAlgorithm(), out:oh, in_parts:ih.substring(0,4096)});
|
||||||
|
} catch(e){}
|
||||||
|
return out;
|
||||||
|
};
|
||||||
|
emit({event:'java-md5-hooked'});
|
||||||
|
} catch(e){}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
emit({event:'script-loaded'});
|
||||||
Reference in New Issue
Block a user