3. 高级过滤与搜索:Wireshark显示过滤器语法(BPF)、Charles的Focus/Block功能、Fiddler的FiddlerScript自定义过滤
抓包工具用久了你会发现,真正拉开效率差距的,不是谁抓的包多,而是谁能从海量数据里一秒定位到问题。今天这章,我带你把这三种工具的过滤能力吃透。
核心认知:过滤不是“筛掉噪音”,而是“精准对话”。你告诉工具你要看什么,它只给你看什么。
3.1 Wireshark 显示过滤器:BPF 的实战艺术
很多人觉得 Wireshark 的过滤语法难记,其实是你没找到规律。BPF(Berkeley Packet Filter)说白了就是一套“条件表达式”,你只要掌握几个核心套路就行。
3.1.1 基础表达式结构
我个人习惯把 BPF 表达式拆成三部分:协议 + 字段 + 运算符 + 值。
# 只看 HTTP 请求
http
# 只看源 IP 为 192.168.1.100 的包
ip.src == 192.168.1.100
# 只看 TCP 端口 443 的包
tcp.port == 443
# 组合条件:来自特定 IP 的 HTTPS 流量
ip.src == 192.168.1.100 and tcp.port == 443
嗯,这里要注意:Wireshark 的显示过滤器用的是 ==,不是 =。我见过不少新手在这栽跟头。
3.1.2 高级过滤技巧
我在项目中遇到过最头疼的场景:客户说“系统偶尔卡顿”,但流量量太大,根本看不出规律。后来我用了一个组合过滤,直接定位到问题。
| 场景 | 过滤表达式 | 说明 |
|---|---|---|
| 过滤重传包 | tcp.analysis.retransmission |
网络问题排查首选 |
| 过滤特定请求方法 | http.request.method == "POST" |
只看 POST 请求 |
| 过滤响应状态码 | http.response.code >= 400 |
快速定位错误 |
| 过滤 DNS 查询 | dns.qry.name contains "api" |
查找特定域名解析 |
| 过滤时间范围 | frame.time_relative > 10 and frame.time_relative < 20 |
定位特定时间段流量 |
我的小技巧:在 Wireshark 的过滤栏输入时,按 Tab 可以自动补全字段名。你试试看,效率翻倍。
3.1.3 避坑指南:BPF 的陷阱
我曾经在排查一个 HTTPS 连接问题时,用了 tcp.port == 443 and http,结果一个包都没抓到。为什么?因为 HTTPS 加密后,Wireshark 看不到 HTTP 层。正确的做法是:
# 只看 TLS 握手包
tls.handshake.type == 1
# 或者只看 Client Hello
tls.handshake.extensions_server_name contains "example.com"
注意:显示过滤器(Display Filter)和捕获过滤器(Capture Filter)是两回事。捕获过滤器用 BPF 原始语法,显示过滤器用 Wireshark 自己的语法。别搞混了。
3.2 Charles 的 Focus/Block 功能:精准控制流量
Charles 的 Focus 和 Block 功能,说白了就是“白名单”和“黑名单”。但用好了,它能帮你省掉 80% 的过滤时间。
3.2.1 Focus:只关注你想要的
我个人习惯在做接口调试时,先把目标域名加到 Focus 列表。这样 Charles 会把相关请求高亮显示,其他流量自动变灰。
# 操作步骤
1. 右键点击目标请求 → Focus
2. 或者:Proxy → Focused Hosts → Add
3. 输入域名:api.example.com
你想想看,当 Charles 里同时跑着几十个请求,只有你关注的几个是高亮的,定位问题是不是快多了?
3.2.2 Block:屏蔽干扰流量
我在项目中遇到过一个问题:某个第三方 SDK 一直在发心跳包,把 Charles 刷屏了。用 Block 功能直接屏蔽:
# 操作步骤
1. 右键点击目标请求 → Block
2. 或者:Proxy → Blocked Hosts → Add
3. 输入域名:heartbeat.thirdparty.com
进阶用法:Block 不只是屏蔽域名,还能屏蔽特定路径。比如 *.example.com/analytics/*,把埋点流量全干掉。
3.2.3 Focus vs Block 对比
| 功能 | 效果 | 适用场景 |
|---|---|---|
| Focus | 高亮显示,其他变灰 | 调试特定接口 |
| Block | 完全屏蔽,不显示 | 屏蔽干扰流量 |
3.3 Fiddler 的 FiddlerScript:自定义过滤的终极武器
FiddlerScript 是 Fiddler 的“灵魂”。它用 JScript.NET 编写,能让你在请求/响应的任意阶段插入自定义逻辑。说白了,你想怎么过滤就怎么过滤。
3.3.1 基础过滤脚本
我刚开始用 FiddlerScript 时,觉得它很复杂。后来发现,你只需要改几个函数就行。
// 在 OnBeforeRequest 函数中过滤请求
static function OnBeforeRequest(oSession: Session) {
// 屏蔽特定域名
if (oSession.HostnameIs("www.baidu.com")) {
oSession["ui-hide"] = "true"; // 隐藏请求
}
// 只保留 GET 请求
if (oSession.HTTPMethodIs("POST")) {
oSession["ui-hide"] = "true";
}
// 过滤掉图片资源
if (oSession.uriContains(".jpg") || oSession.uriContains(".png")) {
oSession["ui-hide"] = "true";
}
}
3.3.2 高级过滤:基于响应内容
有一次,我需要找出所有返回 JSON 中包含 "error": true 的请求。用 FiddlerScript 几行搞定:
// 在 OnBeforeResponse 函数中过滤响应
static function OnBeforeResponse(oSession: Session) {
// 只处理 JSON 响应
if (oSession.ResponseHeaders.Exists("Content-Type") &&
oSession.ResponseHeaders["Content-Type"].Contains("json")) {
var responseBody = oSession.GetResponseBodyAsString();
// 如果包含错误信息,高亮显示
if (responseBody.Contains('"error": true')) {
oSession["ui-backcolor"] = "red";
oSession["ui-notes"] = "Error Response!";
}
}
}
性能警告:FiddlerScript 是在每个请求/响应上执行的。如果你的脚本太复杂,会影响抓包性能。我建议只做必要的过滤,别写死循环。
3.3.3 FiddlerScript 常用过滤模式
| 场景 | 脚本片段 | 说明 |
|---|---|---|
| 隐藏特定域名 | oSession.HostnameIs("xxx") |
完全隐藏 |
| 标记慢请求 | oSession.Timers.ServerDoneResponse > 5000 |
标记超过 5 秒的请求 |
| 修改请求头 | oSession.RequestHeaders["X-Debug"] = "true" |
添加调试头 |
| 拦截特定 URL | oSession.uriContains("/api/v2/") |
只处理 API 请求 |
3.4 三种工具过滤能力对比
你可能会问:我到底该用哪个?我的建议是:看场景选工具。
| 维度 | Wireshark | Charles | Fiddler |
|---|---|---|---|
| 过滤粒度 | ★★★★★ 协议级 | ★★★☆☆ 域名/路径 | ★★★★☆ 请求/响应 |
| 学习曲线 | ★★★★★ 较陡 | ★★☆☆☆ 简单 | ★★★☆☆ 中等 |
| 自定义能力 | ★★★☆☆ 表达式 | ★★☆☆☆ 预设功能 | ★★★★★ 脚本 |
| 适用场景 | 网络层问题 | HTTP/HTTPS 调试 | 全栈调试 |
我的选择逻辑:排查网络问题用 Wireshark,调试接口用 Charles,需要深度定制用 Fiddler。三个工具配合使用,基本能覆盖 99% 的场景。
3.5 本章知识体系
下面这张图,帮你理清三种工具的过滤逻辑和关系:
这张图把三种工具的过滤能力做了分层。你从上往下看:先确定场景,再选工具,最后用对过滤语法。嗯,这就是我平时的工作流。
一句话总结:过滤不是技术问题,是思维问题。你越清楚你要找什么,过滤就越简单。