导出 wireshark 网络包二进制数据的三种方法
Wireshark 是一款很好用的 UI 抓包工具,在 Windows、macOS 上都可以使用。最近开发的一个统计日志上报功能,发送的网络请求明明可以收到 server 正确的响应,但却捞取不到相关的日志,于是想到用 Wireshark 抓包分析内容,看看是哪里出问题了。

图中 Data 部分就是我们关心的数据包,想要进一步分析,需要将它导出为原始的二进制文件,这里一共有三种方法,下面分别说明。
方法一:直接导出
这个方法最简单有效,选中待导出的元素后,菜单选择“文件->导出分组字节流”,对应的快捷键是 Ctrl+Shift+X,从弹出的文件选择对话框中设置输出文件路径名即可。
方法二:导出为 base64
这个方法也比较直观,右键选中的元素,从菜单中选择“复制->...as a Base64 String",然后复制到文件中即可。

注意复制后的内容和 Data[...]: 后面的内容并不一致,后者其实是个 Hex Stream。
导出的数据由于是 Base64 格式,需要进一步使用 base64 命令 decode 一下:
$ cat <<"EOF" > data.base64
> LS0tLU1VTFRJLVBBUlRTLUZPUk0tREFUQS1CT1VOREFSWQ0KQ29udGVudC1EaXNwb3NpdGlvbjogZm9ybS1kYXRhOyBuYW1lPSJ1c2VyZmlsZSI7IGZpbGVuYW1lPSJmaWxlIg0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0NCg0KJJQOyYGrHKk/vsnisQ24jQ91wSHUh+ucWc0pKzOpRC4qdcK8oO1Qq40po6FtYrghx/Xp68bqVqHyOgwpncrVZT9/tkd4BIFpywyL0cNhw9J9JmCuhN0gBmNdxYyCiwbld7nt96UxhveH81WlAjAZkSFdJn2MQJCd15MmjURthQ74/Ys5uoLOfTXgUolx+mMt84bwu0X4lvP8kJ8ed+SHyHTKJbgvSZn8NIkFLzShfvdum1PgvGN1H7n4LqWxOWyfeA0KLS0tLU1VTFRJLVBBUlRTLUZPUk0tREFUQS1CT1VOREFSWS0tDQo=
> EOF
$ base64 -d -i data.base64 -o data.bin
$ xxd data.bin
00000000: 2d2d 2d2d 4d55 4c54 492d 5041 5254 532d ----MULTI-PARTS-
00000010: 464f 524d 2d44 4154 412d 424f 554e 4441 FORM-DATA-BOUNDA
00000020: 5259 0d0a 436f 6e74 656e 742d 4469 7370 RY..Content-Disp
00000030: 6f73 6974 696f 6e3a 2066 6f72 6d2d 6461 osition: form-da
00000040: 7461 3b20 6e61 6d65 3d22 7573 6572 6669 ta; name="userfi
00000050: 6c65 223b 2066 696c 656e 616d 653d 2266 le"; filename="f
00000060: 696c 6522 0d0a 436f 6e74 656e 742d 5479 ile"..Content-Ty
00000070: 7065 3a20 6170 706c 6963 6174 696f 6e2f pe: application/
00000080: 6f63 7465 742d 7374 7265 616d 0d0a 0d0a octet-stream....
00000090: 2494 0ec9 81ab 1ca9 3fbe c9e2 b10d b88d $.......?.......
000000a0: 0f75 c121 d487 eb9c 59cd 292b 33a9 442e .u.!....Y.)+3.D.
000000b0: 2a75 c2bc a0ed 50ab 8d29 a3a1 6d62 b821 *u....P..)..mb.!
000000c0: c7f5 e9eb c6ea 56a1 f23a 0c29 9dca d565 ......V..:.)...e
000000d0: 3f7f b647 7804 8169 cb0c 8bd1 c361 c3d2 ?..Gx..i.....a..
000000e0: 7d26 60ae 84dd 2006 635d c58c 828b 06e5 }&`... .c]......
000000f0: 77b9 edf7 a531 86f7 87f3 55a5 0230 1991 w....1....U..0..
00000100: 215d 267d 8c40 909d d793 268d 446d 850e !]&}.@....&.Dm..
00000110: f8fd 8b39 ba82 ce7d 35e0 5289 71fa 632d ...9...}5.R.q.c-
00000120: f386 f0bb 45f8 96f3 fc90 9f1e 77e4 87c8 ....E.......w...
00000130: 74ca 25b8 2f49 99fc 3489 052f 34a1 7ef7 t.%./I..4../4.~.
00000140: 6e9b 53e0 bc63 751f b9f8 2ea5 b139 6c9f n.S..cu......9l.
00000150: 780d 0a2d 2d2d 2d4d 554c 5449 2d50 4152 x..----MULTI-PAR
00000160: 5453 2d46 4f52 4d2d 4441 5441 2d42 4f55 TS-FORM-DATA-BOU
00000170: 4e44 4152 592d 2d0d 0a
没有 base64 命令的,需要安装一下,Linux、macOS 和 windows Git Bash 均支持。如果较老的版本不支持 -o 选项,直接重定向到输出文件即可。
通过 xxd 查看二进制数据,和 Wireshark 中右侧十六进制展示的一致。
方法三:导出为十六进制
这个方法是我最开始想到的,中间还走了一些弯路,不如上面两种方便,不过也记录一下。
右键选中的元素,从菜单中选择“复制->将字节复制为十六进制 + ASCII 转储",或者选择“...as Hex Dump” 也可,两者的区别仅在于,前者右边会多了字符区显示,与 Wireshark 元素详情中展示的更为一致。
0000 2d 2d 2d 2d 4d 55 4c 54 49 2d 50 41 52 54 53 2d ----MULTI-PARTS-
0010 46 4f 52 4d 2d 44 41 54 41 2d 42 4f 55 4e 44 41 FORM-DATA-BOUNDA
0020 52 59 0d 0a 43 6f 6e 74 65 6e 74 2d 44 69 73 70 RY..Content-Disp
0030 6f 73 69 74 69 6f 6e 3a 20 66 6f 72 6d 2d 64 61 osition: form-da
0040 74 61 3b 20 6e 61 6d 65 3d 22 75 73 65 72 66 69 ta; name="userfi
0050 6c 65 22 3b 20 66 69 6c 65 6e 61 6d 65 3d 22 66 le"; filename="f
0060 69 6c 65 22 0d 0a 43 6f 6e 74 65 6e 74 2d 54 79 ile"..Content-Ty
0070 70 65 3a 20 61 70 70 6c 69 63 61 74 69 6f 6e 2f pe: application/
0080 6f 63 74 65 74 2d 73 74 72 65 61 6d 0d 0a 0d 0a octet-stream....
0090 24 94 0e c9 81 ab 1c a9 3f be c9 e2 b1 0d b8 8d $.......?.......
00a0 0f 75 c1 21 d4 87 eb 9c 59 cd 29 2b 33 a9 44 2e .u.!....Y.)+3.D.
00b0 2a 75 c2 bc a0 ed 50 ab 8d 29 a3 a1 6d 62 b8 21 *u....P..)..mb.!
00c0 c7 f5 e9 eb c6 ea 56 a1 f2 3a 0c 29 9d ca d5 65 ......V..:.)...e
00d0 3f 7f b6 47 78 04 81 69 cb 0c 8b d1 c3 61 c3 d2 ?..Gx..i.....a..
00e0 7d 26 60 ae 84 dd 20 06 63 5d c5 8c 82 8b 06 e5 }&`... .c]......
00f0 77 b9 ed f7 a5 31 86 f7 87 f3 55 a5 02 30 19 91 w....1....U..0..
0100 21 5d 26 7d 8c 40 90 9d d7 93 26 8d 44 6d 85 0e !]&}.@....&.Dm..
0110 f8 fd 8b 39 ba 82 ce 7d 35 e0 52 89 71 fa 63 2d ...9...}5.R.q.c-
0120 f3 86 f0 bb 45 f8 96 f3 fc 90 9f 1e 77 e4 87 c8 ....E.......w...
0130 74 ca 25 b8 2f 49 99 fc 34 89 05 2f 34 a1 7e f7 t.%./I..4../4.~.
0140 6e 9b 53 e0 bc 63 75 1f b9 f8 2e a5 b1 39 6c 9f n.S..cu......9l.
0150 78 0d 0a 2d 2d 2d 2d 4d 55 4c 54 49 2d 50 41 52 x..----MULTI-PAR
0160 54 53 2d 46 4f 52 4d 2d 44 41 54 41 2d 42 4f 55 TS-FORM-DATA-BOU
0170 4e 44 41 52 59 2d 2d 0d 0a NDARY--..
这种格式与 xxd 显示的二进制数据形式非常类似,也是由地址部分、十六进制数据部分、字符部分组成,但是用 xxd 直接进行反向转换,却得不到想要的结果:

仔细对比两者,发现格式还是有一些细微的差别,主要表现在以下几点:
- xxd 地址部分有 8 位,导出的仅有 4 位
- xxd 地址部分与数据有冒号隔开,导出的没有
- xxd 数据部分是 2 个字节一组,导出的是一个字节一组
- xxd 地址和数据之间的空格仅一个、数据与字符之间的空格仅有两个,导出的有三个
经过一番测试,发现导致转换失败的原因仅有两个:冒号和随后的两个空格,因此需要对导出的数据进行一番修改:将地址与数据部分的三个空格,改为一个冒号加一个空格的形式。

行数少的情况可以用 vim 一直 j 到底,多的话就直接 G 到底,这点难不倒 vimer。
当然了,也可以直接用 sed 做替换:
sed -i 's/ /: /' data.xxd
没有添加 g,是因为后面三个空格不想替换。修改好之后,再用 xxd 就正常了:
$ xxd -r data.xxd
----MULTI-PARTS-FORM-DATA-BOUNDARY
Content-Disposition: form-data; name="userfile"; filename="file"
Content-Type: application/octet-stream
��u�!ԇ�Y�)+3�D.*u¼��P��)��mb�!������V��:
)���e?�Gx�i�
���a��}&`��� c]Ō���w���1���U�0�!]&}�@��ד&�Dm���9���}5�R�q�c-��E���w��t�%�/I��4�/4�~�n�S�cu��.��9l�x
----MULTI-PARTS-FORM-DATA-BOUNDARY--
有些 vimer 习惯在 vim 里搞定一切,这一步也可以在 vim 里做:

不过这里需要使用 vim -b 以二进制方式打开文件,否则可能得不到正确的结果。
总结
以上就是三种导出 Wireshark 网络包二进制数据的方法。
删除 formed data 头和尾等明文信息,我就能进行解密、解压等操作了!最终顺利的定位到了数据发送失败的原因。
年底了,水一篇不过分吧,祝各位牛马,都能顺利拿到年终奖,以及在即将到来的 2025,保住自己的饭碗,哈哈~
导出 wireshark 网络包二进制数据的三种方法的更多相关文章
- 关于Hive创建分区目录且能查到数据的三种方法
关于Hive创建分区目录且能查到数据的三种方法 1. 使用dfs -mkdir 和 dfs -put 分别创建分区目录和上传数据,此时执行msck repair table 表名 命令就能查询到数据 ...
- python网络编程调用recv函数完整接收数据的三种方法
最近在使用python进行网络编程开发一个通用的tcpclient测试小工具.在使用socket进行网络编程中,如何判定对端发送一条报文是否接收完成,是进行socket网络开发必须要考虑的一个问题.这 ...
- 去除DataTable重复数据的三种方法
业务需求 最近做一个把源数据库的数据批次导出到目标数据库.源数据库是采集程序采集而来的原始数据库,所以需要对其进行一些处理(过滤一些为空,长度太短或太长,非法字符,重复数据)然后在进行入库. 其中要避 ...
- 去除DataTable重复数据的三种方法(转)
转自:https://www.cnblogs.com/sunxi/p/4767577.html 业务需求 最近做一个把源数据库的数据批次导出到目标数据库.源数据库是采集程序采集而来的原始数据库,所以需 ...
- C# Entity Framework 更新数据的三种方法
例: 实体类: public class TestDbContext : DbContext { public DbSet<Test> Tests { get; set; } public ...
- TensorFlow读取数据的三种方法
tensortlfow数据读取有三种方式 placehold feed_dict:从内存中读取数据,占位符填充数据 queue队列:从硬盘读取数据 Dataset:同时支持内存和硬盘读取数据 plac ...
- Java多线程初学者指南(7):向线程传递数据的三种方法
在传统的同步开发模式下,当我们调用一个函数时,通过这个函数的参数将数据传入,并通过这个函数的返回值来返回最终的计算结果.但在多线程的异步开发模式下,数据的传递和返回和同步开发模式有很大的区别.由于线程 ...
- php获取POST数据的三种方法
方法一,$_POST $_POST或$_REQUEST存放的是PHP以key=>value的形式格式化以后的数据. $_POST方式是通过 HTTP POST 方法传递的变量组成的数组,是自动全 ...
- MVC 添加数据的三种方法
1 通过Request接收数据,进行添加 <%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<d ...
- WPF的DataGrid的某个列绑定数据的三种方法(Binding、Converter、DataTrigger)
最近在使用WPF的时候,遇到某个列的值需要根据内容不同进行转换显示的需求.尝试了一下,大概有三种方式可以实现: 1.传统的Binding方法,后台构造好数据,绑定就行. 2.转换器方法(Convert ...
随机推荐
- Vite打包碎片化,如何化解?
背景 我们在使用 Vite 进行打包时,经常会遇到这个问题:随着业务的展开,版本迭代,页面越来越多,第三方依赖也越来越多,打出来的包也越来越大.如果把页面都进行动态导入,那么凡是几个页面共用的文件都会 ...
- 双通道MIL-STD-1553B总线通讯模块
* 双通道MIL-STD-1553B总线通讯模块 * 32bi,33 MHz CPCI/PCI/总线* 每个通道为A.B双冗余总线* 单功能可设置BC/RT/BM一种工作模式* 数据传输率: 4Mb ...
- OpenELB 在 CVTE 的最佳实践
作者:大飞哥,视源电子股份运维工程师, KubeSphere 社区用户委员会广州站站长,KubeSphere Ambassador. 公司介绍 广州视源电子科技股份有限公司(以下简称视源股份)成立于 ...
- Chirpy+Github
相关网址 Chirpy 示例:网页上有官方教程,我写的肯定不全 Chirpy 示例仓库:这个就是包含官方教程的那个示例的仓库 Chirpy 模板仓库:直接 fork 这个仓库,快速搭建,没有多余的东西 ...
- ToDesk云电脑进军游戏市场,真显卡高性能,新版本可暂停使用时长!
ToDesk远程控制软件在装机量突破1.5亿后,再度迎来里程碑式的发展.今年,该公司创新推出了云电脑产品,正式涉足云计算领域.这款前沿产品一经发布,便凭借其卓越的性能和使用体验赢得了广大用户的赞誉.近 ...
- dotnet core微服务框架Jimu ~ 会员注册微服务
提供会员注册服务,用户必须注册成会员才能享受应用提供的服务,如浏览和发布新闻, 但有些服务又需要指定角色的会员才能操作,如所有会员都可以浏览新闻,只有管理员(admin)角色的会员才可以发布新闻. 有 ...
- 2023NOIP A层联测26 T3 tour
2023NOIP A层联测26 T3 tour 有意思的树上主席树. 思路 首先考虑一个点 \(p\) 能计入答案的情况,就是 \(dis(x,p)-a_p \ge a_p\). 我们把 \(x \t ...
- redis的另一个分支 keydb
今天无意间发现了redis还有一个分支keydb https://keydb.dev 是多线程的,貌似在机器内核多的情况下效果比redis效果好 访问 https://docs.keydb.dev/d ...
- nemu-wsl-环境配置
实在是不愿意用学校的虚拟平台,觉得在自己的电脑上留存一部分真的很有意思,也想捣鼓一下,于是在自己电脑上配置下最基本的环境,做下记录 准备好wsl 因为要求环境是 Ubuntu 18.04 和 gcc- ...
- (Python基础教程之十四)Python将tuple开箱为变量或参数
Python示例将N元素元组或序列开箱缩为N个变量的集合.将元组开箱缩为变量的 Python示例. 1. Python开箱元组示例 可以使用简单的赋值操作将任何序列(或可迭代)开箱缩为变量.唯一的要求 ...