peakame
驱动牛犊
驱动牛犊
  • 注册日期2002-06-28
  • 最后登录2013-08-07
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1759回复:10

大侠救我!网卡hook中能否自己臆造数据报发送到上层协议栈?

楼主#
更多 发布于:2003-06-18 15:03
我碰到的问题是这样的,我们的服务器(WIN2000)经常收到DOS、DDOS攻击,为了部分克服这个问题,我现在被要求写一个网卡NDIS hook程序,对收到的TCP SYN报文进行过滤和计数,同时还要求对一段时间后存在的半链接和全连接进行复位操作(方法是在hook中构造一个RST报文模拟客户机发向服务器)。现在有诸多困惑,关键之一就是在hook中能否通过自己构造TCP RST报文来复位上层的TCP(半)连接?
下面是问题的详细描述,望大侠们赐教,谢谢了!

我理解:正常情况下,当网卡收到数据报时,hook是钩出ReceivePacketHandler:
m_pReceivePacket = ProtocolCharacteristics->ReceivePacketHandler;
ProtocolCharacteristics->ReceivePacketHandler = My_ReceivePacket;
然后在My_ReceivePacket中:
My_ReceivePacket(IN NDIS_HANDLE ProtocolBindingContext,
       IN PNDIS_PACKET Packet)
{
do something to the Packet.
//将Packet发回系统协议栈
return m_pReceivePacket(ProtocolBindingContext, Packet);//*****
}
注意上面*****的地方是有两个参数,其中一个是数据报,另一个是context,它是ReceivePacketHandler对应函数带入的入口参数。现在我在钩子函数中构造一个MyPacket,还是通过m_pReceivePacket(ProtocolBindingContext, MyPacket)强行将我构造的报文发送到上层协议栈,这样做行吗?注意ProtocolBindingContext这个参数还是原来的那个!请问使用ProtocolBindingContext这个参数行吗?它和什么相关?这是问题1
在NDIS中,我记得看到过当上层协议收到一个Packet且处理后,会调用ReturnPacketHandler来通知下层驱动释放这个数据报,我在上面的做法中没有在将MyPacket发送到上层,且上层处理后返回的ReturnPacketHandler进行处理,也就是说协议栈可能会认为我自己生成的数据报是协议栈生成的,这样在ReturnPacketHandler会释放我自己生成的那个报文的资源吗?如果释放的话,可能会出问题,因为这个包的内存空间都是我自己创建的,并不是用的原来的协议栈的报文内存空间。这是问题2。
调试出现的现象:
我仅仅按照上面问题1中描述的方法进行调试(没有对ReturnPacketHandler进行任何处理),发现程序执行到m_pReceivePacket(ProtocolBindingContext, MyPacket)时,即我强行通过参数ProtocolBindingContext即MyPacket将我构造的数据报发到上层协议栈,出现蓝屏,现实信息为:
stop:0000001e : c0000005 f4b5074d 00000000 0000007b
KMODE_EXCEPTION_NOT_HANDLED
请问这是由谁引起的?该如何解决?

对于顶上描述的问题还有没有更好的办法?目前我对TCP SYN处理正确,就是不能复位已存在的TCP连接。期待各位的建议和指导!谢谢!
antspower
驱动中牛
驱动中牛
  • 注册日期2002-10-17
  • 最后登录2010-08-03
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值2点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2003-06-18 20:31
不太明白,关注,
但是感觉有问题。
我觉得你既然HOOK了protocolreceivepacket,
所以miniport发出NDISMINDICATEPACKETRECEIVES时
系统根据protocolreceivepackethandle的值调用你的my-packetrecive,而你的my-packetreceive中却又调用了一个
protocolreceivepacket这是不是有冲突。
也就是说对protocolreceivepacket这样的函数而言,只用系统才能调用!而你调用protocolreceivepacket是系统认为有冲突?(因为系统认为已经有一个了)


[编辑 -  6/18/03 by  antspower]

[编辑 -  6/18/03 by  antspower]
放弃瘟草,现吃李草
peakame
驱动牛犊
驱动牛犊
  • 注册日期2002-06-28
  • 最后登录2013-08-07
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2003-06-18 20:43
修改包的内容不会出错,且在hook中自己为一个数据报分配内存,且填好相应的字段都不会出错,当数据报构造完毕,通过m_pReceivePacket(ProtocolBindingContext, MyPacket)将数据包发送到上层协议栈的时候才出错,请问这样发送数据报行吗?是不是存在方法或想法上的问题?
peakame
驱动牛犊
驱动牛犊
  • 注册日期2002-06-28
  • 最后登录2013-08-07
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2003-06-18 21:01
我的理解:
当系统收到一个数据报时,miniport发出NDISMINDICATEPACKETRECEIVES(就按您所说),然后系统就调用protocolreceivepackethandle所对应的函数(一般为系统内部的ProtocolReceivePacket函数),本来如果不hook这个handler的话,就是在直接调通ProtocolReceivePacket函数;而现在我将protocolreceivepackethandle所指向的函数的地址给改了,改成了my_packetreceive函数,经过这个函数的处理,在此函数结尾处再调用原来的ProtocolReceivePacket函数;就相当于在原来连贯的protocolreceivepackethandle和ProtocolReceivePacket之间插入了我的处理函数,这种方法是可行的,而且我也成功试验了。而现在问题是我另写一个函数构造一个数据报,然后想调用ProtocolReceivePacket函数将数据报发送到上层时出了问题,而调用ProtocolReceivePacket时的参数就是上次正常数据报接收时用的上下文参数。
antspower
驱动中牛
驱动中牛
  • 注册日期2002-10-17
  • 最后登录2010-08-03
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值2点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2003-06-18 21:14
我的理解:
当系统收到一个数据报时,miniport发出NDISMINDICATEPACKETRECEIVES(就按您所说),然后系统就调用protocolreceivepackethandle所对应的函数(一般为系统内部的ProtocolReceivePacket函数),本来如果不hook这个handler的话,就是在直接调通ProtocolReceivePacket函数;而现在我将protocolreceivepackethandle所指向的函数的地址给改了,改成了my_packetreceive函数,经过这个函数的处理,在此函数结尾处再调用原来的ProtocolReceivePacket函数;就相当于在原来连贯的protocolreceivepackethandle和ProtocolReceivePacket之间插入了我的处理函数,这种方法是可行的,而且我也成功试验了。而现在问题是我另写一个函数构造一个数据报,然后想调用ProtocolReceivePacket函数将数据报发送到上层时出了问题,而调用ProtocolReceivePacket时的参数就是上次正常数据报接收时用的上下文参数。

