zxcasd
驱动牛犊
驱动牛犊
  • 注册日期2001-06-14
  • 最后登录2007-08-09
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:3313回复:23

请问如何将修改后的包内容替换原来的包内容啊?

楼主#
更多 发布于:2004-04-28 21:33
我用ndishook的方法在发包时能够截获包的内容放入pBuffer,并修改了包中的ip地址,可是我如何将修改后的包内容替换原来的包内容呢?具体应该怎么做啊?

我有两个想法但不知道哪个可行,具体怎么做?

想法一:直接修改packet里的virtualAddress所指内存数据到pBuffer,具体怎么实现还不是很清楚。

想法二:构造一个mypacket,把mypacket附给原来的packet

最新喜欢:

xiaojian521xiaoji...
死了都要爱......
youngyt
驱动牛犊
驱动牛犊
  • 注册日期2003-11-23
  • 最后登录2006-12-29
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2004-05-07 14:19
youngyt:先谢谢你的指点,那个是没有错误了,但是我一装上驱动以后,系统就马上重起,重新启动后,系统就说检测到新硬件让我更新驱动程序!然后我就不能上网了(我们使用的认证上网的),说是找不到网卡,我费了好大的劲才把那个给卸掉!然后才可以上网,不知为何故。????以前调试的时候也碰到过类似的问题,不知道是怎么引起的,还望各位大侠帮帮我了,下面是部分代码:
pPacketContent为一个字符缓冲区,pPacketBuffer 为一个PNDIS_BUFFER缓冲区,然后再重新构造一个包,帮我看看想这样做错在什么地方?谢谢了
//分配一个PNDS_BUFFER缓冲区pPacketBuffer,指向pPacketContent缓冲区
NdisAllocateBuffer(&Status,
          &pPacketBuffer,
          pAdapt->SendPacketPoolHandle,
          pPacketContent,
          PacketBufferLen);
         if (Status == NDIS_STATUS_SUCCESS)
          NdisChainBufferAtBack(MyPacket,pPacketBuffer);

          NdisSend(&Status, pAdapt->BindingHandle, MyPacket);
      if (Status != NDIS_STATUS_PENDING)
     {
  NdisIMCopySendCompletePerPacketInfo (Packet, MyPacket);
  NdisFreeBuffer(pPacketBuffer);
               NdisFreeMemory(pPacketContent, 2000, 0);
  NdisFreePacket(MyPacket);
     }



NdisChainBufferAtBack(MyPacket,pPacketBuffer);这句之前你有没有做过这样的操作:
MyPacket->Private.Head = NULL;
MyPacket->Private.Tail = NULL;
你最好多贴一点上来。

BTW:你的问题与此贴主题差太多了,建议新开贴。 :D

[编辑 -  5/7/04 by  youngyt]
jackieky
驱动牛犊
驱动牛犊
  • 注册日期2004-02-10
  • 最后登录2004-08-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2004-05-07 09:16
youngyt:先谢谢你的指点,那个是没有错误了,但是我一装上驱动以后,系统就马上重起,重新启动后,系统就说检测到新硬件让我更新驱动程序!然后我就不能上网了(我们使用的认证上网的),说是找不到网卡,我费了好大的劲才把那个给卸掉!然后才可以上网,不知为何故。????以前调试的时候也碰到过类似的问题,不知道是怎么引起的,还望各位大侠帮帮我了,下面是部分代码:
pPacketContent为一个字符缓冲区,pPacketBuffer 为一个PNDIS_BUFFER缓冲区,然后再重新构造一个包,帮我看看想这样做错在什么地方?谢谢了
//分配一个PNDS_BUFFER缓冲区pPacketBuffer,指向pPacketContent缓冲区
NdisAllocateBuffer(&Status,
          &pPacketBuffer,
          pAdapt->SendPacketPoolHandle,
          pPacketContent,
          PacketBufferLen);
         if (Status == NDIS_STATUS_SUCCESS)
          NdisChainBufferAtBack(MyPacket,pPacketBuffer);

          NdisSend(&Status, pAdapt->BindingHandle, MyPacket);
      if (Status != NDIS_STATUS_PENDING)
     {
  NdisIMCopySendCompletePerPacketInfo (Packet, MyPacket);
  NdisFreeBuffer(pPacketBuffer);
               NdisFreeMemory(pPacketContent, 2000, 0);
  NdisFreePacket(MyPacket);
     }
