本文共 2680 字,大约阅读时间需要 8 分钟。
Scapy 学习笔记(一)
本文主要是关于scapy的安装和scapy存在的内存泄露导致内存爆掉的解决方案,关于如何操纵数据包请看另一篇博客:
scapy在windows中安装教程
关于scapy在Linux中安装教程网上很多,但是在windows下的安装就显得有点少了。查了很多资料终于安装完毕,现在将scapy的在windows下的安装教程备份一下。
- 1.scapy在windows下安装时,在官网上只找到了支持python 2.x的,关于python 3.x系列的合适支持就不晓得了。首先下载scapy安装包。我使用的安装包链接为:
- 2.将压缩文件解压,然后安装一级目录中对应的环境。
- 3.将scapy-latest解压之后,打开命令行,切换到对应的文件中setup.py所在路径。
- 4.运行命令python setup.py install即可完成安装。
- 5.测试方法:
- 打开命令行,输入Python进入Python解释器
- 输入import scapy.all as scapy 得到如下结果那么恭喜安装成功
关于rdpcap方法中的内存泄露问题
博主在使用scapy库的时候主要用这个库来对已经捕获好的pcap文件进行分析,提取特征。所以rdpcap方法是接触最早最多的方法了。但是在使用的时候电脑的内存总是无缘无故炸掉,经过一番搜索发现了rdpcap方法中存在的内存泄露问题。(该问题详细描述以及解决方法转自)
rdpcap方法的实现代码如下def rdpcap(filename, count=-1): """Read a pcap file and return a packet list count: read onlypackets""" return PcapReader(filename).read_all(count=count)
那我们继续找PcapReader这个类。同样在这个文件中。继承自同在这个文件中定义的RawPcapReader类。但我此时更关心的是这个read_all是如何定义的……
def read_all(self,count=-1): res = RawPcapReader.read_all(self, count) import plist return plist.PacketList(res,name=os.path.basename(self.filename))
很显然,读取文件内容这部分的主体功能还是来自于他的父类RawPcapReader中的read_all函数,而父类函数定义如下:
def read_all(self,count=-1): """return a list of all packets in the pcap file """ res=[] while count != 0: count -= 1 p = self.read_packet() if p is None: break res.append(p) return res
rdpcap其实就是一行代码——return. 在return时,实例化了PcapReader类,并调用了其read_all函数。不难想到——既然rdpcap的作用是读取一个pcap文件的内容,那一定会有open操作。我们必然要问一句:既然open了,那么你是在哪close的呢?
刚才说了,PcapReader类是继承自RawPcapReader类。我们直接看下RawPcapReader类中的两个关键函数就好了——初始化函数和关闭函数:def __init__(self, filename): self.filename = filename try: self.f = gzip.open(filename,"rb") magic = self.f.read(4) except IOError: self.f = open(filename,"rb") magic = self.f.read(4) if magic == "\xa1\xb2\xc3\xd4": #big endian self.endian = ">" elif magic == "\xd4\xc3\xb2\xa1": #little endian self.endian = "<" else: raise Scapy_Exception("Not a pcap capture file (bad magic)") hdr = self.f.read(20) if len(hdr)<20: raise Scapy_Exception("Invalid pcap file (too short)") vermaj,vermin,tz,sig,snaplen,linktype = struct.unpack(self.endian+"HHIIII",hdr) self.linktype = linktypedef close(self): return self.f.close()
可见,一旦实例化这个类,初始化函数就会自动的将用户指定的pcap文件打开,但用完之后,必须用户手动close掉才可以。而rdpcap这个函数只实例化了PcapReader这个类,却没有close掉,也没有将实例化的对象传递出来,用户也无法close掉……结果就是——谁都没有关闭这个对象。导致内存泄漏
解决方法
修改rdpcap函数,修改方法如下:
def rdpcap(filename, count=-1): """Read a pcap file and return a packet listcount: read onlypackets""" pcap = PcapReader(filename) data = pcap.read_all(count=count) pcap.close() return data
转载地址:https://blog.csdn.net/meanong/article/details/53942116 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!