抖音a_bogus参数逆向实战:JSVMP环境模拟与Hook技术(2025最新)

抖音a_bogus参数逆向实战:JSVMP环境模拟与Hook技术(2025最新)

本文为技术摘要版,完整教程(含完整代码、bdms提取方法、调试技巧)已发布在 道满PythonAI,建议搭配阅读。

为什么需要逆向 a_bogus?

抖音Web端在所有核心API(视频列表、用户主页、搜索接口等)中都强制校验 a_bogus 签名参数。没有这个参数,请求直接被服务器拒绝。

做过抖音数据采集的同学一定遇到过这个问题:

bash 复制代码
# 不带 a_bogus 的请求
GET /aweme/v1/web/aweme/post/?device_platform=webapp&aid=6383&...
→ 403 Forbidden

# 带正确 a_bogus 的请求
GET /aweme/v1/web/aweme/post/?...&a_bogus=XXXX
→ 200 OK (返回JSON数据)

a_bogus 本质上是字节跳动安全SDK(bdms)在浏览器端动态生成的校验值,它绑定了你当前的浏览器指纹、请求参数和时间戳。

核心难点

a_bogus 逆向最大的挑战不在于算法本身,而在于运行环境的模拟:

  1. JSVMP保护 :bdms 的核心逻辑被 JSVMP 虚拟机包裹,直接阅读代码几乎不可能
  2. 环境检测 :SDK 会检测 Function.prototype.toString 是否为 [native code]、navigator 属性是否存在、document 是否可创建元素等
  3. 动态属性访问:SDK 运行时会访问大量浏览器全局对象属性,遗漏任何一个都会导致签名错误

技术路线:环境补全 + 动态代理

我们采用「环境补全优先 + 动态代理兜底」的策略:

javascript 复制代码
┌────────────────────────────────────┐
│         技术路线全景图               │
├─────────────────────────────────────┤
│                                     │
│  1. 函数 Native 伪装                │
│     └─ 重写 Function.toString       │
│     └─ 随机 Symbol 标记原生函数      │
│                                     │
│  2. 全局环境补全                     │
│     └─ window/document/navigator    │
│     └─ screen/location/history      │
│     └─ 第三方SDK存根(CefSharp等)     │
│                                     │
│  3. toStringTag 伪装                │
│     └─ 绕过 Object.toString.call    │
│                                     │
│  4. 动态 Proxy 监控                 │
│     └─ 实时发现缺失属性             │
│     └─ 按需补全,避免一次性写死      │
│                                     │
│  5. SDK 注入 + XHR 模拟             │
│     └─ 加载 bdms 代码               │
│     └─ 模拟 XHR.send 触发加密       │
│     └─ 从 window.a_bogus 获取结果   │
│                                     │
└─────────────────────────────────────┘

关键代码片段

1. 函数 Native 伪装

bdms 会通过 fn.toString() 检查函数是否为原生。我们用随机 Symbol 存储伪造标记:

javascript 复制代码
const $toString = Function.toString;
const fakeNativeTag = Symbol('('.concat('', ')_', (Math.random() + '').toString(36)));

const myToString = function() {
    return (typeof this === 'function' && this[fakeNativeTag]) || $toString.call(this);
};

// 替换原型方法并自伪装
delete Function.prototype['toString'];
Object.defineProperty(Function.prototype, 'toString', {
    enumerable: false, configurable: true, writable: true, value: myToString
});

// 给任意函数打上"原生"标记
globalThis.safefunction = (func) => {
    Object.defineProperty(func, fakeNativeTag, {
        enumerable: false, configurable: true, writable: true,
        value: `function ${func.name || ''}() { [native code] }`
    });
};

2. 动态代理监控

用 Proxy 监听 SDK 对环境对象的属性访问,实时发现需要补全的属性:

javascript 复制代码
function createProxy(objName) {
    return new Proxy(window[objName] || {}, {
        get(target, prop) {
            console.log(`[GET] ${objName}.${String(prop)}`);
            return Reflect.get(target, prop);
        },
        set(target, prop, val) {
            console.log(`[SET] ${objName}.${String(prop)} = ${JSON.stringify(val)}`);
            return Reflect.set(target, prop, val);
        }
    });
}

