feat(VM): 运行时反证通过 —— 静态导出的 cd 槽位序与真机 require 序逐位一致
做法: 真机 iframe 里包 Function.prototype.apply, 模块工厂调用形状实测为 4 参 [object,object,object,function](require 是最后一个), 按工厂实例分组记账; 再用新增 tools/cdp_script_source.js(Debugger.scriptParsed + getScriptSource) 取运行时真正执行的那份 tdc.js(不能用重新 fetch —— 同 URL 每次返回不同构建)。 结果: 静态 == 运行时 = [8,9,10,13,14,15,16,17,18,19,20,21,23,24,25,30,31,32,34,36,37,1,38,39,40,41,42,43,44,47,48,49,50,51,56,57,58] 37 项逐位相同 -> 槽位序=require序 这条链闭合; 之前语义对不上是标注启发式的问题。 附带: window.TDC(含 getData) 只在验证码 iframe, 可直接调用取证; cdp_eval 新增 --init-script。 账本新增已知 #35。
This commit is contained in:
@@ -330,3 +330,30 @@ E.push(function g() {
|
||||
|
||||
> 因此纯算路线必须**按本次构建**导出槽位表(`tools/tdc_layout.py`),
|
||||
> 并用**本次 prehandle 的 sid** 去取那份 tdc.js(真机 URL 还多带 `appid=<aid>`)。
|
||||
|
||||
### 9.5 运行时反证(2026-10-11,已通过)
|
||||
|
||||
静态导出不能自证,所以做了对拍:在真机 iframe 里包一层 `Function.prototype.apply`,
|
||||
模块工厂的调用形状实测是 **4 参 `[object, object, object, function]`**(require 是最后一个),
|
||||
按工厂实例分组记账;再用 `tools/cdp_script_source.js`(`Debugger.scriptParsed` +
|
||||
`getScriptSource`)取到**运行时真正执行的那份 tdc.js**。
|
||||
|
||||
> ⚠️ 不能用"重新 fetch 一次 tdc.js"来对比 —— 同一个 URL **每次返回不同构建**(§9.6/#29),
|
||||
> 必须用 Debugger 取**已解析的源码**。
|
||||
|
||||
结果:静态导出的 37 个 id 与运行时逐位相同
|
||||
|
||||
```
|
||||
[8,9,10,13,14,15,16,17,18,19,20,21,23,24,25,30,31,32,34,36,37,1,38,39,40,41,42,43,44,47,48,49,50,51,56,57,58]
|
||||
```
|
||||
|
||||
→ **槽位序 = 清单模块 require 序** 这条链闭合。脚本:`scripts/experiment_require_order.py`。
|
||||
|
||||
### 9.6 附带发现
|
||||
|
||||
- `window.TDC`(含 `getData`/`getInfo`/`setData`/`clearTc`)**只存在于验证码 iframe**,可以直接
|
||||
`TDC.getData(true)` 触发取证(不必真的答一次题),返回值就是 collect 明文。
|
||||
- iframe 里还有 `__TENCENT_CHAOS_STACK` 全局。
|
||||
- `Page.reload` 对 OOPIF iframe 无效("Command can only be executed on top-level targets");
|
||||
想在脚本执行前挂钩子要用 `Page.addScriptToEvaluateOnNewDocument`(已加到 `tools/cdp_eval.js`
|
||||
的 `--init-script`)。
|
||||
|
||||
Reference in New Issue
Block a user