Skip to content
Wireshark Wiki 中文翻译整理专题首页原始页面

使用 Python 扩展 Wireshark

注意:自 2014 年 6 月起,Wireshark 已移除 Python 支持(commit 1777f608)。一个替代方案可能是 https://github.com/ashdnazg/pyreshark。

现在仍然可以用 python 为 Wireshark 编写 dissector plugin 吗?

该项目的目标是让开发者能够轻松使用 Python 扩展 Wireshark。

这是一个开发中的项目,因此属于实验性质。目前最好不要在生产环境中使用。不过它很适合用于原型开发,因为语法相当简洁。

在尝试使用 Python API 之前,最好已经阅读 doc/README.developer 和 doc/README.python。

要求

你必须有有效的 Python 环境(python >= 2.3)和 ctypes。

从 2.5 版本开始,ctypes 是 Python 包的一部分。如果你使用的是更早版本,则必须自行安装。

编译时启用 Python 支持

./configure --with-python

对于常规安装,所有 Pythonic 相关内容都会安装在 {libdir}/wireshark/python/{VERSION}/ 中。

所有 dissectors 都可以添加到 {libdir}/wireshark/python/{VERSION}/wspy_dissectors/。你完全不需要在 Makefile 中注册你的协议。只需在此目录中添加一个 <dissectorname>.py,它就会在 Wireshark/Tshark 启动时被检测到。

用 Python 编写你的第一个 dissector

这个 Python binding 的编写初衷是简化 dissector 的开发(少写代码),同时不失去 libwireshark 提供的能力。因此,你必须遵循一些约定。

有效的 dissector 骨架

 from wspy_dissector import Dissector class homeplug(Dissector): def protocol_ids(self): return [ ("ethertype", 0x887B, None) ] def dissect(self): print 'yahoo!' def register_protocol(): return homeplug("HomePlug protocol", "HomePlug", "homeplug")

这个 dissector 在解析 homeplug protocol 的数据包时,会在控制台打印“yahoo!”。

注意:homeplug dissector 已存在于 wireshark-1.4.2 中,因此虽然这个示例是有效的,但如果你真的想尝试它,应该选择另一个名称。

一个有效的 dissector 由 2 个主要部分组成。让我们看看它如何工作:

  • 定义 dissector:class homeplug 被定义为继承自 Dissector,后者包含为你简化工作的所有魔法内容。

  • protocol_ids 方法必须返回三个值的列表,这些参数都用于 dissector_add

  • 第三个参数可以定义为 None,它会为此 dissector 创建一个新的 handle(create_dissector_handle())。

  • 你也可以使用 self.find_dissector 或 self.create_dissector_handle()。

  • dissect 方法是在需要由此 dissector 解析数据包时被调用的方法。

  • register_protocol 函数:此函数必须存在,才能注册你的 dissector。此函数会在 Wireshark 注册所有协议时被调用。它基本上必须返回已实例化 dissector 的 handle。

解析某些内容

 from wspy_dissector import Dissector from wspy_dissector import FT_UINT8, FT_NONE from wspy_dissector import BASE_NONE class homeplug(Dissector): def protocol_ids(self): return [ ("ethertype", 0x887B, None) ] def dissect(self): self.dissect_mctrl() def dissect_mctrl(self): hf = self.fields() subt = self.subtrees() self.c_tree = self.tree() tree = self.c_tree.add_item(hf.homeplug_mctrl, length=1, adv=False) mctrl_tree = tree.add_subtree(subt.mctrl) mctrl_tree.add_item(hf.homeplug_mctrl_rsvd, length=1, adv=False) mctrl_tree.add_item(hf.homeplug_mctrl_ne, length=1) def register_protocol(): tp = homeplug("HomePlug protocol", "HomePlug", "homeplug") hf = tp.fields() hf.add("Mac Control Field", "homeplug.mctrl", FT_NONE, BASE_NONE) hf.add("Reserved", "homeplug.mctrl.rsvd", FT_UINT8, bitmask=0x80) hf.add("Number of MAC Data Entries", "homeplug.mctrl.ne", FT_UINT8, bitmask=0x7F) subt = tp.subtrees() subt.add('mctrl') return tp

高级内容

添加基础 Subtree

这个阶段已经自动化,但你可能想要对它进行个性化设置。下面是具体做法。

 from wspy_dissector import Dissector class homeplug(Dissector): def protocol_ids(self): return "ethertype", 0x887B def dissect(self): subt = self.subtrees() main_tree = self.tree() p_tree = main_tree.add_item(self.protocol()) homeplug_tree = p_tree.add_subtree(subt.homeplug) def register_protocol(): tp = homeplug("HomePlug protocol", "HomePlug", "homeplug") subt = tp.subtrees() subt.add('homeplug') return tp

定义将显示解析树的基础树的步骤:

  • 在 homeplug dissector 中使用 Subtree.add(<treename>) 注册 protocol subtree。此步骤在 register_protocol 中完成,然后返回 homeplug dissector 的 handle。

  • 在 dissect 方法中显示 subtree:

  • subt = self.subtrees() 返回一个 Subtree 对象。你可以基于此对象引用你想要的任何 subtree。

  • 例如,当你想用 p_tree.add_subtree 方法创建 subtree “homeplug”时,必须传入此 subtree 的引用。你可以使用 subt.homeplug 来做到这一点。注册时定义的每个 subtree 以后都可以作为 Subtree 对象的属性访问。

注意:定义一个与创建 dissector 时使用的第三个参数(在此例中为“homeplug”)同名的 subtree,会使你负责添加此 dissector 的 main subtree。否则,如果未定义此 subtree,系统会自动为你添加这个 main subtree。

直接使用 libwireshark

其想法是让用户可以直接访问一些尚未由此 binding 封装的 libwireshark 函数。

……开发中……

限制(TODO)

  • dissect_tcp_pdus
  • RVALS, VALS, ...
  • conversation
  • tap
  • having a dissect function differentiated for tcp and udp
  • and probably many more ...

Imported from https://wiki.wireshark.org/Python on 2020-08-11 23:23:44 UTC

相关 Wireshark Wiki 页面

网络分析技术档案