['window', 'document', 'location', 'navigator', 'screen'].forEach(name => {
    window[name] = createProxy(name);
});

3. 模拟 XHR 触发加密

bdms 通过劫持 XMLHttpRequest 来拦截请求并添加签名。我们模拟这个过程来触发加密:

javascript 复制代码
function get_ab(fullUrlWithParams) {
    const xhr = new XMLHttpRequest();
    xhr.bdmsInvokeList = [
        { args: ['GET', fullUrlWithParams, true] },
        { args: ['Accept', 'application/json, text/plain, */*'] }
    ];
    xhr.invokeList = [
        { name: 'addEventListener', args: ['load', null] },
        { name: 'addEventListener', args: ['error', null] }
    ];
    xhr.send(null);
    return window.a_bogus;  // SDK 生成的签名值
}

4. Python 端调用

python 复制代码
import execjs
from urllib.parse import urlencode

# 编译 JS 环境并调用
ctx = execjs.compile(open('env.js', 'r', encoding='utf-8').read())
a_bogus = ctx.call("get_ab", full_url)

# 携带签名发起请求
params['a_bogus'] = a_bogus
response = requests.get(url, headers=headers, cookies=cookies, params=params)

技术难点与解决方案总结

难点 解决方案
Function.toString 被检测 重写原型方法 + 随机 Symbol 标记
Object.toString.call 类型检测 伪装 Symbol.toStringTag
SDK 访问未定义属性 Proxy 动态监控 + f��需补全
加密逻辑封装在 JSVMP 内部 模拟 XHR 触发,无需理解算法

注意事项

  1. bdms 版本会更新:抖音不定期升级安全 SDK,签名失效时需重新提取代码
  2. Cookie 有效性 :s_v_web_id、ttwid 等 Cookie 有有效期,过期需重新获取
  3. WebID 一致性 :env.js 中的 User-Agent 必须与生成 webid 时的浏览器一致
  4. 请求频率控制:即使签名正确,过快请求仍会触发风控

完整教程

本文只展示了核心思路和关键代码片段。完整的教程包含:

  • bdms 代码的完整提取方法(从 Chrome Sources 面板操作)
  • 完整的 env.js 环境模拟脚本(7个步骤,200+行代码)
  • 完整的 Python 调用脚本
  • 调试过程中常见报错的排查方法
  • WebID 生成与指纹一致性校验

👉 完整教程地址 :抖音a_bogus参数加密逆向实战

相关推荐


作者:道满PythonAI

原文链接:www.daomanpy.com/docs/spider...

更多 Python + AI 教程请访问 daomanpy.com

相关推荐
huisheng_qaq7 小时前
【Python基础篇-09】深入理解python的闭包与装饰器
python·闭包
编码者卢布8 小时前
【App Service 】WebJobs 多实例实验:谁在运行,什么时候运行?
开发语言·python
quantdash_cc8 小时前
Python 获取实时行情后如何进行批量筛选?从全市场快照到策略候选池
开发语言·python·数据分析·量化交易·股票数据·quantdash
小蜗 strong9 小时前
和电脑猜拳(随机程序应用)
服务器·前端·python
华研前沿标杆游学10 小时前
企业标杆游学|走进东莞OPPO总部✨探秘智造与品牌出海
python
大侠归来10 小时前
C语言内存管理:从栈到堆的完整指南
c语言·开发语言·python
LOVE️YOU10 小时前
Python 数据结构的本质:位置、对象引用、Hash 与可变性
数据结构·python·哈希算法
特立独行的猫A10 小时前
仓颉版 Tauri:基于轻量化线程与纯血鸿蒙架构的下一代 Web 混合开发利器
javascript
李航198310 小时前
自动动手开发图形引擎,不仅能AI建模,还能AI渲染
人工智能·python·计算机视觉·ai·ai编程
LeoCrawls10 小时前
Python 读取 JSON 常见报错排查,附完整处理函数
python·json·php