Files
notiMessage/docs/TNG_captcha逆向.md
mars f9426d6b68 chore: 清理临时逆向脚本,保留 TNG 安装工具与 captcha 文档
删除未跟踪的一次性 _*.py 扫描脚本,并从仓库移除已过时辅助脚本。
2026-08-04 13:48:47 +08:00

65 lines
3.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# TNG eWallet 滑动验证码(阿里云 Captcha逆向笔记2026-08-03
## 现象
注册/登录手机号页点「继续」→ 弹阿里云滑动拼图验证 → 滑块拖对通过 →
**不返回**TTCaptcha 未回调 TNG 业务层)→ 手动点「继续」→ 再次弹验证 → 循环。
## 回调链1.9.10 dex 逆向)
```
用户滑动成功
→ JS postMessage → CaptchaWebViewDialog$2.a (action=sendAliyunCaptchaVerifyData, data 含 success/message)
→ Captcha.generateResult(char, zzbfs) → JSON {code, retCode, message, certifyId}
→ setVerifyResult(true) → Captcha$1(Handler) → VerificationCallback.onSuccess(result)
→ TTCaptcha 反射 Proxy → TTCaptchaCallback.callBack(result)
→ parseJson → TTCaptchaResponse{code, certifyId}
code==0 且 certifyId 非空 ?
→ notifySuccess(certifyId) → TTInListener.success → TNG 业务层提交 RPC
→ notifyFailure(code) / handleFailure("Result is null"|"Invalid code or certifyId")
→ 服务端二次校验 certifyId 失败
→ quake 抛 CaptchaNeededException("Captcha needed")
/ CaptchaNotPassedException("Captcha not passed")
→ 验证拦截器再弹滑块 → 循环
```
## 关键类dex 定位)
| 类 | 作用 |
|----|------|
| `com.aliyun.captcha.Captcha`classes10 | 单例verify/generateResult/showDialog |
| `com.aliyun.captcha.CaptchaWebViewDialog` + `$2` | 滑块 WebView + JS postMessage 桥 |
| `com.aliyun.TigerTally.captcha.api.TTCaptcha` | TigerTally 封装,**反射**调 aliyun Captcha |
| `com.aliyun.TigerTally.captcha.core.TTCaptchaCallback` | 解析 resultcode==0 且 certifyId 非空才 success |
| `my.com.tngdigital.captcha.TigerTallyApiWrapper` | TNG 业务侧封装Kotlin 协程 showCaptcha |
| `...aliservice.quake.CaptchaNeededException` / `CaptchaNotPassedException` | 服务端要验证 / 验证未通过 |
| `...amcs.CaptchaConfigCenter` / `CaptchaInitializer` | 远程下发 wafCaptchaKey / captcha_switch |
| `...opmpaasexpress.interceptor.OpMpVerifyInterceptor` 等 | RPC 验证拦截器,触发滑块 |
## 判定点(本次 hook 已打点)
1. `Captcha.generateResult` 返回的 JSON —— **certifyId 是否为空**(滑块是否真正拿到服务端签发)
2. `CaptchaWebViewDialog$2.a` —— JS postMessage 的 data 内容
3. `TTCaptchaCallback.callBack/notifySuccess/notifyFailure` —— TNG 是否拿到 certifyId
4. `CaptchaNeeded/NotPassedException` 构造 message —— 服务端二次校验失败原因
5. `TTCaptcha.verifyByReflect/buildParams` —— captcha 参数region/appKey 等)
## 根因候选
- **TigerTally 设备指纹umidToken异常**`hookTigerTally` 短路了
`TigerTallyAPI.init/initCommon``t.B.genericNt1`(防 ANR fork 卡死)。
若 captcha 服务端用 umidToken 校验设备,缺失/变化会导致 certifyId 校验失败。
- **captcha 全量方法打点拖慢 JS 桥回调**(已修复:改为精准打点)。
- **region 错误**`TTCaptcha.buildParams``t.B.genericNt14()` 取 region。
## 抓 logcat 判定
```powershell
powershell -File scripts/logcat-tng.ps1
```
复现滑块 → 观察:
- `captcha JS postMessage` 后是否有 `captcha RET generateResult`(含 certifyId
- `captchaCb CALL notifySuccess` 是否出现(成功)还是 `notifyFailure`
- `captcha EXC ...CaptchaNotPassedException` 的 msg