拦截原始套接字输入输出的方法和系统与流程

文档序号:11960027阅读:844来源:国知局
拦截原始套接字输入输出的方法和系统与流程

本发明涉及数据拦截技术领域,特别是涉及一种拦截原始套接字输入输出的方法和系统。



背景技术:

原始套接字具有广泛的用途,特别是用于自定义协议(标准协议TCP、UDP和ICMP等外)的数据收发。在Linux下拦截套接字IO的一般方法是拦截对应的套接字系统调用,对于发送为sendmsg和sendto,对于接收为recvmsg和recvfrom。这种方法虽然也能拦截原始套接字IO,但要先判断套接字的类型,如果为SOCK_RAW(原始套接字类型),那么进行拦截处理,这样一来由于每次IO都要判断套接字类型,性能就比较低了。



技术实现要素:

本发明所要解决的技术问题是提供一种拦截原始套接字输入输出的方法,直接拦截所有进程的原始套接字输入输出。

本发明所要解决的另一技术问题是提供一种拦截原始套接字输入输出的系统,直接拦截所有进程的原始套接字输入输出。

为了解决上述的技术问题,本发明的技术方案如下:

一种拦截原始套接字输入输出的方法,用于Linux内核,包括:查找所述Linux内核中内置的原始套接字接口;清除CPU的控制寄存器的写保护位;将所述Linux内核中内置的原始套接字接口中的第一接收消息函数和第一发送消息函数保存到所述Linux内核中新分配的原始套接字接口中;将第二接收消息函数和第二发送消息函数分别替换所述Linux内核中内置的原始套接字接口中的第一接收消息函数和第一发送消息函数;还原所述CPU的控制寄存器的写保护位。

进一步,所述查找Linux内核中内置的原始套接字接口的过程包括:初始化套接字接口,所述套接字接口为原始套接字类型;注册所述套接字接口,所述套接字接口位于以SOCK_RAW为索引的双向循环链表的链表头的后面;获取所述套接字接口的后一个套接字接口,该后一个套接字接口为所述Linux内核中内置的原始套接字接口;注销所述套接字接口。

进一步,在所述将所述Linux内核中内置的原始套接字接口中的第一接收消息函数和第一发送消息函数保存到所述Linux内核中新分配的原始套接字接口中的过程之前,还包括:在所述Linux内核中新分配的原始套接字接口中分配子单元。

进一步,所述将所述Linux内核中内置的原始套接字接口中的第一接收消息函数和第一发送消息函数保存到所述Linux内核中新分配的原始套接字接口中的过程包括:将所述第一接收消息函数和所述第一发送消息函数保存到所述子单元中。

进一步,在所述还原所述CPU的控制寄存器的写保护位的过程之后,还包括:清除所述CPU的控制寄存器的写保护位;将所述子单元中的所述第一接收消息函数和所述第一发送消息函数分别替换所述Linux内核中内置的原始套接字接口中的所述第二接收消息函数和所述第二发送消息函数;还原所述CPU的控制寄存器的写保护位;释放所述子单元。

以及,一种拦截原始套接字输入输出的系统,用于Linux内核,包括:查找模块,用于查找所述Linux内核中内置的原始套接字接口;写保护位清除模块,用于清除CPU的控制寄存器的写保护位;存储模块,用于将所述Linux内核中内置的原始套接字接口中的第一接收消息函数和第一发送消息函数保存到所述Linux内核中新分配的原始套接字接口中;第一替换模块,用于将第二接收消息函数和第二发送消息函数分别替换所述Linux内核中内置的原始套接字接口中的第一接收消息函数和第一发送消息函数;写保护位还原模块,用于还原所述CPU的控制寄存器的写保护位。

进一步,所述查找模块包括:初始化子模块,用于初始化套接字接口,所述套接字接口为原始套接字类型;注册子模块,用于注册所述套接字接口,所述套接字接口位于以SOCK_RAW为索引的双向循环链表的链表头的后面;获取子模块,用于获取所述套接字接口的后一个套接字接口,该后一个套接字接口为所述Linux内核中内置的原始套接字接口;注销子模块,用于注销所述套接字接口。

进一步,还包括:分配模块,在所述将所述Linux内核中内置的原始套接字接口中的第一接收消息函数和第一发送消息函数保存到所述Linux内核中新分配的原始套接字接口中的过程之前,所述分配模块用于在所述Linux内核中新分配的原始套接字接口中分配子单元。

