最近在弄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"变成版本号数字即可。下面是列出来需要添加的包:
After 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"文件夹里包含了例子,以后你编译的解析器也会放在这个文件夹里。
用记事本或者其他你喜欢的文本编辑器打开C:\Wireshark\config.nmake。下面列出的几个地方都必须修改:
启动 cmd.exe (开始 > 运行 > "cmd")
(译者注:上面没写清楚,应该是先启动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中执行):
C:\wireshark> Nmake –f Makefile.nmake verify_tools
可能会得到这样的输出:
如果提示某些东西丢失,你可能需要重新执行Cygwin安装程序。
如果关闭了CMD,你必须重新执行步骤8。 你也可以执行step1, step2, step3 批处理以简化执行过程。在C:\Wireshark目录下执行(第一步可能会花点时间):
nmake –f Makefile.nmake setup
nmake –f Makefile.nmake distclean
如果关闭了CMD,你必须重新执行步骤8。 你也可以执行step1, step2, step3 批处理以简化执行过程。
(这个命令会花费一些时间)
Collapse |Copy Code
nmake –f Makefile.nmake all
我有个想法,想把我编译的WireShark版本分发给我的朋友。 通过执行下面的步骤你可以很容易的创建一个安装程序:
nmake –f Makefile.nmake packaging
想要运行WireShark的话直接执行C:\wireshark\wireshark-gtk2\wireshark.exe并且确定程序已经启动。我发现我必须先下载并安装一次标准的Wireshark后才能运行我自己编译的WireShark。这可能是因为我之前没有安装WinPcap的缘故。你可以从官网下载并安装标准WireShark。
注意:如果你是使用的是VS2005,那么你也必须使用编译WireShark时所用的VS的版本去测试解析器。由于某些原因,用VS2005编译的协议解析插件无法在主流的WireShark版本上使用。如果你是使用的其他版本,则不需要使用编译WireShark时所用的VS版本(译者注:大概意思应该是VS2005有BUG,如果用VS2005开发协议解析插件,那么开发出来的插件只能在用VS2005编译的WireShark上使用,可能我理解的有偏差,大家可以去看下英文原文)。
Amin是一个足够说明IOCP协议的C/S结构的协议。他的协议结构非常简答,主要是基于TCP协议传输数据。这篇文章只是个说明怎样编译协议解析插件的开始,所以在这里我们只解析C/S之间传输的文本消息。传输文件则有点点复杂,这里我们将忽略此种消息类型。
所有的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。
Amin数据包中紧跟在长度后面的一个字节暗示了包含的数据类型。我们只处理类型为0x00的数据包,这代表了数据类型是文本。注意:一个字节的话就不存在字节顺序了。
在这里我们可以通过Amin的MFC界面构造一个以NULL结尾的字符串。默认的字符串是'ABCDEFGHIJKLMNOPQRST123456789'。
你可以从这里下载由Amin编写的IOCP协议的C/S程序。注意:本文章不会去讨论WireShark的基本使用方法。假定你曾经使用过并且知道怎样去摆弄WireShark。下图是没有AMIN协议解析器时的WireShark界面。
注意到WireShark只是简单的把数据包解释为"Data"。在数据展示区里,我们可以知道我们的AMIN协议数据包长度为"1f 00 00 00 00"。接下来的是数据类型,在数据类型后面的是用ASCII码"ABC..."。
在WireShark源代码里有个文件夹叫Plugins,里面包含了很多标准协议解析器。然而,从那些解析器找出一个简单一点做参考是有点难度的。[So, in combination with the H223 dissector, random examples from the internet, and the developer guide,]我在例子源代码里准备了一个简单的例子,这个例子可以在Amin文件夹下面找到。
为了去解析你的协议,你必须创建一些文件以便去编译你的解析器。最简单的方法就是从例子源代码里的AMIN文件夹下复制下面的文件。
一旦你复制了相应的文件到C:\Wireshark\plugins\yourprotocolname,你就可以按照下面的步骤编辑这些文件。
你可以用你喜欢的文本编辑器打开packet-yourprotocol.c。让我们一行一行的讲解:
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
函数去读取长度值,欢迎提出来。
如果你的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协议的截图。
我在CodeBase[^]上发现了大量的例子。如果不参考这个网站,写解码器将是一个艰巨的任务。你们应当花些时间阅读下官方的WireShark API 文档。
同事告诉我CodeBase网站是一个付费网站。我有个方法能使用CodeBase而无需认证用户。使用这个链接就可以(使用搜索框以便找到非文档方法)。
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的数据包。
在plugins文件夹中能找到更复杂的例子。我的建议是去看看H223解码器。这个解码器覆盖了例如TCP方面的知识,以及怎样将数据包组合到一起解码(例如一个分割成多个数据包的会话)。
如果你想用WireShark抓取本地数据包,例如127.0.0.1 。你必须执行一些额外的步骤才行。这个链接能帮助你解决这个问题。那个网站上的建议步骤如下:
接着:
你可以通过下面的命令测试下:
如果协议本身并不复杂,那么在WireShark里编写一个解码器是一个很容易的事。此外,[the guys at Wireshark greatly appreciate those who take the time to legally reverse engineer protocols for inclusion within the Wireshark distribution.]
static int intialized=FALSE
to static gboolean
.#include
, not needed.if(proto_amin == -1){}
.if(check_col(pinfo->cinfo, COLINFO)){
routine out of if(tree)
.packettypename[]
where{0,NULL}
was required to avoid a seg fault. Thank you Ronnie.
这篇文章,包括文章内容和源代码,都遵循许可证The Code Project Open License (CPOL)
>>看来一套多人开发的软件,其架构的设计是唯一性的,通过一个接口连接各种功能的插件,以实现为先前设计好的架构增加新功能,可复用性