TikTok X-Dynosaur5.3.1补环境(新版)

校验更新了,导致上次补的签名失效,返回空。继续让AI分析。最终消耗了Trae 1400积分。


问题概述

TikTok 网页版 /api/post/item_list/ 接口(用户作品列表)请求返回空数据,原因是补环境生成的签名无效。

根本原因分析

1. envcode 被非法修改

现象:在签名生成过程中,860 状态表的 envcode 字段被 webmssdk 内部逻辑从 1 改为 4105

根因:补环境缺少完整的 WebGL 上下文,导致 webmssdk 无法正确获取 GPU 信息,进而将环境编码计算为 4105(非浏览器标记),使服务端校验失败。

影响:签名中的环境指纹与浏览器不一致,服务端拒绝请求返回空数据。

2. WebGL 上下文缺失

现象:原始补环境中 HTMLCanvasElement.prototype.getContext 返回 null

根因:TikTok 的 webmssdk 在初始化和签名过程中会调用 Canvas 的 getContext('webgl') 来获取 GPU 指纹信息,包括:

  • UNMASKED_VENDOR_WEBGL(0x9245)
  • UNMASKED_RENDERER_WEBGL(0x9246)
  • WebGL 扩展列表
  • 最大纹理尺寸等参数

影响:envcode 计算错误,签名无效。

3. msToken 时效性

现象:即使签名正确,msToken 过期后请求也会返回空数据。

根因:msToken 是会话标识符,具有时效性,过期后必须从浏览器获取最新值。

解决方案

修复 1:完整的 WebGL 模拟

get_sign.js 中实现完整的 WebGL 上下文对象:

// 核心实现:createMockWebGLContext()
// 提供完整的 getParameter 实现
// 支持所有 WebGL 常量查询
// 包括 WEBGL_debug_renderer_info 扩展

关键参数

const _webGLInfo = {
    vendor: 'WebKit',
    renderer: 'WebKit WebGL',
    unmaskedVendor: 'Google Inc. (NVIDIA)',
    unmaskedRenderer: 'ANGLE (NVIDIA, NVIDIA GeForce RTX 3060 ...)',
    maxTextureSize: 16384,
    maxCubeMapTextureSize: 16384,
    maxRenderbufferSize: 16384,
    maxTextureImageUnits: 16,
    maxVertexTextureImageUnits: 16,
    maxCombinedTextureImageUnits: 32,
    maxVertexAttribs: 16,
    maxVertexUniformVectors: 4095,
    maxFragmentUniformVectors: 1024,
    maxVaryingVectors: 30,
    extensions: [/* 完整的 WebGL 扩展列表 */]
};

修复 2:预初始化状态注入

ba.init() 之前注入关键状态表:

// 854: WebGL 状态(防止 webmssdk 重新获取 GPU 信息)
// 868: Canvas hash

// 从 browser_state.json 读取并注入
const bs = JSON.parse(fs.readFileSync('browser_state.json'));
sandbox.__msdkTable[854].v = bs['854'];
sandbox.__msdkTable[868].v = bs['868'];

修复 3:Proxy 保护 envcode

使用 JavaScript Proxy 拦截对 envcode 的修改:

const proxy860 = new Proxy(originalV, {
    set(target, prop, value) {
        if (prop === 'envcode' && value !== 1) {
            console.error('[proxy-block] envcode blocked');
            return true; // 阻止修改
        }
        target[prop] = value;
        return true;
    }
});
sandbox.__msdkTable['860'].v = proxy860;
sandbox.__msdkTable['938'].v = proxy938; // 938 与 860 同步

涉及的状态表(环境参数)