进一步:所述存储模块用于将所述第一接收消息函数和所述第一发送消息函数保存到所述子单元中。

进一步,还包括:第二替换模块,在清除所述CPU的控制寄存器的写保护位的过程之后,所述第二替换模块用于将所述子单元中的所述第一接收消息函数和所述第一发送消息函数分别替换所述Linux内核中内置的原始套接字接口中的所述第二接收消息函数和所述第二发送消息函数;释放模块,在还原所述CPU的控制寄存器的写保护位的过程之后,所述释放模块用于释放所述子单元。

与现有技术相比,本发明包括以下优点:

1、本发明实施例的拦截原始套接字输入输出的方法,运行在内核态,直接拦截所有进程的原始套接字输入输出(IO),提高了拦截性能。

2、本发明实施例的拦截原始套接字输入输出的系统,运行在内核态,直接拦截所有进程的原始套接字输入输出(IO),提高了拦截性能。

附图说明

图1是本发明实施例的拦截原始套接字输入输出的方法的流程图;

图2是本发明实施例的查找Linux内核中内置的原始套接字接口的过程的流程图;

图3是本发明实施例的注册套接字接口之前的双向循环链表的示意图;

图4是本发明实施例的注册套接字接口之后的双向循环链表的示意图;

图5是本发明实施例的拦截原始套接字输入输出的方法在还原CPU的控制寄存器的写保护位的过程之后的流程图;

图6是本发明实施例的拦截原始套接字输入输出的系统的结构示意图;

图7是本发明又一个实施例的拦截原始套接字输入输出的系统的结构示意图。

具体实施方式

为使本发明的上述目的、特征和优点能够更加明显易懂,下面结合附图和具体实施方式对本发明作进一步详细的说明。

本发明实施例公开了一种拦截原始套接字输入输出的方法。该方法用于Linux内核。由于该方法实现在Linux内核中,为了防止其它内核模块可能也注册了原始套接字接口,因此需要在操作系统启动时优先加载该Linux内核模块。如图1所示,为本发明实施例的拦截原始套接字输入输出的方法的流程图。该方法具体包括如下的步骤:

步骤S101:查找Linux内核中内置的原始套接字接口。

在Linux内核中,struct proto_ops变量的结构提供了协议无关的套接字层到协议相关的传输层的转接,例如,IPv4协议族中内置的inet_sockraw_ops。因此,该Linux内核中内置的原始套接字接口可以为inet_sockraw_ops。

步骤S102:清除CPU的控制寄存器的写保护位。

清除CPU的控制寄存器的写保护位后,可写入数据。

步骤S103:将Linux内核中内置的原始套接字接口中的第一接收消息函数和第一发送消息函数保存到Linux内核中新分配的原始套接字接口中。

其中,在Linux中,接收消息函数一般用recvmsg表示,发送消息函数一般用sendmsg表示。应当理解的是,本发明中的“第一”、“第二”仅用于区分,没有实际含义。优选的,该Linux内核中内置的原始套接字接口中的第一接收消息函数和第一发送消息函数可置于Linux内核中内置的原始套接字接口分配的存储单元中。

步骤S104:将第二接收消息函数和第二发送消息函数分别替换Linux内核中内置的原始套接字接口中的第一接收消息函数和第一发送消息函数。

优选的,替换Linux内核中内置的原始套接字接口中的第一接收消息函数和第一发送消息函数后的第二接收消息函数和第二发送消息函数可置于Linux内核中内置的原始套接字接口分配的存储单元中。

步骤S105:还原CPU的控制寄存器的写保护位。

还原CPU的控制寄存器的写保护位后,不可写入数据。

通过上述的步骤S102~步骤S105实现挂钩IO的过程。

本发明实施例的拦截原始套接字输入输出的方法,运行在内核态,直接拦截所有进程的原始套接字输入输出(IO),提高了拦截性能。本发明实施例的方法可支持IPv4和IPv6。

如图2所示,为本发明实施例的查找Linux内核中内置的原始套接字接口的过程的流程图。由于内置的原始套接字接口(inet_sockraw_ops)为Linux内核未导出的内部符号,因此需要通过特别的方法找到它,该特别的方法基于如下的原理:

(1)所有的原始套接字类型的接口均存放在以原始套接字类型(SOCK_RAW)为索引的双向循环链表中,而Linux内核中内置的原始套接字接口inet_sockraw_ops就在该链表的末尾。

(2)Linux内核提供了调用接口API:注册套接字接口(inet_register_protosw)。对于原始套接字类型的接口,该API将输入的套接字接口插入到该链表头的后面。

因此,基于上述的原理,查找Linux内核中内置的原始套接字接口的具体过程如下:

步骤S201:初始化套接字接口。

其中,该套接字接口为原始套接字类型(SOCK_RAW)。

步骤S202:注册套接字接口。

具体的,可通过调用inet_register_protosw函数注册该套接字接口。如图3和4所示,分别为本发明实施例的注册套接字接口之前的双向循环链表的示意图及注册套接字接口之后的双向循环链表的示意图。从图中可以看出,注册套接字接口之后,该套接字接口位于以SOCK_RAW为索引的双向循环链表的链表头的后面。

步骤S203:获取该套接字接口的后一个套接字接口。

其中,该后一个套接字接口为Linux内核中内置的原始套接字接口,如图4所示。

步骤S204:注销套接字接口。

具体的,可通过调用inet_unregister_protosw函数注销该套接字接口。

通过上述的过程,可查找到Linux内核中内置的原始套接字接口。

优选的,在步骤S103之前,还包括在Linux内核中新分配的原始套接字接口中分配子单元的步骤。

该Linux内核中新分配的原始套接字接口中的子单元具有存储的功能。具体的,该Linux内核中新分配的原始套接字接口中的子单元可以是协议操作对象old_ops。

在分配了该子单元后,本发明的方法可将所述第一接收消息函数和第一发送消息函数保存到该子单元中。

在本发明一优选的实施例中,在步骤S105之后,还包括卸钩IO的过程。如图5所示,为本发明实施例的拦截原始套接字输入输出的方法在还原CPU的控制寄存器的写保护位的过程之后的流程图。该过程具体如下:

步骤S501:清除CPU的控制寄存器的写保护位。

清除CPU的控制寄存器的写保护位后,可写入数据。

步骤S502:将子单元中的第一接收消息函数和第一发送消息函数分别替换Linux内核中内置的原始套接字接口中的第二接收消息函数和第二发送消息函数。

优选的,替换Linux内核中内置的原始套接字接口中的第二接收消息函数和第二发送消息函数后的第一接收消息函数和第一发送消息函数可置于Linux内核内置的原始套接字接口分配的存储单元中。

例如,该子单元是协议操作对象old_ops,则将协议操作对象old_ops中保存的第一接收消息函数和第一发送消息函数分别替换Linux内核中内置的原始套接字接口分配的存储单元中的第二接收消息函数和第二发送消息函数。

步骤S503:还原CPU的控制寄存器的写保护位。

还原CPU的控制寄存器的写保护位后,不可写入数据。

步骤S504:释放子单元。

例如,该子单元是协议操作对象old_ops,则释放该协议操作对象old_ops。

释放子单元后,不再占用Linux内核中的内存空间。

通过上述的过程,使得Linux内核中内置的原始套接字接口中的接收消息函数和发送消息函数恢复为原来的接收消息函数和发送消息函数,保持了原程序的健壮性。

综上所述,本发明实施例的方法由于可直接拦截所有进程的原始套接字输入输出(IO),因此可用于防火墙或主机防护系统中,丢弃接收和发送的攻击或病毒数据包。

本发明实施例还公开了一种拦截原始套接字输入输出的系统。该系统用于Linux内核。如图6所示,为本发明实施例的拦截原始套接字输入输出的系统的结构示意图。该系统具体包括如下的结构。

查找模块601:用于查找Linux内核中内置的原始套接字接口。

在Linux内核中,struct proto_ops变量的结构提供了协议无关的套接字层到协议相关的传输层的转接,例如,IPv4协议族中内置的inet_sockraw_ops。因此,该Linux内核中内置的原始套接字接口可以为inet_sockraw_ops。

写保护位清除模块602:用于清除CPU的控制寄存器的写保护位。

清除CPU的控制寄存器的写保护位后,可写入数据。

存储模块603:用于将Linux内核中内置的原始套接字接口中的第一接收消息函数和第一发送消息函数保存到Linux内核中新分配的原始套接字接口中。

