Files
hello_js_reverse_skill/scripts/verify/balance_names_values.py
T
yml2213 51dff870cf feat(collect): 纯离线生成打通 1ms 签到文字点选 —— errorCode=0 收口
做了什么:
- 新增 tcaptcha/tdc_values.py: 37 个语义名的取值生成器(静态画像 / 会话量 /
  每次采集量三层)+ build_plain 四段组装 + generate_collect 纯离线出包
- crypto: 新增 generate_telemetry(mode="python_values");轨迹生成统一到
  trajectory_points()(首点绝对坐标 + 增量 + 固定收尾 [1,1,12])
- crypto.split_collect_segments 重写: pad 只有 1 个空格时旧 ` {2,}` 判据会漏段,
  且 UA 串里的普通空格会假阳性 —— 改为「模 24 算术 + 不落在 JSON 字符串内部 + 结构校验」
- tools/tdc_modules: trajectory 指纹原先指向只做 JSON.stringify 的模块,改为
  mouseMoveEvent/touchStartEvent(真轨迹模块),37/37 不变
- client 默认 telemetry_mode 改为 python_values
- 新增 scripts/verify/{align_session,audit_names,verify_values,verify_offline,send_test}.py
  与 tools/{cdp_collect,cdp_dump_scripts,tdc_profile}.py

为什么:
- 账本 #40「谁在发 HTTP 是 12 的剩余自变量」被推翻。同 aid/同客户端/同求解器、
  答案都对,只换 collect 构造方式: 本次会话构建生成 -> 0 (4/4),
  旧模板回填 -> 12 (2/2)。真因是 collect 必须与本次会话构建同源。

怎么验证:
- .venv/bin/python -m tcaptcha.selftest  全绿(含新增四段切分与纯离线闭环回归)
- scripts/verify/verify_values.py        4 份真机明文 152/152 逐槽全等
- scripts/verify/verify_offline.py       逐槽全等 + 分段几何一致
- scripts/verify/send_test.py --mode python_values  1ms 签到页文字点选 errorCode=0 x4
2026-10-12 03:38:18 +08:00

76 lines
3.1 KiB
Python
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.
# -*- coding: utf-8 -*-
"""全量配平:37 个语义名 <-> 真机明文的 38 个槽。
约束(这些是硬证据,不是猜):
1. 值内容唯一确定语义名(MacIntel/UTF-8/ANGLE/GgoA.../98k/iframe...)
2. screen_fingerprint `"1440-2560-2530-24-*-*-|-*"` 反解出
screen_height=1440 / screen_width=2560 / screen_color_depth=24
3. itoken 有 `^\\d+:\\d+$` 特征 -> 占 **2 槽**(`641547489,1791732001`)
4. 37 项 -> 38 槽(仅 itoken 多占 1 槽),可与明文槽数对账
输出: 每个语义名的取值 + 置信度,供人工核对。
"""
import json
import re
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
sys.path.insert(0, str(ROOT / "tools"))
import tdc_modules as tm # noqa: E402
RAW = "/tmp/1ms_bridge/real_collect_plain.txt"
raw = open(RAW, encoding="latin1").read().rstrip("\x00")
cd = json.loads(re.sub(r" {2,}", "", raw))["cd"]
print("明文 38 槽:")
for i, v in enumerate(cd):
print(" %2d %s" % (i, json.dumps(v, ensure_ascii=False)[:78]))
print()
rows = tm.analyze("har/1ms_dianxuan/tdc.js")
names = [r["name"] for r in rows]
print("语义名 %d 个" % len(names))
print()
# ---- 按内容给每个槽打标签(不依赖位置)----
def tags(v):
t = []
if isinstance(v, str):
if "Mozilla" in v: t.append("user_agent")
if v == "MacIntel": t.append("platform")
if re.fullmatch(r"[+-]\d\d", v): t.append("timezone_offset")
if v.upper() == "UTF-8": t.append("charset")
if "ANGLE" in v: t.append("webgl_renderer")
if "Inc." in v: t.append("webgl_vendor")
if v.startswith("GgoA"): t.append("canvas_fingerprint")
if "rand=" in v and "captcha" in v: t.append("template_url")
if v == "98k": t.append("constant_98k")
if v == "iframe": t.append("iframe_detect")
if "*" in v and "-" in v: t.append("screen_fingerprint")
if v.startswith("http") and "1ms.run" in v: t.append("location_href")
elif isinstance(v, list):
if v and all(isinstance(x, list) and len(x) == 3 for x in v): t.append("trajectory")
if v and all(isinstance(x, str) for x in v): t.append("languages")
elif isinstance(v, int) and not isinstance(v, bool):
if 1_600_000_000 <= v <= 2_100_000_000: t.append("timestamp?")
elif v > 1_000_000: t.append("bigint?")
else: t.append("smallint?")
elif isinstance(v, str) and v == "":
t.append("emptystr?")
return t
print("逐槽标签:")
for i, v in enumerate(cd):
print(" %2d %-22s %s" % (i, ",".join(tags(v)), json.dumps(v, ensure_ascii=False)[:50]))
print()
# ---- 反解 screen_fingerprint 的约束 ----
fp = next((v for v in cd if isinstance(v, str) and "*" in v and "-" in v), None)
if fp:
p = fp.split("-")
print("screen_fingerprint = %r -> 高%s 宽%s 色深%s" % (fp, p[0], p[1], p[3]))
for target, want in (("screen_height", int(p[0])), ("screen_width", int(p[1])),
("screen_color_depth", int(p[3]))):
idxs = [i for i, v in enumerate(cd) if v == want]
print(" %-20s 期望 %s -> 明文里出现在槽 %s" % (target, want, idxs))