fracker
驱动太牛
驱动太牛
  • 注册日期2001-06-28
  • 最后登录2021-03-30
  • 粉丝0
  • 关注0
  • 积分219分
  • 威望81点
  • 贡献值0点
  • 好评度23点
  • 原创分0分
  • 专家分1分
  • 社区居民
地板#
发布于:2004-05-01 21:28
SendComplete的问题已经跟你说了,自己慢慢体会吧,如果你还不能做对,说明你还没有看懂:)
zxcasd
驱动牛犊
驱动牛犊
  • 注册日期2001-06-14
  • 最后登录2007-08-09
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2004-05-01 19:11
[quote][quote][quote]
按第1种说的那样做不是有点怪么,把我自己的那个MyPacket发下去,系统传给我的那个PACKET也返回成功,那不是发了两次?

不怪,系统传给你的那个包你返回成功,只是协议层看到包是发出去了,但真正要发出去,还得调用下层的miniport才能发出,
多看看passthru的原理。 [/quote]

你的意思是系统传给我的那个包返回成功,但不返回给SEND_HANDLER是么?这样系统传给我的那个包就不会发出去了 [/quote]用MyPacket代替Packet调用SendHandler [/quote]

ok,我现在用你说的第一种方法实现了自己的包替换原包发送,感谢,给分:),现在就是在SendComplete中资源释放有点问题,也不知道算不算问题,我一用NdisFreeMemory(pPacketContent,bufLength,0);释放自己构造的包就蓝屏,把这句屏蔽掉就不会蓝屏了,工作也还正常,不知道这样做会不会有问题啊.
死了都要爱......
youngyt
驱动牛犊
驱动牛犊
  • 注册日期2003-11-23
  • 最后登录2006-12-29
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2004-04-30 14:54
我把包的内容全部都拷贝到了一个pPacketContent字符缓冲区,又开辟了一个pPacketBuffer PNDIS_BUFFER缓冲区,然后再重新构造一个包,帮我看看想这样做错在什么地方?谢谢了
//分配一个PNDS_BUFFER缓冲区pPacketBuffer,指向pPacketContent缓冲区
NdisAllocateBuffer(&Status,
&pPacketBuffer,
pAdapt->SendBufferPoolHandle,
pPacketContent,
PacketBufferLen);
if (Status == NDIS_STATUS_SUCCESS)
{
//MyPacket为一个PNDIS_PACKET,已分配
NdisChainBufferAtBack(MyPacket,pPacketBuffer);
NdisSend(&Status, pAdapt->BindingHandle, MyPacket);
..............

但是编译的时候有错误,错误如下:
c:\\xpassthru\\SEND.C(329) : error C2039: \'SendBufferPoolHandle\' : is not a member of \'_ADAPT\'
c:\\xpassthru\\xpassthru.h(54) : see declaration of \'_ADAPT\'
c:\\xpassthru\\SEND.C(330) : warning C4022: \'NdisAllocateBuffer\' : pointer mismatch for actual parameter 4
c:\\xpassthru\\SEND.C(330) : error C2198: \'NdisAllocateBuffer\' : too few actual parameters

我看了NdisAllocateBuffer函数的参数,好像也没有少什么,还有那个缓冲池的句柄是不是SendBufferPoolHandle?我是新手,功力浅薄,还请高手不吝赐教,谢谢了
 



SendBufferPoolHandle 不是PADAPT结构的成员
你在调用NdisAllocateBuffer时要使用SendPacketPoolHandle
zxcasd
驱动牛犊
驱动牛犊
  • 注册日期2001-06-14
  • 最后登录2007-08-09
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2004-04-29 12:56
[quote]我用ndishook的方法在发包时能够截获包的内容放入pBuffer,并修改了包中的ip地址,可是我如何将修改后的包内容替换原来的包内容呢?具体应该怎么做啊?

我有两个想法但不知道哪个可行,具体怎么做?

想法一:直接修改packet里的virtualAddress所指内存数据到pBuffer,具体怎么实现还不是很清楚。

想法二:构造一个mypacket,把mypacket附给原来的packet

不知道你用的是那种HOOK,如果是GJP的注册假协议,或修改NDIS.SYS的HOOK,那和PASSTHRU的道理是一样的。关于在PASSTHRU中重新组包的代码,我已经在进期贴过好几次了,找找吧。
可以肯定,方法1绝对不行。
方法2是对的,但不能把mypacket附给原来的packet ,要把PACKET直接返回给系统。以后就和PACKET没有关系。
BTW:1、资源的释放。2、重新计算校验和。这两点非常重要,而且有一些细节问题,我都说了。
 [/quote]

我是用GJP的注册假协议的方法

[编辑 -  4/29/04 by  zxcasd]
死了都要爱......
asmsys
驱动老牛
驱动老牛
  • 注册日期2002-03-29
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望17点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2004-04-29 12:39
我用ndishook的方法在发包时能够截获包的内容放入pBuffer,并修改了包中的ip地址,可是我如何将修改后的包内容替换原来的包内容呢?具体应该怎么做啊?

我有两个想法但不知道哪个可行,具体怎么做?

想法一:直接修改packet里的virtualAddress所指内存数据到pBuffer,具体怎么实现还不是很清楚。

想法二:构造一个mypacket,把mypacket附给原来的packet

不知道你用的是那种HOOK,如果是GJP的注册假协议,或修改NDIS.SYS的HOOK,那和PASSTHRU的道理是一样的。关于在PASSTHRU中重新组包的代码,我已经在进期贴过好几次了,找找吧。
可以肯定,方法1绝对不行。
方法2是对的,但不能把mypacket附给原来的packet ,要把PACKET直接返回给系统。以后就和PACKET没有关系。
BTW:1、资源的释放。2、重新计算校验和。这两点非常重要,而且有一些细节问题,我都说了。
fracker
驱动太牛
驱动太牛
  • 注册日期2001-06-28
  • 最后登录2021-03-30
  • 粉丝0
  • 关注0
  • 积分219分
  • 威望81点
  • 贡献值0点
  • 好评度23点
  • 原创分0分
  • 专家分1分
  • 社区居民
8楼#
发布于:2004-04-29 11:34
[quote][quote]
按第1种说的那样做不是有点怪么,把我自己的那个MyPacket发下去,系统传给我的那个PACKET也返回成功,那不是发了两次?

不怪,系统传给你的那个包你返回成功,只是协议层看到包是发出去了,但真正要发出去,还得调用下层的miniport才能发出,
多看看passthru的原理。 [/quote]

你的意思是系统传给我的那个包返回成功,但不返回给SEND_HANDLER是么?这样系统传给我的那个包就不会发出去了 [/quote]用MyPacket代替Packet调用SendHandler
zxcasd
驱动牛犊
驱动牛犊
  • 注册日期2001-06-14
  • 最后登录2007-08-09
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2004-04-29 11:27
[quote]
按第1种说的那样做不是有点怪么,把我自己的那个MyPacket发下去,系统传给我的那个PACKET也返回成功,那不是发了两次?

不怪,系统传给你的那个包你返回成功,只是协议层看到包是发出去了,但真正要发出去,还得调用下层的miniport才能发出,
多看看passthru的原理。 [/quote]

你的意思是系统传给我的那个包返回成功,但不返回给SEND_HANDLER是么?这样系统传给我的那个包就不会发出去了
死了都要爱......
fracker
驱动太牛
驱动太牛
  • 注册日期2001-06-28
  • 最后登录2021-03-30
  • 粉丝0
  • 关注0
  • 积分219分
  • 威望81点
  • 贡献值0点
  • 好评度23点
  • 原创分0分
  • 专家分1分
  • 社区居民
10楼#
发布于:2004-04-29 11:16

按第1种说的那样做不是有点怪么,把我自己的那个MyPacket发下去,系统传给我的那个PACKET也返回成功,那不是发了两次?

不怪,系统传给你的那个包你返回成功,只是协议层看到包是发出去了,但真正要发出去,还得调用下层的miniport才能发出,
多看看passthru的原理。
zxcasd
驱动牛犊
驱动牛犊
  • 注册日期2001-06-14
  • 最后登录2007-08-09
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2004-04-29 11:13
[quote][quote]这种方法只适用于包的长度没有变化的情况(想不出来你修改IP会引起什么长度变化,除非你在做FTP之类的东西的NAT)。

如果是使用PASSTHRU,就简单了,自己重新弄个PACKET,把你的缓冲区插进去就可以了。


如果长度变化呢?因为还要修改tcp数据的内容。在ndishook中怎么做呢? [/quote]
这个就很复杂了,ndishook做就很麻烦了,
1。你重新分配一个MyPacket,串上你的数据,然后把MyPacket发下去,系统传给你的那个PACKET直接返回成功,当然你也可以等MyPacket结束以后,再通知上层,MyPacket的释放要自己做。
2。把你的数据拷贝回原来那个PACKET,长出来的部分重新分配一个NDIS_BUFFER,挂在这个PACKET后面,然后将这个PACKET发下去,如果发送非PENDING,那么将这个NDIS_BUFFER从PACKET里面删除,然后返回给上层协议,如果返回PENDING,那么你要拦截上层协议的SendComplete,当这个被你处理过的包回来的时候,你也要先删除你加的那个NDIS_BUFFER,然后再调用原来的SendComplete。
3。如果产生分片,要自行处理,论坛里面有很多人讨论这个,就不多说了。 [/quote]

按第1种说的那样做不是有点怪么,把我自己的那个MyPacket发下去,系统传给我的那个PACKET也返回成功,那不是发了两次?
死了都要爱......
jackieky
驱动牛犊
驱动牛犊
  • 注册日期2004-02-10
  • 最后登录2004-08-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2004-04-29 11:07
我把包的内容全部都拷贝到了一个pPacketContent字符缓冲区,又开辟了一个pPacketBuffer PNDIS_BUFFER缓冲区,然后再重新构造一个包,帮我看看想这样做错在什么地方?谢谢了
//分配一个PNDS_BUFFER缓冲区pPacketBuffer,指向pPacketContent缓冲区
NdisAllocateBuffer(&Status,
&pPacketBuffer,
pAdapt->SendBufferPoolHandle,
pPacketContent,
PacketBufferLen);
if (Status == NDIS_STATUS_SUCCESS)
{
//MyPacket为一个PNDIS_PACKET,已分配
NdisChainBufferAtBack(MyPacket,pPacketBuffer);
NdisSend(&Status, pAdapt->BindingHandle, MyPacket);
..............

但是编译的时候有错误,错误如下:
c:\\xpassthru\\SEND.C(329) : error C2039: \'SendBufferPoolHandle\' : is not a member of \'_ADAPT\'
c:\\xpassthru\\xpassthru.h(54) : see declaration of \'_ADAPT\'
c:\\xpassthru\\SEND.C(330) : warning C4022: \'NdisAllocateBuffer\' : pointer mismatch for actual parameter 4
c:\\xpassthru\\SEND.C(330) : error C2198: \'NdisAllocateBuffer\' : too few actual parameters

我看了NdisAllocateBuffer函数的参数,好像也没有少什么,还有那个缓冲池的句柄是不是SendBufferPoolHandle?我是新手,功力浅薄,还请高手不吝赐教,谢谢了
fracker
驱动太牛
驱动太牛
  • 注册日期2001-06-28
  • 最后登录2021-03-30
  • 粉丝0
  • 关注0
  • 积分219分
  • 威望81点
  • 贡献值0点
  • 好评度23点
  • 原创分0分
  • 专家分1分
  • 社区居民
13楼#
发布于:2004-04-29 11:04
[quote]这种方法只适用于包的长度没有变化的情况(想不出来你修改IP会引起什么长度变化,除非你在做FTP之类的东西的NAT)。

如果是使用PASSTHRU,就简单了,自己重新弄个PACKET,把你的缓冲区插进去就可以了。


如果长度变化呢?因为还要修改tcp数据的内容。在ndishook中怎么做呢? [/quote]
这个就很复杂了,ndishook做就很麻烦了,
1。你重新分配一个MyPacket,串上你的数据,然后把MyPacket发下去,系统传给你的那个PACKET直接返回成功,当然你也可以等MyPacket结束以后,再通知上层,MyPacket的释放要自己做。
2。把你的数据拷贝回原来那个PACKET,长出来的部分重新分配一个NDIS_BUFFER,挂在这个PACKET后面,然后将这个PACKET发下去,如果发送非PENDING,那么将这个NDIS_BUFFER从PACKET里面删除,然后返回给上层协议,如果返回PENDING,那么你要拦截上层协议的SendComplete,当这个被你处理过的包回来的时候,你也要先删除你加的那个NDIS_BUFFER,然后再调用原来的SendComplete。
3。如果产生分片,要自行处理,论坛里面有很多人讨论这个,就不多说了。
zxcasd
驱动牛犊
驱动牛犊
  • 注册日期2001-06-14
  • 最后登录2007-08-09
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2004-04-29 11:00
弄清楚PACKET的构造你就不会这么苦恼了,
一般做PACKET的处理的时候,都是把PACKET的内容复制到一块连续的缓冲区,然后去取IP或者做别的操作,但PACKET里面的BUFFER并不是连续的(似乎总是一块MAC,一块IP。。。),你分配的缓冲区总是跟PACKET的所有BUFFER的长度总和相等。

当你把IP修改以后(当然记得要重新计算CHECKSUM),你可以把你的内存重新复制回那个PACKET,也就是重新取出PACKET里面的BUFFER,然后把你的缓冲区里面的数据,一块一块地复制过去,这个过程就是你前面把PACKET里面的数据复制出来的逆过程。

[编辑 -  4/29/04 by  fracker]


我想是这样了,我去试试看先:)
死了都要爱......
zxcasd
驱动牛犊
驱动牛犊
  • 注册日期2001-06-14
  • 最后登录2007-08-09
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
15楼#
发布于:2004-04-29 10:54
这种方法只适用于包的长度没有变化的情况(想不出来你修改IP会引起什么长度变化,除非你在做FTP之类的东西的NAT)。

如果是使用PASSTHRU,就简单了,自己重新弄个PACKET,把你的缓冲区插进去就可以了。


如果长度变化呢?因为还要修改tcp数据的内容。在ndishook中怎么做呢?
死了都要爱......
fracker
驱动太牛
驱动太牛
  • 注册日期2001-06-28
  • 最后登录2021-03-30
  • 粉丝0
  • 关注0
  • 积分219分
  • 威望81点
  • 贡献值0点
  • 好评度23点
  • 原创分0分
  • 专家分1分
  • 社区居民
16楼#
发布于:2004-04-29 10:50
这种方法只适用于包的长度没有变化的情况(想不出来你修改IP会引起什么长度变化,除非你在做FTP之类的东西的NAT)。

如果是使用PASSTHRU,就简单了,自己重新弄个PACKET,把你的缓冲区插进去就可以了。
yangyb_628
驱动牛犊
驱动牛犊
  • 注册日期2004-03-08
  • 最后登录2005-04-25
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
17楼#
发布于:2004-04-29 10:49
不是copy到原包中去!
是你构造的mypacket还要复制packet中必要的flag,oob,MEDIA等信息
NdisSend(&Status, pAdapt>BindingHandle, MyPacket);
发送的是MyPacket,而不是packet.

fracker
驱动太牛
驱动太牛
  • 注册日期2001-06-28
  • 最后登录2021-03-30
  • 粉丝0
  • 关注0
  • 积分219分
  • 威望81点
  • 贡献值0点
  • 好评度23点
  • 原创分0分
  • 专家分1分
  • 社区居民
18楼#
发布于:2004-04-29 10:49
弄清楚PACKET的构造你就不会这么苦恼了,
一般做PACKET的处理的时候,都是把PACKET的内容复制到一块连续的缓冲区,然后去取IP或者做别的操作,但PACKET里面的BUFFER并不是连续的(似乎总是一块MAC,一块IP。。。),你分配的缓冲区总是跟PACKET的所有BUFFER的长度总和相等。

当你把IP修改以后(当然记得要重新计算CHECKSUM),你可以把你的内存重新复制回那个PACKET,也就是重新取出PACKET里面的BUFFER,然后把你的缓冲区里面的数据,一块一块地复制过去,这个过程就是你前面把PACKET里面的数据复制出来的逆过程。

[编辑 -  4/29/04 by  fracker]
zxcasd
驱动牛犊
驱动牛犊
  • 注册日期2001-06-14
  • 最后登录2007-08-09
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
19楼#
发布于:2004-04-29 10:44

Packet->Private.Head = myPacket->Private.Head;
Packet->Private.Tail = myPacket->Private.Tail;
两行屏蔽掉是不会蓝屏了,可是这样我构造的包myPacket内容就不会指给原来的Packet了,那不就等于没起作用。如何把myPacket包内容指给原Packet而且又不会蓝屏啊?
死了都要爱......
上一页
游客

返回顶部