其中,在Linux中,接收消息函数一般用recvmsg表示,发送消息函数一般用sendmsg表示。优选的,该Linux内核中内置的原始套接字接口中的第一接收消息函数和第一发送消息函数可置于Linux内核中内置的原始套接字接口分配的存储单元中。

第一替换模块604:用于将第二接收消息函数和第二发送消息函数分别替换Linux内核中内置的原始套接字接口中的第一接收消息函数和第一发送消息函数。

优选的,替换Linux内核中内置的原始套接字接口中的第一接收消息函数和第一发送消息函数后的第二接收消息函数和第二发送消息函数可置于Linux内核分配中内置的原始套接字接口的存储单元中。

写保护位还原模块605:用于还原CPU的控制寄存器的写保护位。

还原CPU的控制寄存器的写保护位后,不可写入数据。

通过写保护位清除模块602、存储模块603、第一替换模块604、写保护位还原模块605可实现挂钩IO的过程。

本发明实施例的拦截原始套接字输入输出的系统,可直接拦截所有进程的原始套接字输入输出(IO),提高了拦截性能。本发明实施例的系统可支持IPv4和IPv6。

如图7所示,为本发明又一个实施例的拦截原始套接字输入输出的系统的结构示意图。本发明又一个实施例中,该系统的查找模块具体包括如下的结构:

初始化子模块6011:用于初始化套接字接口。

其中,该套接字接口为原始套接字类型(SOCK_RAW)。

注册子模块6012:用于注册套接字接口。

具体的,注册子模块6012可通过调用inet_register_protosw函数注册该套接字接口。

获取子模块6013:用于获取该套接字接口的后一个套接字接口。

其中,该后一个套接字接口为Linux内核中内置的原始套接字接口。

注销子模块6014:用于注销套接字接口。

具体的,注销子模块6014可通过调用inet_unregister_protosw函数注销该套接字接口。

通过上述的模块设计,使得该系统可查找到Linux内核中内置的原始套接字接口。

优选的,该系统还包括:分配模块606。

在存储模块603将Linux内核中内置的原始套接字接口中的第一接收消息函数和第一发送消息函数保存到Linux内核中新分配的原始套接字接口中的过程之前,分配模块606用于在Linux内核中新分配的原始套接字接口中分配子单元。

该Linux内核中新分配的原始套接字接口中的子单元具有存储的功能。具体的,该Linux内核中新分配的原始套接字接口中的子单元可以是协议操作对象old_ops。

当分配模块606分配了该子单元后,存储模块603可用于将第一接收消息函数和第一发送消息函数保存到该子单元中。

优选的,该系统还包括:第二替换模块607和释放模块608,用于实现卸钩IO的过程。

卸钩IO的过程中,在写保护位清除模块602清除CPU的控制寄存器的写保护位的过程之后,第二替换模块607,用于将子单元中的第一接收消息函数和第一发送消息函数分别替换Linux内核中内置的原始套接字接口中的第二接收消息函数和第二发送消息函数。优选的,替换Linux内核中内置的原始套接字接口中的第二接收消息函数和第二发送消息函数后的第一接收消息函数和第一发送消息函数可置于Linux内核内置的原始套接字接口分配的存储单元中。

例如,该子单元是协议操作对象old_ops,则第二替换模块607将协议操作对象old_ops中保存的第一接收消息函数和第一发送消息函数分别替换Linux内核中内置的原始套接字接口分配的存储单元中的第二接收消息函数和第二发送消息函数。

在写保护位还原模块605还原CPU的控制寄存器的写保护位的过程之后,释放模块608用于释放该子单元。

例如,该子单元是协议操作对象old_ops,则释放模块608释放该协议操作对象old_ops。

释放子单元后,不再占用Linux内核中的内存空间。

通过设置上述的模块,该系统可使Linux内核中内置的原始套接字接口中的接收消息函数和发送消息函数恢复为原来的接收消息函数和发送消息函数,保持了原程序的健壮性。

以上对本发明所提供的技术方案,进行了详细介绍,本文中应用了具体个例对本发明的原理及实施方式进行了阐述,以上实施例的说明只是用于帮助理解本发明的方法及其核心思想;同时,对于本领域的一般技术人员,依据本发明的思想,在具体实施方式及应用范围上均会有改变之处,综上所述,本说明书内容不应理解为对本发明的限制。

当前第1页1 2 3 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1