状态表 ID 名称 作用 数据来源
854 WebGL 状态 GPU 指纹信息 browser_state.json
860 msStatus 签名状态核心(含 envcode、exBundleProof) browser_state.json
868 Canvas hash Canvas 指纹哈希 browser_state.json
917 设备指纹 浏览器环境指纹数据 fp_data.json
921 浏览器信息 电池、权限、WebGL 等信息 browser_state.json
938 msStatus(副本) 与 860 同步 自动同步
980 鼠标轨迹 鼠标移动轨迹数据 browser_state.json

关键请求参数

参数 说明 示例值
aid 应用 ID 1988
count 返回数量 16
cursor 分页游标 0 或上次返回的 cursor
secUid 安全用户 ID MS4wLjABAAAA...
clientABVersions 实验性功能版本 35个版本ID用逗号分隔
enable_cache 是否启用缓存 false
post_item_list_request_type 请求类型 0
needPinnedItemIds 是否需要置顶视频 true
video_encoding 视频编码 dash
coverFormat 封面格式 2

签名参数说明

参数 说明 来源
X-Dynosaur 主签名字段,包含环境指纹 webmssdk 生成
X-Bogus 辅助签名,通常为 1 webmssdk 生成
X-Gnarly 附加签名 webmssdk 生成
msToken 非必须,从浏览器获取 Cookie

使用方法

1. 获取最新 msToken

// 在浏览器控制台执行
document.cookie.split(';')
  .find(c => c.trim().startsWith('msToken='))
  .split('=')[1]

或使用 MCP 工具:

# js-reverse MCP
evaluate_script("() => document.cookie.match(/msToken=([^;]+)/)?.[1]")

2. 运行补环境生成签名

node get_sign.js "<URL>" "<UA>" "<msToken>"

参数说明

  • URL: 完整的 API 请求 URL(包含所有查询参数)
  • UA: 浏览器 User-Agent
  • msToken: 从浏览器获取的最新 msToken

示例

node get_sign.js \
  "https://www.tiktok.com/api/post/item_list/?aid=1988&..." \
  "Mozilla/5.0 (Windows NT 10.0; Win64; x64) ..." \
  "BbXpLlis3IVHHQGv3cPPQISfdmfa8HyrUgWL8..."

3. 使用生成的签名 URL 请求接口

import requests

signed_url = "get_sign.js 输出的 URL"
headers = {
    'User-Agent': 'Mozilla/5.0 ...',
    'Referer': 'https://www.tiktok.com/@ainbag9',
    'Cookie': 'msToken=<最新msToken>'
}

response = requests.get(signed_url, headers=headers)
data = response.json()
items = data.get('itemList', [])

核心文件说明

文件 作用 说明
get_sign.js 核心签名脚本 补环境实现 + 签名生成
webmssdk.js 签名 SDK TikTok 的签名算法实现
browser_state.json 浏览器状态 从浏览器抓取的状态表数据
fp_data.json 设备指纹 从浏览器抓取的指纹数据
test_with_new_ms.py 测试脚本 示例测试脚本

调试技巧

环境变量

# 启用签名日志
SIG_LOG=1 node get_sign.js ...

# Dump 状态表到文件
DUMP_TABLE=1 node get_sign.js ...

# 记录键访问
TRACE_KEYS=1 node get_sign.js ...

日志标记

  • [pre-sign]: 签名前状态
  • [post-sign]: 签名后状态
  • [proxy-block]: Proxy 拦截日志
  • [inject]: 状态注入日志

注意事项

  1. msToken 必须新鲜:过期后签名正确也会返回空数据
  2. 环境指纹必须匹配:860、917、921 等状态表必须与浏览器一致
  3. WebGL 模拟必须完整:缺少任何关键参数都可能导致 envcode 计算错误
  4. clientABVersions 参数:TikTok 新版接口需要此参数,从浏览器抓取最新值
  5. IP 风控:同一 IP 频繁请求可能被风控,建议使用代理

验证结果

✅ 成功获取 14 个视频
✅ 签名与浏览器一致
✅ envcode 保持为正确值 1
✅ 支持 post/item_list 接口

点赞

发表回复