【背景】
最近项目上有一个业务需要从网络上抓包和发包,应用是在JAVA平台上搭建,业界比较成熟的Winpcap组件则是在DLL的,所以我们用到一个开源组件Jpcap来桥接。Jpcap包含了一个jar包和一个dll,jar负责跟java接口,dll负责与winpcap接口。
【问题】
本来一切正常,可是到了项目后期竟然发生了一系列偶发性JVM crash事故。这类问题对我来说是比较头疼的,原因有二。第一是没有重现的规律(改过bug的程序员都知道,找到重现规律就搞定这个bug的1/3了,debug到代码行就解决了2/3了,剩下动手改只是小事一桩);第二是本地代码出错,纯粹Java的程序员往往比较恐惧跟native,因为那意味着必须跟c语言甚至汇编语言打交道。
今天周五,下周一项目交测,看来只得硬着头皮上了。
【思路一、分析错误日志】
STEP1: 分析工程目录下众多的hs_err_pidxxxx.log,可以看出,所有的日志都表明在同一个地方出的错--Jpcap.dll+0x1bf2
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code,
C=native code)
V [jvm.dll+0x105eed]
C [Jpcap.dll+0x2506]
C [Jpcap.dll+0x1ac6]
j jpcap.JpcapCaptor.getPacket()Ljpcap/packet/Packet;+0
STEP 2:将Jpcap.dll 反向工程,我使用的是VC/bin/dumpbin.exe /exports /disasm Jpcap.dll > Jpcap.asm
10001AC1: E8 7A 04 00 00 call 10001F40
10001AC6: 8B 44 24 2C mov eax,dword ptr [esp+2Ch]
10001ACA: 83 C4 18 add esp,18h
10001ACD: 5F pop edi
10001ACE: 5E pop esi
10001ACF: 59 pop ecx
10001AD0: C2 08 00 ret 8
找到10001AC6(要加ImageBase,一般是10000000,可以通过dumpbin /headers确认),发现发生错误的时候在call 10001F40,本段asm对应JpcapCaptor.c的Java_jpcap_JpcapCaptor_getPacket方法,从c代码可以看出getPacket方法只有三个位置在call其他方法。回到asm,离ret 8如此之近,猜想应该是最后一个位置的get_packet();
get_packet()的c代码长达近两百行,通过asm与c对比的方式寻找错误位置显然不太现实,此路不通,尝试第二方案。
【思路二、调试代码】
STEP3:
前面的尝试虽然失败,但至少可以知道问题出在get_packet();于是我在该方法里部署了很多printf,重新编译成dll,然后就等着JVM crash,遗憾的是,从上午9点等到13点,一次错误都没有。突然想起来,今天周六,其他人的机器都不开,看来跟网络环境有关。没办法,只能等周一才能继续了,回家打机去。
STEP4:
周一,果然零星出现了几次crash,在反复几次修改printf之后,总算有点收获了。
void get_packet(struct pacp_pkthdr header,u_char *data,jobject *packet,int id){
u_short nproto,tproto;
short clen=header.caplen,hlen;
u_char *orig_data=data;
printf("data=%d=%x,packetLength=%d,caplen=%d
\n",*data,*data,header.len,clen);
...
}
打出来的结果是:
data=108=6c,packetLength=32885,caplen=-32651
意思是,包长32885,抓包得到的长度是-32651,问题是显而易见的,short只支持-32768 到 32767。
找到问题所在,剩下的就小事一桩鸟,short改成u_short,只加了2个字符。
第一次跟踪c代码,走了不少弯路,最后发现是这么小的问题,真是太初级了。
该问题已同时提交维护组http://groups.google.com/group/jpcap
分享到:
相关推荐
jpcap包的学习笔记(总结得很不错),十分详细,包括配置,安装等
基于Jpcap的IP数据包分析,包含对tcp/ip首部的分析以及jpcap的使用……
基于Jpcap的TCPIP数据包分析.rar
基于JPcap的网络流量分析研究与应用报告 详细介绍jpcap的类和接口,分析网络流量,并进行研究分析
可以捕获和分析IP数据包,NETBEAN下运行通过。只要jpcap配置正确,保证可以运行。xixi代码,保证质量。谢谢大家长时间的支持!我会继续努力,为大家上传过多有用的资源的!!!改一下文件名哦~~~
Jpcap version 0.06.0
采用JPCAP开源库开发的一款网络抓包工具.简单易用.
用Jpcap,你可以开发应用程序捕获数据包从一个网络接口和可视化/分析他们在java。您还可以开发Java应用程序通过网络接口发送任意数据包。 Jpcap已在微软视窗(98/2000/XP/Vista)测试,Linux操作系统(Fedora的,的...
java利用jpcap进行数据包的捕获与分析的重要资料
java 网络通讯报文监听。。。。 jpcap.jar 和 jpcap.dll(32位动态库和64位动态库),需要安装wincap
jpcap的Jpcap.dll和jpcap.jar。有一篇原创博文的评论说:“为什么我下载的jpcap压缩包中没有jpcap.jar呢”,故上传该资源方便其下载。哈哈哈啦啦啦
java 进行抓包、分析包的必备jar包
jpcap dll 64位 jpcap jar jpcap dll 64位 jpcap jar
jpcap.jar+Jpcap.dll java版,能够抓取经过数据链路层的数据包,对抓取到的数据包进行一定程序的解析,可自己写IP数据包直接发送给数据链路层……
jpcap教程.pdf
可以用来抓取本机网络接口上网络数据包,可以分析IP/ICMP/TCP/UDP等协议包。 jpcap.dll必须放jre的bin目录
jpcap的开发API文档以及可使用的jar包,可供开发者使用
JPCAP实际上并非一个真正去实现对数据链路层的控制,而是一个中间件,JPCAP调用wincap/libpcap,而给 JAVA语言提供一个公共的接口,从而实现了平台无关性。在官方网站上声明,JPCAP支持FreeBSD 3.x, Linux RedHat ...
jpcap 发送、捕捉返回消息jpcap 发送、捕捉返回消息jpcap 发送、捕捉返回消息jpcap 发送、捕捉返回消息jpcap 发送、捕捉返回消息