python 网络数据包处理和嗅探工具Scapy 学习笔记(一)
发布日期:2021-10-07 04:43:08 浏览次数:16 分类:技术文章

本文共 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
      得到如下结果那么恭喜安装成功
      scapy环境测试

关于rdpcap方法中的内存泄露问题

博主在使用scapy库的时候主要用这个库来对已经捕获好的pcap文件进行分析,提取特征。所以rdpcap方法是接触最早最多的方法了。但是在使用的时候电脑的内存总是无缘无故炸掉,经过一番搜索发现了rdpcap方法中存在的内存泄露问题。(该问题详细描述以及解决方法转自)

rdpcap方法的实现代码如下

def rdpcap(filename, count=-1):        """Read a pcap file and return a packet list        count: read only 
packets""" 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 only 
packets""" pcap = PcapReader(filename) data = pcap.read_all(count=count) pcap.close() return data

转载地址:https://blog.csdn.net/meanong/article/details/53942116 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:scapy学习笔记(二)
下一篇:java 版 selenium 自动化操作 chrome

发表评论

最新留言

留言是一种美德,欢迎回访!
[***.207.175.100]2024年03月31日 21时33分15秒