Skip to content

Add plugin SAZ 抓包解析 v0.2.4 - #638

Open
lehuaner wants to merge 1 commit into
ZToolsCenter:mainfrom
lehuaner:plugin/saz-parser
Open

lehuaner wants to merge 1 commit into
ZToolsCenter:mainfrom
lehuaner:plugin/saz-parser

Conversation

@lehuaner

@lehuaner lehuaner commented Oct 4, 2026 •

Copy link
Copy Markdown

插件信息

  • 名称: SAZ 抓包解析
  • 插件ID: saz-parser
  • 版本: 0.2.4
  • 描述: 把 Fiddler .saz 抓包归档转换为可供 AI 分析的结构化素材:秒级索引全部会话,自动解压 gzip/br/zstd,解析 WebSocket 帧日志(_w.txt,原解析脚本未处理),按 L0–L3 四档生成体积可控(可设 token 预算、自动分卷)的分析包,含接口清单、字段结构、鉴权链与跨会话参数传递摘要;同时保留与原解析脚本同构的目录树导出。隐私字段默认完整保留,纯本地处理不联网、不调用任何模型。
  • 作者: 乐幻
  • 类型: 新增

一句话定位:把几千条报文变成能交给 AI 分析、体积可控、且每条都能回溯到原始字节的素材。运行时零第三方依赖(解压/gzip/brotli/zstd 全走宿主内嵌 Node 的 zlib),不联网、不调用任何模型。

下面每个数字都是本机 50 个真实 .saz 归档(合计 793.4MB)上跑出来的实测结果,不是估算、不是预期。

它解决什么问题

痛点 本插件的做法(含实测)
全量解析出的平铺目录约 97 万 token,AI 一口吃不下 L0–L3 四档详细度 + 单卷 token 预算(默认 100,000)+ 自动分卷;超预算按优先级降级并输出被裁清单 trimLog,每条都能回溯原始 bodyRef
原解析脚本丢弃 WebSocket 帧日志 raw/<sid>_w.txt 按 Fiddler 帧日志字节格式逐帧解析,再按 RFC 6455 解 opcode/掩码/长度:实测取回 34 会话 / 1,984 帧 / 1,007KB 原本无声丢失的业务数据
Transfer-Encoding: chunked 的分块框架没剥,正文混着长度行、压缩流必然解压失败 按 RFC 9112 先 transfer-decoding 再解压。实测影响 245 条:未剥框 36 → 0,其中 209 条原本整条正文不可用 → 0;可扫描会话 7,402 → 7,611
SSE / 多帧 JSON 整块 JSON.parse 失败,AI 拿到一坨未拆分文本 逐事件拆分并结构化每个 data:实测 19 会话 / 5,030 事件 / 5,023 个 data 为合法 JSON;单会话最大 2,587 事件
声明 text/event-stream 但正文没有 data: 前缀的会话,此前只交出"1 个空事件" 自动回退为顶层多值拆分并写明改判理由(fellBackFrom)。实测全包 21 条声明该头的会话命中 3 条,3/3 救回
Content-Type 错标(如 290.8KB 的多值 JSON 被标成 text/html)完全不处理 内容探测命中(detectedBy:'content'):实测 3,125 条候选命中 1 条,JS/CSS/HTML 假阳性 0
只能靠鼠标一条条点、无法把"看哪些报文"交给 AI 秒级索引(3,756 条约 1–3s,不解正文)+ 域名/端点归并 + 业务流程分组 + 跨会话参数传递链;条件对象取数三个入口(界面筛选 / 配置文件 / MCP 入参)产出完全一致的 selection

本次变更(v0.2.4)

新增

  • 归档级流式/分块枚举:saz_query 的条件对象新增 transferEncoding[]、chunkedOnly、eventStreamOnly(只读索引期响应头,零正文 IO;false 是补集而非关闭)。
  • 单事件全文展开:详情「事件流」页点击任一行即可展开该事件的完整 data(复用已有返回体,不二次请求);被上游截断时明确提示"这里给的不是全文"。
  • 拆帧参数正式化:maxStreamEventsInFile(200) / maxWsFramesInFile(120) / streamMaxEvents(5000) / streamMaxValues(2000) / streamMaxDataChars(200000) 进入默认配置与导出面板。上限只控制逐条展开的行数,计数始终是全量。
  • 发布合规自检:打包链路逐条目扫描包内文本文件,拦截真实样本名 / 本机绝对路径 / 凭证形态。

修复

  • 伪 SSE 会话(声明 text/event-stream 但无 data:)此前只交出"1 个事件、data 为空",三份 JSON 全堆在控制字段里。现自动回退为顶层多值拆分并留痕。实测 21 条声明该头的会话命中 3 条,3/3 救回。
  • Content-Type 错标的多值 JSON 此前完全不处理,现由内容探测命中(实测 3,125 条候选命中 1 条,假阳性 0)。
  • 兼容层美化器按 Content-Type 分派,导致错标类型的多值 JSON 直接 passthrough。现补按内容兜底:同一批样本美化 passthrough 39 → 0。

