From d2adfb25ad4104d23ccf8bdcba9a6c8f9db81c5e Mon Sep 17 00:00:00 2001 From: yml2213 Date: Fri, 28 Aug 2026 19:13:36 +0800 Subject: [PATCH] =?UTF-8?q?feat(huya):=20doLaunch=20live=E5=AF=B9=E6=8B=8D?= =?UTF-8?q?=E5=AE=9A=E6=A1=88=20-=20=E4=BF=A1=E5=B0=81/=E9=94=AE/=E8=B7=AF?= =?UTF-8?q?=E5=BE=84=E8=A2=AB=E6=9C=8D=E5=8A=A1=E7=AB=AF=E6=8E=A5=E5=8F=97?= =?UTF-8?q?,=20tReq=E5=80=BC=E6=81=92=E5=AE=9A=E6=8B=92=E7=BB=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - App侧全细节确认: a09.getRequestKey=tReq / UniPacket(true)=v3 / 值=write(struct,0) / URL=/launch/doLaunch / getOtherParams追加 platform/version/channel/uid 键 / 传输类型服务端动态下发(HTTP是否真渠道未定) - live诊断: E(空值)->require field / F(缺键)->not found key / G(0x0c)->完全复现 'read struct type mismatch tag0 type12' -> 服务端确实解析tReq值, 语义与本地djce不同 - 工具升级: --live 用5键 App同等 map; 悬而未决点=需App真实doLaunch帧(约束内路径全探) - logcat无klog / xlog+mmap2 mars压缩不解 / 冷启动走缓存不发网络launch / 禁pm clear - 可选项: 代理+CA被动抓包 / 模拟器新装 / 继续抠mars xlog --- docs/HUYA_HDID_ALGORITHM_GEN.md | 33 +++++++++++++++++++++++++++++++++ tools/huya_launch_mint.py | 30 +++++++++++++++++++++++++----- 2 files changed, 58 insertions(+), 5 deletions(-) diff --git a/docs/HUYA_HDID_ALGORITHM_GEN.md b/docs/HUYA_HDID_ALGORITHM_GEN.md index f5043ef..af5f405 100644 --- a/docs/HUYA_HDID_ALGORITHM_GEN.md +++ b/docs/HUYA_HDID_ALGORITHM_GEN.md @@ -317,3 +317,36 @@ lib 内置大量模拟器检测串(qemu_pipe / mumuvmm / genymotion / windroye - **传输待 live 实测确认**:hyns/KiwiServant(a09)栈的最终 URL/头(先按 wup.huya.com 平铺, 与服务端对拍后再校准);响应 sBuffer 可能是 map 假象(解析器已兼容 bytes/struct 两种形态,sGuid_candidates 兜底)。 + +### 11.7 doLaunch live 对拍结论(2026-08-29 实测,wire 已 App 对齐) +- **已确认 App 侧全部细节**(bjj/cjj 构建器反编译): + - `a09.getRequestKey() = "tReq"`,`getResponseKey() = "tRsp"`; + - `bjj.a(servant,func,key,req,otherParams)` + `new UniPacket(true)`(= v3 + _newData + map);值 = `write(struct,0)` = struct_begin(0)+fields+end,map 值头 + SIMPLE_LIST(0x1d) 与登录黄金帧逐字节同构; + - **URL 路径 = /launch/doLaunch**(hyns 约定 `"/"+servant+"/"+func`); + - **sBuffer 额外键**:a09.getOtherParams() 追加 `platform/version/channel/(yyuid/uid/imei)` + (u9a.put 裸字符串值,map 头含全部键,实测服务端接受此形态); + - **传输类型服务端动态下发**:`FunctionTransportModule.getTransportType("launch#doLaunch")` + 查动态配置 mFunctionTransportMap(缺省 mDefaultTransportType)——HTTP 是否 doLaunch 真渠道 + 未定;zij.a().b() 还支持 cdn.wup.huya.com IP 列表直连 :80(明文 HTTP/WS 形态)。 +- **live 实测序列**(全部 HTTP 200,服务端回声 servant/func + requestId): + | 变体 | STATUS_RESULT_DESC | + |---|---| + | 键 `_wup_data` / 根路径 | `UniAttribute not found key:tReq` | + | 键 `tReq`(值=wrapped/SIMPLE_LIST) | `read 'struct' type mismatch, tag: 0, get type: 12.` | + | 键 `tReq` 值=裸字段/STRING4/guid=空/黄金guid/5键 map | 同上(**恒定**) | + | 值=0x0c 单字节 | 完全复现同错(=tag0 ZERO,服务端确实在解析值) | + | 值=空 | `require field not exist, tag: 0`(解析走到流尾) | + | 无 tReq 键 | `UniAttribute not found key:tReq` | +- **结论**:信封/键/路径已被服务端接受;tReq 值永远被拒且错误与内容无关 → 最可能 = + 服务端对 tReq 值的解析语义与本地 djce 版本不同(或 HTTP 非 doLaunch 真渠道)。 + 悬而未决点,定案需 App 真实 doLaunch 帧: + - 约束内路径全试过:logcat 无 klog(自定义 xlog 落盘);xlog/mmap2 拉取为 mars 压缩 + 格式,无公开魔数解不动;17:17 冷启动走 `initCache from disc`(缓存未过期 → 不发 + 网络 doLaunch);禁 pm clear ⇒ 无法制造首次启动场景;无模拟器;spawn/attach 收敛。 + - 可选项:① 授权一次"代理+系统CA"被动抓包(可逆,无 pm clear/attach);② 装模拟器 + 全新安装(必然触发 doLaunch);③ 继续纯 PC 侧拆 mars xlog。 +- 前置条件不变:**live 复测前先落 docs §11.5 步骤 1 的确定性实验设计**(同一虚拟指纹 + 多次请求 → sGuid 是否一致 / 是否 = f(字段))。若 sGuid 随机签发,则铸币=整套身份模板 + 随机化后由登录链验证服务端接受度。 diff --git a/tools/huya_launch_mint.py b/tools/huya_launch_mint.py index 64f0f78..bdcc287 100644 --- a/tools/huya_launch_mint.py +++ b/tools/huya_launch_mint.py @@ -16,8 +16,13 @@ - --dump : 打印请求体结构/hex (不联网) - --live [url] : 真实发送 (默认 https://wup.huya.com) -传输细节 (hyns/KiwiServant a09 栈) 未完全静态定案: 先按经典 UniPacket + wup.huya.com -平铺, live 测试确认服务端接受度后再校准; 字段/tag 均已按 dex 精确还原. +实测状态 (2026-08-29): + - 信封/路径/键均被服务端接受: servant/func 回声, UniAttribute 找到 tReq 键; + 但 tReq 值被拒: "read 'struct' type mismatch, tag: 0, get type: 12" (恒定). + - 诊断: 值=0x0c 复现同错 (E:空值->require field; F:缺键->not found key) => 服务端在 + 解析值, 但首字段始终判为 ZERO. 疑点: a09 传输类型由服务端动态配置 + (IFunctionTranspotModule.getTransportType("launch#doLaunch")), HTTP POST 路径 + 未必是 doLaunch 真渠道; wire 已逐字节对齐 App (见 docs §11.6), 待真机帧定案. 用法: python tools/huya_launch_mint.py --self-test @@ -97,10 +102,20 @@ def build_live_launch_wup(profile: dict, request_id: int | None = None) -> bytes request_id = int.from_bytes(__import__("os").urandom(4), "big") & 0x7FFFFFFF req_jce = encode_live_launch_req(profile) + # App 端 a09.getOtherParams() 还会追加 platform/version/channel/(yyuid/uid/imei) 键 + entries = [("tReq", ("bytes", req_jce))] + for k in ("platform", "version", "channel", "yyuid", "uid", "imei"): + v = profile.get(k) + if v: + entries.append((k, ("string", v))) sb = _Writer() - sb.map_begin(0, 1) - sb.string(0, "_wup_data") - sb.bytes(1, req_jce) + sb.map_begin(0, len(entries)) + for k, (kind, val) in entries: + sb.string(0, k) + if kind == "bytes": + sb.bytes(1, val) + else: + sb.string(1, val) s_buffer = sb.get() w = _Writer() @@ -272,6 +287,11 @@ DEFAULT_PROFILE = { "net_type": "", "token": "", "cookie": "", + "platform": "android", + "version": "13.4.22", + "channel": "xxx", + "yyuid": "0", + "uid": "0", }