[工具使用] wireshark protobuf 插件

628 0
Honkers 2026-1-17 06:48:22 来自手机 | 显示全部楼层 |阅读模式

搞网络开发的时候,涉及到很多私有协议。方便是方便,不过抓包分析问题就麻烦了,wireshark是不可能会为我们自己的网络协议开发分析工具的,唯有自己开发协议分析插件。在私有协议方面,google protobuf是一个类似与IDL的语言,用于定义消息接口,并且支持很多语言,原生支持C++、Java和python,而且还有很多第三方的支持,基本上支持C、C#、object-c,AS3,PHP等.目前protobuf的解析并不是wireshark内置支持的,不排除以后的版本会支持。当前网络上有一个工程可以支持protobuf的解析(protobuf-wireshark),但是该插件原生支持的只有linux版本,而且还只支持UDP解析。经本人改造,已经可以支持windows,并且同时支持TCP和UDP解析。TCP时,需要在protobuf之上加上一个4字节的数据长度,用于支持后续的protobuf消息的大小。


_ _ _ _  _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

消息长度 protobuf二进制消息内容

消息长度的值只包含protobuf消息的大小,不包含自己4个字节的长度。例如protobuf长度为12字节时, 消息长度里面的值,应该是 00 00 00 0c,总的数据长度为16个字节.(如果无法解析数据长度,调换一下网络字节序)

另外对protobuf消息的定义也有一定的限制,必须有一个顶层的消息,例如Message1 和Message2如果是并列的消息,需要有一个Message来包含Message1和Message2.

【配置】

protobuf的配置文件放在C:\Program Files\Wireshark\protobuf目录下面,C:\Program Files\Wireshark\为wireshark在电脑上的安装目录。protobuf文件夹默认是没有的,自己创建。

把附件 *.proto;*.conf放在protobuf目录下面,把dll放在plugins\1.8.6目录下面。

protobuf-wireshark 插件下载, 测试包下载

基于tcp的protobuf包


基于UDP的protobuf包


插件代码:(代码基于google 上面的protobuf-wireshark 修改)

packet-protobuf.h

  1. #ifdef HAVE_CONFIG_H
  2. # include "config.h"
  3. #endif
  4. #include <gmodule.h>
  5. #include <epan/packet.h>
  6. #include <epan/prefs.h>
  7. #include <epan/emem.h>
  8. #include <epan/dissectors/packet-tcp.h>
  9. #include <epan/filesystem.h>
  10. #include <errno.h>
  11. #include <string.h>
  12. /* TCP数据包的固定头大小*/
  13. #define FRAME_HEADER_LEN 4
  14. void proto_register_protobuf();
  15. void proto_reg_handoff_protobuf();
  16. static void dissect_protobuf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
  17. static void dissect_protobuf_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
  18. /* Define version if we are not building ethereal statically */
  19. #ifndef ENABLE_STATIC
  20. G_MODULE_EXPORT const gchar version[] = "0.0";
  21. #endif
  22. static int proto_protobuf = -1;
  23. static dissector_handle_t protobuf_handle;
  24. // Protocol field variables - START
  25. static int hf_protobuf = -1;
  26. // Protocol field variables - END
  27. int wireshark_pb_process_protobuf(void *tree_root, int srcport, int dstport, int item_id, void *tvb, void *buf, int buf_size);
  28. void wireshark_pb_process_protobuf_register_proto( int proto, const char* dirname );
  29. void wireshark_pb_process_protobuf_register_ports();
  30. void wireshark_pb_process_protobuf_register_subtree( int proto, const char* name,
  31. int *handle, int ** tree_handle );
  32. void wireshark_pb_process_protobuf_register_field( int proto, int type,
  33. const char* name, const char * fullName,
  34. int *handle );
  35. /* Register plugin - START */
  36. #ifndef ENABLE_STATIC
  37. G_MODULE_EXPORT void
  38. plugin_register(void) {
  39. /* register the new protocol, protocol fields, and subtrees */
  40. if (proto_protobuf == -1) { /* execute protocol initialization only once */
  41. proto_register_protobuf();
  42. }
  43. }
  44. G_MODULE_EXPORT void
  45. plugin_reg_handoff(void){
  46. proto_reg_handoff_protobuf();
  47. }
  48. #endif
  49. void proto_register_protobuf(void) {
  50. module_t *protobuf_module;
  51. char* dirname;
  52. if (proto_protobuf == -1) {
  53. proto_protobuf = proto_register_protocol (
  54. "protobuf ",/* name */
  55. "protobuf",/* short name */
  56. "protobuf"/* abbrev */
  57. );
  58. }
  59. protobuf_module= prefs_register_protocol(proto_protobuf, proto_reg_handoff_protobuf);
  60. /*char**/ dirname = get_persconffile_path("protobuf", FALSE, FALSE);
  61. if( test_for_directory( dirname ) != EISDIR )
  62. {
  63. /* Although dir isn't a directory it may still use memory */
  64. g_free( dirname );
  65. dirname = get_datafile_path("protobuf");
  66. if( test_for_directory( dirname ) != EISDIR )
  67. {
  68. g_free( dirname );
  69. dirname = NULL;
  70. }
  71. }
  72. wireshark_pb_process_protobuf_register_proto( proto_protobuf, dirname );
  73. }
  74. void proto_reg_handoff_protobuf (void) {
  75. static int Initialized=FALSE;
  76. unsigned int i = 0;
  77. if (!Initialized) {
  78. protobuf_handle = create_dissector_handle(dissect_protobuf, proto_protobuf);
  79. wireshark_pb_process_protobuf_register_ports();
  80. }
  81. }
  82. /* Register plugin - END */
  83. /* 解析一个TCP数据包,wireshark会自动做分包和合并处理,此数据是一个完成的数据包,包含包头的内容*/
  84. static void dissect_protobuf_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
  85. {
  86. /* TODO: implement your dissecting code */\
  87. if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
  88. col_set_str(pinfo->cinfo, COL_PROTOCOL, "protobuf-tcp");
  89. }
  90. /* Clear out stuff in the info column */
  91. if(check_col(pinfo->cinfo,COL_INFO)){
  92. col_clear(pinfo->cinfo,COL_INFO);
  93. }
  94. if (tree) { /* we are being asked for details */
  95. /* Always make sure that offset is LESS than maxOffset */
  96. gint data_len = tvb_get_ntohl(tvb, 0);
  97. proto_item * ti = NULL;
  98. tvbuff_t * next_tvb = tvb_new_subset_remaining (tvb,4);
  99. gint maxOffset = tvb_length(next_tvb);
  100. ti = proto_tree_add_item(tree,proto_protobuf,tvb,0,4,ENC_NA);
  101. proto_item_append_text(ti, ", Length %d",data_len);
  102. wireshark_pb_process_protobuf((void *) tree, pinfo->srcport, pinfo->destport, hf_protobuf,
  103. (void *)next_tvb, (void *)tvb_get_ptr(next_tvb,0,data_len), data_len);
  104. }
  105. }
  106. /* TCP数据包的总长度,包含包头长度 */
  107. static guint get_protobuf_message_len(packet_info *pinfo, tvbuff_t *tvb, int offset)
  108. {
  109. /* TODO: change this to your needs */
  110. return (guint)tvb_
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

中国红客联盟公众号

联系站长QQ:5520533

admin@chnhonker.com
Copyright © 2001-2026 Discuz Team. Powered by Discuz! X3.5 ( 粤ICP备13060014号 )|天天打卡 本站已运行