wireshark protobuf 插件

搞网络开发的时候,涉及到很多私有协议。方便是方便,不过抓包分析问题就麻烦了,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

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include <gmodule.h>
#include <epan/packet.h>
#include <epan/prefs.h>
#include <epan/emem.h>
#include <epan/dissectors/packet-tcp.h>
#include <epan/filesystem.h>
#include <errno.h>
#include <string.h>

/* TCP数据包的固定头大小*/
#define FRAME_HEADER_LEN 4
void proto_register_protobuf();
void proto_reg_handoff_protobuf();
static void dissect_protobuf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
static void dissect_protobuf_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);


/* Define version if we are not building ethereal statically */
#ifndef ENABLE_STATIC
G_MODULE_EXPORT const gchar version[] = "0.0";
#endif


static int proto_protobuf = -1;

static dissector_handle_t protobuf_handle;

// Protocol field variables - START
static int hf_protobuf = -1;
// Protocol field variables - END

int wireshark_pb_process_protobuf(void *tree_root, int srcport, int dstport, int item_id, void *tvb,  void *buf, int buf_size);
void wireshark_pb_process_protobuf_register_proto( int proto, const char* dirname );
void wireshark_pb_process_protobuf_register_ports();
void wireshark_pb_process_protobuf_register_subtree( int proto, const char* name,
                                                int *handle, int ** tree_handle );
void wireshark_pb_process_protobuf_register_field( int proto, int type,
                                                const char* name, const char * fullName,
						int *handle );
/* Register plugin - START */
#ifndef ENABLE_STATIC
G_MODULE_EXPORT void
plugin_register(void) { 
	/* register the new protocol, protocol fields, and subtrees */
	if (proto_protobuf == -1) { /* execute protocol initialization only once */
		proto_register_protobuf();
	}
}
G_MODULE_EXPORT void
plugin_reg_handoff(void){
	proto_reg_handoff_protobuf();
}
#endif
void proto_register_protobuf(void) {

	module_t *protobuf_module;
	char* dirname;
	if (proto_protobuf == -1) {
		proto_protobuf = proto_register_protocol (
				"protobuf ",/* name */
				"protobuf",/* short name */
				"protobuf"/* abbrev */
			);
		}
	protobuf_module= prefs_register_protocol(proto_protobuf, proto_reg_handoff_protobuf);

        /*char**/ dirname = get_persconffile_path("protobuf", FALSE, FALSE);
        if( test_for_directory( dirname ) != EISDIR ) 
	{
            /* Although dir isn't a directory it may still use memory */
            g_free( dirname );

            dirname = get_datafile_path("protobuf");

            if( test_for_directory( dirname ) != EISDIR ) 
            {
                g_free( dirname );
                dirname = NULL;
            }
        }

        wireshark_pb_process_protobuf_register_proto( proto_protobuf, dirname );
}



void proto_reg_handoff_protobuf (void) {
	static int Initialized=FALSE;
	unsigned int i = 0;

	if (!Initialized) {
		protobuf_handle = create_dissector_handle(dissect_protobuf, proto_protobuf);

		wireshark_pb_process_protobuf_register_ports();	  
	}
}
/* Register plugin - END */



/* 解析一个TCP数据包,wireshark会自动做分包和合并处理,此数据是一个完成的数据包,包含包头的内容*/
static void dissect_protobuf_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    /* TODO: implement your dissecting code */\
		if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
				col_set_str(pinfo->cinfo, COL_PROTOCOL, "protobuf-tcp");
			}
	
			/* Clear out stuff in the info column */
			if(check_col(pinfo->cinfo,COL_INFO)){
				col_clear(pinfo->cinfo,COL_INFO);
			}
	
	
			if (tree) { /* we are being asked for details */
	
			  /* Always make sure that offset is LESS than maxOffset */
			  gint data_len = tvb_get_ntohl(tvb, 0);
			  proto_item * ti = NULL;
		      tvbuff_t * next_tvb = tvb_new_subset_remaining (tvb,4);
		      gint maxOffset = tvb_length(next_tvb);

			  ti = proto_tree_add_item(tree,proto_protobuf,tvb,0,4,ENC_NA);
			  proto_item_append_text(ti, ", Length %d",data_len);
				  wireshark_pb_process_protobuf((void *) tree, pinfo->srcport, pinfo->destport, hf_protobuf, 
				(void *)next_tvb,  (void *)tvb_get_ptr(next_tvb,0,data_len), data_len);
			}
}

/* TCP数据包的总长度,包含包头长度 */
static guint get_protobuf_message_len(packet_info *pinfo, tvbuff_t *tvb, int offset)
{
    /* TODO: 
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值