数;就相当于在原来连贯的protocolreceivepackethandle和ProtocolReceivePacket之间插入了我的处理函数,这种方法是可行的,而且我也成功试验了。你杂这个函数中调用了类似m_pReceivePacket(ProtocolBindingContext, Packet);//
的函数吗?我的意思是他的两个参数是ProtocolBindingContext, Packet
我怀疑这个可能和系统有冲突,你不能把m_pReceivePacket(ProtocolBindingContext, MyPacket)的内容写到你的那个程序中去吗?那样处理过了吗?有没有问题呢?
继续关注,
放弃瘟草,现吃李草
peakame
驱动牛犊
驱动牛犊
  • 注册日期2002-06-28
  • 最后登录2013-08-07
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2003-06-18 21:28
My_ReceivePacket(IN NDIS_HANDLE ProtocolBindingContext,IN PNDIS_PACKET Packet)
{
do something to the Packet.
//将Packet发回系统协议栈
return m_pReceivePacket(ProtocolBindingContext, Packet);//您的第一个问号。
}
现在的问题时将自己构造出的数据报MyPacket仍旧通过m_pReceivePacket(ProtocolBindingContext, MyPacket)转发时出问题。注意第一个参数还是原来的那个参数,第二个参数是我构造出的数据报的指针。
我的mail:peakame@163.com。QQ:56984291
antspower
驱动中牛
驱动中牛
  • 注册日期2002-10-17
  • 最后登录2010-08-03
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值2点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2003-06-18 21:38
大哥能不能给点分啊
没功劳也有苦劳啊:)
My_ReceivePacket(IN NDIS_HANDLE ProtocolBindingContext,IN PNDIS_PACKET Packet)
{
do something to the Packet.
//将Packet发回系统协议栈
return m_pReceivePacket(ProtocolBindingContext, Packet);//我的意思是把这里换成本来protocolreceivepacket函数的代码会有问题吗?你有没有类似的例子,我从来没有用过HOOK
}
现在的问题时将自己构造出的数据报MyPacket仍旧通过m_pReceivePacket(ProtocolBindingContext, MyPacket)转发时出问题。注意第一个参数还是原来的那个参数,第二个参数是我构造出的数据报的指针。
放弃瘟草,现吃李草
antspower
驱动中牛
驱动中牛
  • 注册日期2002-10-17
  • 最后登录2010-08-03
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值2点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2003-06-18 21:54
My_ReceivePacket(IN NDIS_HANDLE ProtocolBindingContext,IN PNDIS_PACKET Packet)
{
do something to the Packet.
//将Packet发回系统协议栈
return m_pReceivePacket(ProtocolBindingContext, Packet);//您的第一个问号。
}
现在的问题时将自己构造出的数据报MyPacket仍旧通过m_pReceivePacket(ProtocolBindingContext, MyPacket)转发时出问题。注意第一个参数还是原来的那个参数,第二个参数是我构造出的数据报的指针。
我的mail:peakame@163.com。QQ:56984291


你的包是自己分配的啊,:――)
你在ptreceivecomplete中有释放资源的函数吗?
既然你自己新生成了包,那原来的哪个包你怎么“消化”的呢
放弃瘟草,现吃李草
yangxiaochong
驱动牛犊
驱动牛犊
  • 注册日期2003-05-23
  • 最后登录2004-07-08
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2003-06-18 22:59
TCP包中有序列号,序列号对不对?
peakame
驱动牛犊
驱动牛犊
  • 注册日期2002-06-28
  • 最后登录2013-08-07
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2003-06-18 23:16
刚刚又没碰到这个问题,不知怎么回事!
现在碰到这样的问题:
我调试用的服务器是ftp服务器,为了防止别人对我的ftp服务器进行攻击,我对针对ftp服务器而来的TCP SYN报文进行过滤,这正常完成,对那些连接时间较长(> 80s)的连接我在hook程序中自己创建一个针对这个连接的RST报文,然后通过m_pReceivePacket(ProtocolBindingContext, MyPacket)发送到上层应用,刚调试没发现问题,似乎包被发送出去了,但奇怪的是系统启动时发现ftp服务器不能运转,说是21端口被占用了,奇怪!
现在不调试程序,去掉这个网卡hook驱动,重新启动机子,发现21端口还被占用,到底被谁占用,为什么会这样?
antspower
驱动中牛
驱动中牛
  • 注册日期2002-10-17
  • 最后登录2010-08-03
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值2点
  • 好评度0点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2003-06-19 08:44
1。你修改如果要修改的话。首先要把TCP包文的数据部分去掉。还有你的reset报文是正确的吗?
你的checksum重计算了吗?!
2。你的想法(对BSOD)应该是正确的,你自己的包的善后工作,最好你自己完成
放弃瘟草,现吃李草
游客

返回顶部