变更

  • 内容探测预门收窄为"正文首非空白字符必须是 { 或 ["。依据实测成本:放宽到任意 JSON 值开头会让扫描从 39 次膨胀到 6,271 次(1,955 次被硬判据拒绝)而收益 0 条。
  • 回归断言:verify 60 → 74、verify-legacy 18 → 24、verify-preload 203 → 210;当前全量 74 / 56 / 24 / 210 / 20 共 384 条断言全绿,vue-tsc 0 错。

截图 / 演示

三张均为开发态假数据界面(域名 *.example.com、正文写 DEV 事件、值形如 demo-*),不含任何一条真实抓包内容:

会话列表 + 详情懒加载 事件流逐事件展开(v0.2.4) 导出面板:档位与 token 预算
screenshot-1-sessions.png screenshot-2-event-stream.png screenshot-3-export-panel.png

MCP 工具(5 个)

saz_parse(索引+概览,只读头部,秒级)、saz_query(条件取数,含传输层维度)、saz_body(已解码正文,隐私值原样返回、附 dechunk 留痕)、saz_ws(WebSocket 逐帧)、saz_stream(事件流/多值正文分页)。宿主不支持 tools 时,同一套能力仍可通过分析包文件与条件对象使用,功能不打折。

自检清单

  • plugin.json 的 name / title / version / description / author 字段均已检查
  • 已移除调试日志、未使用文件、敏感信息(.env、token、密钥等)
  • 本次 PR 的 diff 仅涉及 plugins/saz-parser/ 目录
  • 已在本地 ZTools 客户端实际加载并测试过此插件,主要功能正常
  • 同意以仓库声明的开源协议发布此插件

逐条依据(都可复核):

  1. name=saz-parser(小写连字符)、title=SAZ 抓包解析、version=0.2.4、author=乐幻,2 个 feature 的 code/cmds 齐备,5 个工具名为小写 snake_case。
  2. 随包 30 个文本文件按"真实归档名 / 被抓包业务域名与业务名 / 本机绝对路径 / 邮箱 / 账号 / 凭证形态"六类判据扫描,0 命中;preload/ 是未打包、未混淆的 CommonJS 源码,可直接审阅;无 .env、无密钥、无嵌套 zip、无 node_modules。
  3. 本次 diff 的 36 个文件全部位于 plugins/saz-parser/ 下。
  4. 已安装在本机 ~/.ztools/plugins/saz-parser 并在 ZTools 3.x(Electron 41 / Chromium 146)跑通:索引、三档过滤、详情懒加载、事件流、WebSocket 帧、分析包导出、兼容层导出;5 个 MCP 工具已被宿主注册并调用过。
  5. 本目录已附 LICENSE(MIT)。

构建与打包说明

plugins/saz-parser/ 就是安装后的 1:1 内容:目录内没有 build 脚本,CI 侧 npm install(无依赖)后直接打包本目录即可,产物与本地安装件等价(28 条目 / 499,259 字节,已用宿主自带的 adm-zip 与 Windows 解压做交叉验证,逐条目解压字节与源相等)。package.json 只用于把 preload/*.js 钉在 CommonJS 语义上(Electron preload 的硬要求)。

数据保真原则与已知限制

  • 任何裁剪、截断、降级都必须留痕(trimLog / 90-anomalies.md / manifest.json),不静默丢数据;隐私字段只标注类型、值完整保留(默认不脱敏,因为它们是分析对象本身)。
  • 与原 Python 解析脚本的 8 处不一致逐条登记在 _导出清单.md 的"有意不一致"里;chunked 场景另做了与历史产物逐条对拍的登记(该场景不能用"逐字节相等"对齐,因为原算法以文本模式写盘会改写 \n)。
  • 无 .proto 时 protobuf 正文只能保留原始字节(子协议名已记录在会话字段)。
  • JS 正文有意不做重排美化(朴素重排会破坏模板串/正则/ASI 语义)。
  • 单次触发处理一个归档;多归档切换、HAR 1.2 导出在路线图上。

文档

plugins/saz-parser/docs/ 内是完整的《设计与开发文档》(1,139 行:需求与缺陷清单、决策记录、每条实测数字的取证口径、里程碑状态)。真实归档名与被抓包业务域名/业务名已替换为 样本-NN / 域名-NN / 业务-NN / 协议-NN 别名,本机路径替换为占位符,所有数字原样保留,因此结论仍可逐条核对。


此 PR 由 ztools-plugin-cli 自动管理:每次 ztools publish 基于最新主仓库重建发布分支;打开的 PR 链接保持不变。

@lehuaner
lehuaner marked this pull request as ready for review October 4, 2026 08:34
- feat: saz-parser v0.2.4
- feat: saz-parser v0.2.4(同步 v0.5.8 发布记录到公开文档)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant