最近在弄wireshark,网上资料很少,不过找到了一篇不错的,翻译过来,方便大家查看。不过设置编译环境那章写的不怎么好,可以参考下官网或其他人写的经验贴。
原文地址:http://www.codePRoject.com/Articles/19426/Creating-Your-Own-Custom-Wireshark-Dissector
相关例子源代码地址:http://www.codeproject.com/KB/ip/custom_dissector/packet-amin_src.zip
WireShark是一款强大的网络协议分析开源软件。你是否曾经为不知道怎样开发自定义协议解析器而烦恼?进一步说,是否曾试图研究过WireShark的API,但发现这过程太难了。这篇文章会告诉你怎样去开发属于你自己的协议解析器。文章把Amin Gholiha 的"A Simple IOCP Server/Client class"作为例子来说明怎样开发解析器,例子是用来解析AMIN协议的。
官网的Wireshark developer's guide 讲述了如何建立Win32开发环境,但我觉得价值不大。在本章中我会讲述得更详细些(译者注:我倒觉得官网的还可以,我的就是按照官网上的配置的,不过有一点就是Python的版本最好用配置文件里提到的版本,不然可能会出错)。
如果你没有VS2005/VS2003 等C语言编译器,你可以从网上下个(现在官网的源代码已经支持VS2010了)。
你必须下载并安装Server 2003 R2的SDK(译者注:一般安了VS的话就会自动安装相应本机操作系统对应的SDK)。
在这里不会详细描述Cygwin是什么,简单的来说,Cygwin可以使得WireShark可以在Windows平台和Linux平台下编译(译者注:貌似Linux平台下不用下载Cygwin吧,而且Linux下编译非常简单),Cygwin可以从Cygwin installer上下载并启动。
在"Select Packages" 页,需要选择一些额外的包,这些包默认是不会安装的。展开Category/Package,选中想要添加的包,点击"New" 列,使得"Skip"变成版本号数字即可。下面是列出来需要添加的包:
Archive/unzipDevel/bisonDevel/flexInterpreters/perlUtils/patchWeb/wgetAfter clicking the Next button several times, the setup will then download and install the selected packages (this may take a while).
点击几次Next后,安装程序就会下载并安装所选的包(译者注:这里说的比较简单,有几个界面作者没有说,一个是让你选择操作的种类,要么在线安装,要么只下载安装包,要么从本地安装包安装Cygwin;还一个界面是让你从哪个网站下载。都是些简单的英语,一看就懂)。
下载Python 2.4 installer并安装Python到默认路径。注意:使用Python 2.5 会无法正常编译,故不要使用2.5版本(译者注:尽量使用配置文件里提到的版本,不然真的会编译不成功,我就遇到过,另外建议不要修改默认安装路径)。
对于选择Subversion客户端软件,我的专业意见是下载并使用TortoiseSVN[^]。开启右键菜单功能可能需要重启计算机才能生效。这个功能很不错,当你在浏览试图中右键文件夹时会出现此菜单,通过他你能获取源代码树。
你可能会有点奇怪,为什么为了编写一个解析器却下载整个源代码。源代码的"plugins"文件夹里包含了例子,以后你编译的解析器也会放在这个文件夹里。
在Windows浏览器的C:/ drive 文件夹上右键。在弹出来的上下文菜单中, 选中"SVN checkout.." :在 URL of the repository中填入源代码地址http://anonsvn.wireshark.org/wireshark/trunk/。在 checkout directory中写上想到导出的文件夹c:/wireshark。点击OK. 可能会提示说需要创建一个Wireshark文件夹。选Yes。TortoiseSVN 开始检出源代码。如果下载失败,可能是因为防火墙限制的原因。 如果是这种情况,你自己可以选个好的方法处理(译者注:直接关了防火墙呗)用记事本或者其他你喜欢的文本编辑器打开C:/Wireshark/config.nmake。下面列出的几个地方都必须修改:
VERSION_EXTRA: 这里可以自定义个人版本信息。例如:-myprotocol123. Mine reads: SVN-AMINPROTOCOL. 你可以在这里写上任何你想写的东西。PROGRAM_FILES: WireShark程序将来想要安装的位置。通常保持默认值即可。MSCV_VARIANT: 这个地方很关键。如果你的VS版本被注释掉了,那么要先把其他版本VS注释掉,只保留你的VS版本。例如(译者注:作者用的VS是VS2005,所以下面列出的所有版本中,只有VS2005的宏没有被注释掉):
启动 cmd.exe (开始 > 运行 > "cmd")
Call "C:/Program Files/Microsoft Platform SDK for Windows Server 2003 R2/SetEnv.Cmd"Call "C:/Program Files/Microsoft Visual Studio 8/VC/bin/vcvars32.bat"cd c:/wireshark(译者注:上面没写清楚,应该是先启动CMD,然后运行"C:/Program Files/Microsoft Visual Studio 8/VC/bin/vcvars32.bat",再转到c:/wireshark。第2条没必要执行,至少我的没有执行却成功了。另外,所有的命令都必须在同一个CMD窗口执行,也就是说,后面提到了nmake命令也必须在此CMD中执行,不然提示无法识别nmake命令)。
VS的路径按你自己本机上的路径做相应修改。 在例子的ZIP包中, 你会发现step1.bat,step2.bat和step3.bat。 我打包这些批处理到ZIP包中是为了简化步骤。 我知道有一些更好的方式去创建这些批处理, 所以按你自己想法来执行这些步骤。
在C:/WireShark 目录中执行(需要在上面步骤8提到的同一个CMD中执行):
Collapse |Copy CodeC:/wireshark> Nmake –f Makefile.nmake verify_tools 可能会得到这样的输出:
如果提示某些东西丢失,你可能需要重新执行Cygwin安装程序。
步骤 10. 安装库文件
如果关闭了CMD,你必须重新执行步骤8。 你也可以执行step1, step2, step3 批处理以简化执行过程。在C:/Wireshark目录下执行(第一步可能会花点时间):
Collapse |Copy Codenmake –f Makefile.nmake setup nmake –f Makefile.nmake distclean步骤 11. 编译Wireshark
如果关闭了CMD,你必须重新执行步骤8。 你也可以执行step1, step2, step3 批处理以简化执行过程。
(这个命令会花费一些时间)
Collapse |Copy Code
nmake –f Makefile.nmake all 步骤 12. (可选) 创建Wireshark安装程序
我有个想法,想把我编译的WireShark版本分发给我的朋友。 通过执行下面的步骤你可以很容易的创建一个安装程序:
下载并安装 NSIS [^].下载 vcredist_x86.exe [^] 并把他放在c:/wireshark-win32/libs 目录。该目录下可能已经存在此文件,所以最好先检查下。使用CMD,按步骤8或执行我提供的Step1/2/3 批处理,转到C:/Wireshark目录下,执行: Collapse |Copy Codenmake –f Makefile.nmake packaging你会发现安装文件c:/wireshark/packaging/nsis/wireshark-setup.exe。你可以尝试运行下。3.0 执行编译好的Wireshark
想要运行WireShark的话直接执行C:/wireshark/wireshark-gtk2/wireshark.exe并且确定程序已经启动。我发现我必须先下载并安装一次标准的Wireshark后才能运行我自己编译的WireShark。这可能是因为我之前没有安装WinPcap的缘故。你可以从官网下载并安装标准WireShark。
注意:如果你是使用的是VS2005,那么你也必须使用编译WireShark时所用的VS的版本去测试解析器。由于某些原因,用VS2005编译的协议解析插件无法在主流的WireShark版本上使用。如果你是使用的其他版本,则不需要使用编译WireShark时所用的VS版本(译者注:大概意思应该是VS2005有BUG,如果用VS2005开发协议解析插件,那么开发出来的插件只能在用VS2005编译的WireShark上使用,可能我理解的有偏差,大家可以去看下英文原文)。
4.0 理解AMIN协议
Amin是一个足够说明IOCP协议的C/S结构的协议。他的协议结构非常简答,主要是基于TCP协议传输数据。这篇文章只是个说明怎样编译协议解析插件的开始,所以在这里我们只解析C/S之间传输的文本消息。传输文件则有点点复杂,这里我们将忽略此种消息类型。
4.1 数据包长度前缀
所有的Amin数据包都用前面4个字节来表示后面数据长度。这个值是以网络字节顺序,或者说MSB格式在网络上传输。网络字节顺序的意思是最重要的信息放在开头。例如,假定数据包长度是十进制12。用十六进制则为0x0000000c(如果你以long类型存储的话)。如果你从网络上接受到这个值,那么此值将会以0c 00 00 00的形式出现;这就是网络字节顺序。你可能会疑惑为什么字节顺序是反的。如果你用字节数组来表示long类型,每个字节按顺序存储值。在这种情况下,byte[0]的值是0x0c,所以0x0c写在了第一位。理解网络字节顺序这个概念很重要。
当我们使用WireShark来解析数据包时,理解2个或4个字节长度的整数在网络字节顺序或是说LSB格式下是怎样表示很重要。而在其他协议中,值的表示方式一般为主机字节顺序,即LSB。
注意:这个值表示的是接下来的数据长度,意思就是这开头的4个字节并没有包括在这个长度内。例如,如果你发送一个含有12个文本字符的数据包,长度将是12+1=13(1表示数据包包含的数据类型),综合到一起是12+1+4=17。
4.2 数据类型
Amin数据包中紧跟在长度后面的一个字节暗示了包含的数据类型。我们只处理类型为0x00的数据包,这代表了数据类型是文本。注意:一个字节的话就不存在字节顺序了。
4.3 Null结尾的字符串
在这里我们可以通过Amin的MFC界面构造一个以NULL结尾的字符串。默认的字符串是'ABCDEFGHIJKLMNOPQRST123456789'。
5.0 使用不包含自定义插件的Wireshark观察Amin协议数据包
你可以从这里下载由Amin编写的IOCP协议的C/S程序。注意:本文章不会去讨论WireShark的基本使用方法。假定你曾经使用过并且知道怎样去摆弄WireShark。下图是没有AMIN协议解析器时的WireShark界面。
注意到WireShark只是简单的把数据包解释为"Data"。在数据展示区里,我们可以知道我们的AMIN协议数据包长度为"1f 00 00 00 00"。接下来的是数据类型,在数据类型后面的是用ASCII码"ABC..."。
6.0 编写自己的解析器
在WireShark源代码里有个文件夹叫Plugins,里面包含了很多标准协议解析器。然而,从那些解析器找出一个简单一点做参考是有点难度的。[So, in combination with the H223 dissector, random examples from the internet, and the developer guide,]我在例子源代码里准备了一个简单的例子,这个例子可以在Amin文件夹下面找到。
6.1 make文件
为了去解析你的协议,你必须创建一些文件以便去编译你的解析器。最简单的方法就是从例子源代码里的AMIN文件夹下复制下面的文件。
Makefile.am - 这个是UNIX/Linux平台下的makefile模板Makefile.common - 这个文件包含了内置插件所依赖的文件Makefile.nmake - 这个文件是Windows平台下WireShark内置插件的makefilemoduleinfo.h - 内置插件的版本信息moduleinfo.nmake - Windows平台下DLL的版本信息packet-amin.c - 你自己写的解析器的源代码文件plugin.rc.in - Windows平台下的DLL资源模板 一旦你复制了相应的文件到C:/Wireshark/plugins/yourprotocolname,你就可以按照下面的步骤编辑这些文件。
把文件中的所有AMIN改成你的协议名称,但行42、43、114除外。在Makefile.common中,把所有AMIN替换成你的协议名称,行31除外。在moduleinfo.h中,把所有AMIN替换成你的协议名称,行8除外。另外你可以在行16把版本改成你自己想要的版本标识。这样的话就方便你管理你的解析器计划。在 moduleinfo.nmake中,把所有AMIN替换成你的协议名称,行6除外。行9、10、11和12必须与moduleinfo.h的行16标记的版本标志对应。在packet-amin.c中,第一件事就是把文件名改为packet-你协议名称.c. 所有的解析器都遵从本规定: packet-协议名称.c。在源文件中,你可以简单的吧"amin"替换成""。记住,确定所有的"AMIN"和"amin"都替换了。在某些情况下,你可能无法注册过滤器名称,因而WireShark会运行失败。这一点一定要注意。现在该做剩下的事情了,现在将开始写代码了。7.0 自定义解析器代码
你可以用你喜欢的文本编辑器打开packet-yourprotocol.c。让我们一行一行的讲解:
所有的解码器都使用标准的头文件。你当然也需要把theconfig.h,glib.h和packet.h放到开头。 我的习惯是尽可能的不使用数字常量(译者注:就是把数字用变量代替)。 这个变量对WireShark来说很重要。WireShark用他来标识我们的协议。 WireShark用这个解码器句柄来引用解码器。 这个解码函数的前置声明。我们将在后面实现这个函数。 WireShark将用这个端口号去判断数据包是否属于AMIN协议。
这里是数据包类型相关的配置信息。你可以按你自己协议的需要定义。[It adds a level of detail that makes the dissector look well thought out]
这里我们将我们协议的子组件与ID绑定。
这个函数的作用是注册我们的协议,注意我们是怎样传递端口号和解码句柄的。
上面的数组定义了我们想要显示的信息。这些声明只是一些简单的定义,在我们以后解码数据包的时候WireShark会使用这些信息去区分数据类型。
上面的数组简单的把ID绑定到了我们之前的定义上。记着要与上面定义的hf_
andett_
data 一一对应。
上面是注册我们协议的过程。在我所看过的大多数例子中,他们都会[根据第一个函数返回结果]检查proto_amin
是否已经初始化好。然而,WireShark官方开发者中的名叫"Jaap"的人发邮件给我说没必要去执行这个过程。后面注册协议和解码句柄的过程会保证解码器注册成功。
解码函数用来解码实际的数据,以及显示这些数据包的详细信息。
首先,需要初始化一些树指针和信息单元:
接下来看下INFO列是否显示我们协议的标签"AMIN"。如果没有,则显示之。
如果用户想把此数据包的信息添加到主解码树中,则处理这个请求。
这个调用是将我们的解码出来的解码树添加到主解码树种。
在这里,把我们的解码树添加上去,以便我们有一个可以折叠的树头。接下来构造子树,我们取得了数据段的字节长度。按网络字节顺序编码。如果其他人有更好的tvb_get
函数去读取长度值,欢迎提出来。
7.1 编译packet-yourprotocol.c
如果你的CMD窗口没有关掉,你可以直接使用那个窗口。如果关了,执行step1/2/3.bat ,然后转到c:/wireshark/plugins/yourprotocol目录。如果你想编译我的源代码,则转到c:/wireshark/plugins/amin下。在"请按任意键继续"提示下,执行下面的命令:
如果编译成功,你应当可以看到yourprotocol.dll。复制此文件到C:/WireShark/wireshark-gtk2/plugins/0.99.7-YOUR-BUILD。这个文件夹是用来存放其他解码DLL分支的地方。如果你之前安装了你编译的WireShark,则还需要放到c:/program files/wireshark/plugins/0.99.7-YOUR-BUILD 里,前面的路径按你安装的具体位置更改下。前提是你复制了你编译出来的DLL到合适的位置,你将能够启动WireShark并解码AMIN的数据包了。一个比较好的测试是否已经部署好的方法是在"filter"中键入你的协议名称看数据的底色是绿色还是红色,如果像下面显示的那样,则表示解码器加载对了。
这是WireShark上AMIN协议的截图。
8.0 提示
8.1 CodeBase
我在CodeBase[^]上发现了大量的例子。如果不参考这个网站,写解码器将是一个艰巨的任务。你们应当花些时间阅读下官方的WireShark API 文档。
同事告诉我CodeBase网站是一个付费网站。我有个方法能使用CodeBase而无需认证用户。使用这个链接就可以(使用搜索框以便找到非文档方法)。
8.2 Wireshark过滤
After you've defined your data type map, you can use the '.' Operator to limit the packets being displayed. For example,amin.type==0 will only show packets where the type equals zero.
当你定义了你的数据类型映射后,你可以使用'.'操作来不显示你的数据包。例如,amin.type==0 只显示那些类型为0的数据包。
8.3 其他列子
在plugins文件夹中能找到更复杂的例子。我的建议是去看看H223解码器。这个解码器覆盖了例如TCP方面的知识,以及怎样将数据包组合到一起解码(例如一个分割成多个数据包的会话)。
8.4 捕捉循环数据包
如果你想用WireShark抓取本地数据包,例如127.0.0.1 。你必须执行一些额外的步骤才行。这个链接能帮助你解决这个问题。那个网站上的建议步骤如下:
安装一个循环适配器。 Windows 2003[^], Windows XP[^], Windows 2000[^]转到MS的循环适配器属性页。设置:IP 10.0.0.10掩码 255.255.255.0适配器/额外设置/网络地址: 55-55-55-55-55-55在命令行中 (cmd.exe):
接着:
你可以通过下面的命令测试下:
9.0 总结
如果协议本身并不复杂,那么在WireShark里编写一个解码器是一个很容易的事。此外,[the guys at Wireshark greatly appreciate those who take the time to legally reverse engineer protocols for inclusion within the Wireshark distribution.]
10.0 参考文献
"A Simple IOCP Server/Client Class", Amin Gholiha, The Code Project, 09/05/2005Wireshark Developer's Guide, 22223 For Wireshark 0.99.6H223 Example MX Telecom Ltd.Wireshark – Network Traffic Analyzer, Gerald Combs11.0 历史
July 22, 2007 - Fixed a typo in packet-amin.c: tvb_get_uint8 -> tvb_get_guint8. Thanks Keith!July 9, 2007 - Added a CodeBase link that allows you to search without being a member of CodeBase. Not sure if this is legal, send me an email if it isn't.July 3, 2007 - Removed extra "nmake Makefile.nmake setup" in tools installation section.July 2, 2007 - Updated source code and article to reflect suggestions made by Jaap. Changes include:Changed static int intialized=FALSE
to static gboolean
.Removed #include <gmodule.h>
, not needed.Commented out if(proto_amin == -1){}
.Moved the if(check_col(pinfo->cinfo, COLINFO)){
routine out of if(tree)
.Fixed comments on network versus host byte order.Added section 8.4 on capturing loopback packets.July 1, 2007 - Spell checking and other grammatical corrections. Fixed an issue withpackettypename[]
where{0,NULL}
was required to avoid a seg fault. Thank you Ronnie.June 29, 2007 – First draft.许可证
这篇文章,包括文章内容和源代码,都遵循许可证The Code Project Open License (CPOL)
>>看来一套多人开发的软件,其架构的设计是唯一性的,通过一个接口连接各种功能的插件,以实现为先前设计好的架构增加新功能,可复用性
新闻热点
疑难解答