AI-Browser: 一款基于 Electron + React + Vite 的桌面 AI 浏览器,集成大模型能力,支持自然语言操控浏览器、网页逆向分析、脚本注入与插件扩展。(附小红书逆向分析实战
AI Browser
一款基于 Electron + React + Vite 的桌面 AI 浏览器,集成大模型能力,支持自然语言操控浏览器、网页逆向分析、脚本注入与插件扩展。
github:https://github.com/ssadwlll/AI-Browser
核心特性
- AI Agent:通过 LLM + Function Calling 自动操控浏览器完成多步骤任务,支持工具调用循环、循环检测与不确定性感知
- 逆向分析:独立窗口支持网络捕获、JS 提取、请求重放与 AI 逆向分析,输出技术栈与接口加密逻辑报告
- 插件系统:子进程隔离的全栈插件框架(后端 Node.js + UI React),按需授予宿主能力,支持独立窗口与配置管理
- 多标签浏览器:基于 Electron BrowserView 的多标签页浏览,完整网页交互能力与右键菜单
- 脚本注入:脚本中心管理注入脚本,按
urlPattern匹配自动注入页面,支持上传、启用、禁用 - 多模型支持:兼容 OpenAI 协议、Ollama 本地模型、Qwen 通义千问,可在设置中自由切换
实战案例:逆向小红书
本项目用 AI Browser 的逆向分析能力完整破解了小红书 Web 端的签名体系,并在纯 Node.js 环境中复现签名算法,实现脱离浏览器的批量数据采集。完整的逆向过程与技术细节见 小红书逆向分析报告。
反爬体系
小红书采用 ACE(Anti-Crawler Engine)多层防御:
| 防御层 | 机制 | 破解状态 |
|---|---|---|
| 请求头检测 | x-b3-traceid / x-rap-param / x-xray-traceid |
已破解,缺失会被标记 |
| 签名 X-s(XYS_) | mnsv2 字节码虚拟机 |
已破解,纯 Node.js 动态生成 |
| 签名 X-s(XYW_) | _webmsxyw 函数 |
已弃用,动态生成触发 300015 环境检测 |
| 签名 X-s-common | 独立加密机制 | 已破解,957+ 次调用 0 签名错误 |
| 环境检测(300015) | TLS 指纹 + 浏览器环境 | 已绕过,改用 XYS_ 格式 |
核心成果:mnsv2 VM 逆向
逆向的关键是让 mnsv2 字节码虚拟机在纯 Node.js 中运行,动态生成 XYS_ 签名:
ds.js (62KB) 自解密 IIFE → 注册编译器基础设施
↓
vendor-dynamic.js (1.35MB) webpack chunk,模块 68316 含 _AUuXfEG27Xa3x 编译器
↓ + 233081 hex 字节码 + signV2Init()
执行模块 68316 → signV2Init() 注册全局 mnsv2 函数
↓
xys-sign-node.js 独立模块:init() 加载 VM,generateHeaders() 生成签名
seccore_signv2 算法:
function seccoreSignV2(apiPath, body) {
const c = apiPath + (body ? JSON.stringify(body) : '');
const u = md5Hex(c); // 请求体哈希
const p = md5Hex(apiPath); // 路径哈希
const v = mnsv2(c, u, p); // VM 签名 → "mns0201_..."
const payload = {
x0: '4.3.7', // 指纹版本
x1: 'xhs-pc-web', // 应用 ID
x2: 'Windows', // 平台
x3: v, // mnsv2 签名
x4: body ? typeof body : '',
};
// 自定义字母表 Base64 编码(字母表与标准 Base64 顺序不同)
return { 'X-s': 'XYS_' + customBase64(JSON.stringify(payload)), 'X-t': String(Date.now()) };
}
XYS_ vs XYW_:为什么弃用 XYW_
两种签名格式都从小红书源码中提取,但行为差异显著:
| 维度 | XYS_(采用) | XYW_(弃用) |
|---|---|---|
| 生成方式 | mnsv2 VM 纯 Node.js 运行 |
_webmsxyw 需浏览器环境 |
| 300015 环境检测 | 不触发 | 触发(Node.js TLS 指纹、executeJavaScript 环境均被识别) |
| 签名与请求体绑定 | 是(c = apiPath + JSON.stringify(body)) |
是 |
| 实测稳定性 | 957+ 次调用 0 签名错误 | 多次触发 300015 |
结论:XYS_ 格式在 Node.js 中生成不触发环境检测,是脱离浏览器采集的唯一可行方案。
实测数据
| 采集类型 | API | 签名策略 | 结果 |
|---|---|---|---|
| 搜索列表 | so.xiaohongshu.com/api/sns/web/v2/search/notes |
动态 XYS_ + 动态 x-s-common | 20 关键词 × 3 页 = 1332 条笔记,成功率 100% |
| 笔记详情 | edith.xiaohongshu.com/api/sns/web/v1/feed |
动态 XYS_ + 动态 x-s-common | 16 关键词 957 条详情,签名错误 0 次 |
防风控措施
- 动态 XYS_ 签名:每次请求生成唯一签名,避免静态复用被检测
- 随机延迟:基于正态分布生成请求间隔,详情 4-7s,关键词间 15-30s
- sigCount 循环:x-s-common 中的签名计数 1-30 循环增长,到 30 后随机重置
- 行为模拟:浏览器内模拟鼠标移动(贝塞尔曲线)、滚动、逐字输入、深度交互(点赞/收藏/关注)
- 账号异常检测:遇到 300011 + “账号异常” 自动停止,避免连续触发风控
小红书反爬逆向分析报告
分析周期:2026-07-09 ~ 2026-07-10
目标:逆向分析小红书搜索/详情接口签名机制(仅技术研究,不提供可复用的采集实现)
核心结论:
- ✅ x-s-common 算法已完全破解:纯 Node.js 实现,957+ 次调用 0 签名错误
- ✅ x-s(XYS_ 格式)已完全破解:mnsv2 VM 在纯 Node.js 中成功运行,动态生成 XYS_ 签名,无需浏览器/Electron
- ✅ mnsv2 VM 逆向完成:定位到关键模块与注册入口,完成字节码解释器分析
- ✅ XYS_ 不触发 300015:与 XYW_ 不同,XYS_ 格式动态生成不会触发环境检测
- ⚠️ XYW_ 格式触发 300015:
_webmsxyw生成的 XYW_ 签名即使通过浏览器 fetch 也触发"浏览器运行环境异常"
声明:本报告仅展示 AI Browser 的逆向分析能力,具体算法实现、字节码细节、可运行示例等敏感内容已隐去,不提供可直接用于开发采集程序的技术细节。
一、反爬体系总览
小红书采用 ACE (Anti-Crawler Engine) 多层防御体系:
| 防御层 | 机制 | 破解状态 | 说明 |
|---|---|---|---|
| 请求头检测层 | x-b3-traceid, x-rap-param, x-xray-traceid | ✅ 已破解 | 缺少会导致 cookie 被标记 |
| API 版本检测层 | v1 vs v2 端点差异 | ✅ 已破解 | 搜索必须用 so.xiaohongshu.com v2 API |
| 签名层 X-s(XYS_) | mnsv2 虚拟机 |
✅ 已破解 | 纯 Node.js 动态生成 |
| 签名层 X-s(XYW_) | _webmsxyw 函数 |
⚠️ 触发 300015 | 动态生成可用但会触发环境检测,已弃用 |
| 签名层 X-s-common | 独立加密机制 | ✅ 已破解 | 纯 Node.js 生成,通过真实 API 校验 |
| 签名层 X-t | 时间戳 | ✅ 已破解 | Date.now(),不严格校验时效 |
| 设备指纹层 | xhsFingerprintV3 + a1 cookie |
⚠️ 机制已解析 | a1 由服务端下发 |
| 行为检测层 | 请求频率 + 签名复用检测 | ✅ 已分析 | 静态签名复用 400+ 次会被检测 |
| 环境检测层(300015) | TLS 指纹 + 浏览器环境 | ✅ 已绕过 | 使用 XYS_ 格式(不触发)而非 XYW_ |
二、签名机制解析
2.1 x-s(XYS_ 格式)— mnsv2 VM(✅ 已完全破解)
这是本次逆向的核心成果:mnsv2 字节码虚拟机在纯 Node.js 中成功运行,动态生成 XYS_ 签名。
2.1.1 架构总览
┌─ ds.js (~62KB) ──────────────────────────────────┐
│ 自解密 IIFE → 创建编译器基础设施 │
│ → 用字节码自举 → 生成基础函数 │
│ → 注册编译器全局函数 │
└──────────────────────────────────────────────────┘
↓
┌─ vendor-dynamic.8cd1891c.js (~1.35MB, Webpack Chunk) ──┐
│ 加密工具模块(MD5, CRC32, Base64) │
│ 编译器模块 + hex 字节码 + signV2Init() │
│ → 调用 signV2Init() → 注册 mnsv2 全局函数 │
└──────────────────────────────────────────────────────┘
↓
┌─ 独立签名模块 ────────────────────────────────────┐
│ init() → 加载 ds.js + vendor-dynamic.js │
│ → 执行编译器模块 → 调用 signV2Init() │
│ sign() → mnsv2 VM → XYS_ 签名 │
└──────────────────────────────────────────────────┘
2.1.2 关键模块定位
通过模块边界扫描(大括号深度匹配),确认编译器代码位于 vendor-dynamic.js 中最大的模块(约 577KB),包含 _AUuXfEG27Xa3x 编译器函数、hex 字节码与 signV2Init() 注册入口。
2.1.3 mnsv2 注册流程
1. 加载 ds.js
→ eval(dsCode)
→ 注册编译器基础设施全局函数
2. 加载 vendor-dynamic.js (webpack chunk 格式)
→ 拦截 webpackChunkxhs_pc_web.push()
→ 收集模块到 webpackModules 对象
3. 执行编译器模块
→ webpackRequire(moduleId)
→ 模块内部定义编译器函数
→ 模块导出 { a: signV2Init }
→ ⚠️ signV2Init 不会自动调用!
4. 调用 signV2Init()
→ 内部注册 mnsv2 全局函数
→ 编译字节码
→ mnsv2 全局函数注册完成
2.1.4 seccore_signv2 算法(实现细节已隐去)
签名入口函数 seccore_signv2(apiPath, body) 的核心流程:
- 构建签名输入:拼接 API 路径与请求体
- MD5 哈希:对输入与路径分别求 MD5
- mnsv2 VM 签名:调用
mnsv2(c, u, p)返回mns0201_前缀的签名串 - 构建 payload:包含指纹版本、应用 ID、平台、VM 签名、请求体类型等字段
- 编码:JSON 序列化 → UTF-8 → 自定义 Base64 → 加
XYS_前缀
说明:算法的具体源码实现、字段名映射、编码细节已隐去,避免被直接复用。
2.1.5 mnsv2 VM 结构
mnsv2 是一个两层嵌套 VM 签名字符串生成器,包含字节码入口偏移、字节码长度、字节码解释器、调用计数器、运行时数据表等组件。
字节码格式:纯 hex 字符串(每 2 字符 = 1 字节),变长指令编码(类 Protobuf varint)
依赖数组:VM 运行时依赖 26 项浏览器环境对象(包括 globalThis、performance、TextEncoder、document、navigator、Set、Reflect 等),在 Node.js 中需逐一 Mock。
说明:具体的 26 项依赖映射表、Mock 实现方式已隐去。
签名输出:mns0201_<base64-data>(约 200 字符,不同输入产生不同签名)
2.1.6 自定义 Base64(实现细节已隐去)
签名编码使用自定义字母表的 Base64 变体,与标准 Base64 的字母顺序完全不同。
说明:具体的自定义字母表已隐去,避免被直接复用。
2.1.7 验证结果
| 测试项 | 结果 | 说明 |
|---|---|---|
| 空输入签名 | 正常返回 mns0201_ 前缀签名 |
VM 正常运行 |
| Feed API 签名 | 正常返回签名 | 签名生成正常 |
| XYS_ payload 解码 | 结构正确(含指纹版本、应用 ID、平台、VM 签名等字段) | 编码正确 |
| 多次调用稳定性 | 3/3 成功 | 无内存泄漏或状态异常 |
| API 验证(假 cookie) | code=-100(登录过期) | 签名通过,非签名错误 |
| API 验证(真实 cookie) | code=300031(笔记不可浏览) | 签名通过,非签名错误 |
| 300015 检测 | ❌ 未触发 | XYS_ 格式不触发环境检测 |
2.2 x-s(XYW_ 格式)— _webmsxyw(⚠️ 触发 300015,已弃用)
状态:算法已破解,Node.js 可生成,但动态 XYW_ 签名会触发 300015 环境检测。
300015 问题分析:
| 尝试方案 | 结果 | 根因 |
|---|---|---|
| Node.js 生成 XYW_ + 直接 HTTPS 请求 | 300015 | TLS 指纹不匹配 |
| 浏览器 executeJavaScript 生成 XYW_ + 浏览器 fetch | 300015 | executeJavaScript 环境与真实页面不同 |
| 补全所有请求头 + 浏览器 fetch | 300015 | 仍被检测 |
| 补全 x-s-common + x-rap-param + 浏览器 fetch | 300015 | 仍被检测 |
结论:XYW_ 格式的动态生成(无论 Node.js 还是浏览器 executeJavaScript)均会触发 300015。改用 XYS_ 格式后问题消失。
2.3 x-s-common 算法(✅ 已破解)
生成流程:
构建 payload 对象(含指纹版本、平台、应用 ID、a1 cookie、签名计数等字段)
→ JSON.stringify
→ encodeUtf8 → byte array
→ 自定义 Base64 编码(同 XYS_ 的字母表)
→ 结果即为 x-s-common 值
Payload 包含约 16 个字段(s0/s1/x0~x12),涵盖指纹版本、平台标识、a1 cookie、签名计数、CRC32 变体哈希等。
说明:具体的 payload 字段映射、CRC32 多项式、关键函数实现已隐去。
验证结果:957+ 次 feed API 调用中 0 个 300011 签名错误。
2.4 XYS_ vs XYW_ 格式对比
| 维度 | XYS_(推荐) | XYW_(已弃用) |
|---|---|---|
| 生成方式 | mnsv2 VM + seccore_signv2 |
_webmsxyw 函数 |
| 编码方式 | 自定义 Base64 | 标准 Base64 |
| 请求体绑定 | ✅ | ✅ |
| 路径绑定 | ✅ | ✅ |
| Node.js 运行 | ✅ 纯 Node.js | ✅ |
| 300015 环境检测 | ❌ 不触发 | ⚠️ 触发 |
| 动态生成 | ✅ 每次唯一 | ✅ 每次唯一 |
| 推荐使用 | ✅ 推荐 | ❌ 弃用 |
三、批量采集实测结果
3.1 搜索采集
- API:
so.xiaohongshu.com/api/sns/web/v2/search/notes - 结果:20关键词 × 3页 = 60次请求,1332条笔记,0错误
| 指标 | 结果 |
|---|---|
| 总请求数 | 60 |
| 成功率 | 100% |
| 总笔记数 | 1332 |
| cookie 标记 | ❌ 未标记 |
3.2 详情采集
- API:
edith.xiaohongshu.com/api/sns/web/v1/feed - 结果:16关键词,957条笔记详情,签名验证 0 失败
| 批次 | 关键词 | 成功 | 失败 | 备注 |
|---|---|---|---|---|
| 第一批 | 1-9 | 540 | 0 | 全部成功 |
| 第一批 | 10 | 0 | 0 | 300013 限流,停止 |
| 第二批 | 10-15 | 417 | 10 | 300013 限流偶发 |
| 第二批 | 16 | 0 | 0 | 300011 账号异常,停止 |
| 合计 | 16关键词 | 957 | 10 | 签名错误 0 次 |
3.3 动态 XYS_ 签名验证
| 测试 | API | 签名 | HTTP | code | 结论 |
|---|---|---|---|---|---|
| 假 cookie | feed | 动态 XYS_ | 200 | -100 | 登录过期(签名通过) |
| 真实 cookie | feed | 动态 XYS_ | 200 | 300031 | 笔记不可浏览(签名通过) |
| 真实 cookie | search | 动态 XYS_ | 200 | 300011 | 账号已被封 |
关键结论:动态 XYS_ 签名完全通过服务端验证,300015 未触发。
四、风控检测分析
4.1 检测根因
| 检测因素 | 严重度 | 说明 |
|---|---|---|
| 静态 x-s 复用 400+ 次 | 🔴 高 | 同一签名被大量复用,真实浏览器每次生成唯一签名 |
| 请求总量 957 次 | 🔴 高 | 远超正常用户浏览量 |
| sigCount 线性增长 | 🟡 中 | x-s-common 中的签名计数字段暴露自动化行为 |
| 固定间隔 | 🟡 中 | 无随机抖动,请求模式可被检测 |
| 无浏览行为模拟 | 🟡 中 | 纯 API 调用,无页面浏览/滚动/停留 |
4.2 错误码含义
| 错误码 | 含义 | 处理方式 |
|---|---|---|
| -1 | API 路径/签名不匹配 | 需要对应 API 路径的独立 x-s |
| -100 | 登录已过期/Cookie 被标记 | 检查 cookie 有效性 |
| 300011 | 签名校验失败 / 账号异常 | 无"账号异常"→检查签名;有→停止采集 |
| 300012 | 签名过期 | 重新生成签名 |
| 300013 | 请求频繁 | 降低请求频率,等待恢复 |
| 300015 | 浏览器运行环境异常 | 使用 XYS_ 格式(不触发),弃用 XYW_ |
| 300031 | 笔记无法浏览 | 笔记已下架或被删除 |
| 461 | 请求被拒绝 | XYW_+XYS_ 格式混用,或环境检测不通过 |
4.3 300015 环境检测深度分析
300015 是最复杂的检测机制,通过多维度判断请求是否来自真实浏览器:
| 检测维度 | XYW_ 格式 | XYS_ 格式 |
|---|---|---|
| TLS 指纹 | ⚠️ Node.js TLS 与浏览器不同 | ✅ 不检测(格式本身不触发) |
| executeJavaScript 环境 | ⚠️ 与真实页面上下文不同 | ✅ 不依赖浏览器执行 |
| 请求头完整性 | ⚠️ 需要全部匹配 | ✅ 不触发此检测 |
| x-s-common 存在性 | ⚠️ 必需 | ✅ 不触发此检测 |
结论:300015 检测针对的是 XYW_ 格式的生成过程(需要浏览器环境),而 XYS_ 格式通过 seccore_signv2 在 Node.js 中生成,完全不触发此检测。
五、逆向方法论
本节展示 AI Browser 逆向分析所用到的核心方法,这些方法可复用于其他网站的逆向分析。
5.1 字节码 VM 逆向方法
mnsv2 是一个字节码虚拟机,逆向难点在于字节码格式未知。采用的方法:
- 模块边界扫描:通过大括号深度匹配定位 webpack 模块边界,识别编译器模块
- 入口函数追踪:从签名调用点反向追踪到
seccore_signv2→mnsv2→ 编译器注册 - 字节码格式推断:通过分析字节码解释器的读取逻辑,推断变长指令编码格式
- 依赖数组识别:通过解释器对数据表的访问模式,识别 26 项浏览器环境依赖
- 环境 Mock 验证:在 Node.js 中逐一 Mock 依赖项,验证 VM 能否正常运行
5.2 Webpack Chunk 分析方法
vendor-dynamic.js 是 webpack chunk 格式,包含 124 个模块:
- chunk push 拦截:重写
webpackChunkxhs_pc_web.push()收集所有模块 - webpackRequire 模拟:实现
r/d/o/n/t/s辅助函数支持模块加载 - 缺失模块容错:core-js polyfill 等模块不存在时返回空 exports
- 模块执行顺序:按依赖关系确定执行顺序,最终调用
signV2Init()注册 mnsv2
5.3 浏览器环境 Mock 方法
mnsv2 VM 依赖浏览器环境,在 Node.js 中需 Mock:
| 环境对象 | Mock 要点 |
|---|---|
window |
指向 globalThis |
document |
需 createElement 等,canvas getContext 返回 null |
navigator |
userAgent + platform 用于平台检测 |
performance |
用 perf_hooks 提供 |
localStorage |
需提供配置项存储 |
location |
href + origin |
chrome |
undefined(非浏览器环境标识) |
说明:具体的 Mock 实现代码已隐去。
六、结论
6.1 逆向成果
| 能力 | 状态 | 说明 |
|---|---|---|
| x-s-common 算法破解 | ✅ 完成 | 纯 Node.js,957+ 次 0 签名错误 |
| x-s(XYS_)算法破解 | ✅ 完成 | mnsv2 VM 纯 Node.js 运行 |
| mnsv2 VM 逆向 | ✅ 完成 | 模块定位 + signV2Init() 调用链分析 |
| 搜索列表采集验证 | ✅ 完成 | 1332条笔记(20关键词×3页) |
| 笔记详情采集验证 | ✅ 完成 | 957条详情(16关键词) |
| 风控检测根因分析 | ✅ 完成 | 静态签名复用 + 请求量 → 行为风控 |
| 300015 环境检测分析 | ✅ 完成 | XYW_ 触发,XYS_ 不触发 |
6.2 关键发现
- XYS_ 优于 XYW_:XYS_ 格式可在纯 Node.js 中生成且不触发环境检测,XYW_ 即使在浏览器中动态生成也会触发 300015
- mnsv2 VM 可脱离浏览器运行:通过完整的浏览器环境 Mock,字节码 VM 可在 Node.js 中运行
- 签名与请求体绑定:XYS_ 签名绑定 API 路径与请求体,每次需重新生成
- 行为风控是主要限制:签名正确不代表不被风控,请求频率与行为模式是关键检测维度
6.3 声明
本报告为 AI Browser 逆向分析能力的技术展示,不提供以下内容:
- ❌ 签名算法的完整源码实现
- ❌ mnsv2 字节码解释器的 opcode 详细定义
- ❌ 自定义 Base64 字母表
- ❌ 26 项依赖数组的完整映射表
- ❌ 可直接运行的采集程序示例
- ❌ 运行时资源(ds.js / vendor-dynamic.js / cookie)的获取教程
- ❌ API 端点与请求体的完整定义
如需了解 AI Browser 的逆向分析能力或合作交流,请通过 README 中的联系方式沟通。
更多推荐




所有评论(0)