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

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

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

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

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

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

最新喜欢:

xiaojian521xiaoji...
死了都要爱......
yangyb_628
驱动牛犊
驱动牛犊
  • 注册日期2004-03-08
  • 最后登录2005-04-25
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2004-04-29 09:30
我只做过NDIS驱动。在PASSTHRU中,个人认为如果要修改包内容应该先把原PACKET的内容COPY到一块连续的缓存区中。就可以对包进行处理。然后
1,定义一NEWBUFFER指向那块连续的缓存区。
2,定义一MYPACKET联接NEWBUFFER.
3,COPY原包必要的OOB数据及媒介信息。
就可以指示发包了。当然还要做必要的资源释放工作。
我不知道你的第2种方法是不是这样的。
像你提到的第一种修改包的方法我觉得可能存在资源释放出错的问题。因为PACKET一般是由好几个BUFFER组成,每个BUFFER指向不同的
virtualAddress表示不同的内容。你得确保你所替换的BUFFER是原包中相应的包内容。而且你还的很小心的做好资源释放工作。
zxcasd
驱动牛犊
驱动牛犊
  • 注册日期2001-06-14
  • 最后登录2007-08-09
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2004-04-29 09:48
我只做过NDIS驱动。在PASSTHRU中,个人认为如果要修改包内容应该先把原PACKET的内容COPY到一块连续的缓存区中。就可以对包进行处理。然后
1,定义一NEWBUFFER指向那块连续的缓存区。
2,定义一MYPACKET联接NEWBUFFER.
3,COPY原包必要的OOB数据及媒介信息。
就可以指示发包了。当然还要做必要的资源释放工作。
我不知道你的第2种方法是不是这样的。
像你提到的第一种修改包的方法我觉得可能存在资源释放出错的问题。因为PACKET一般是由好几个BUFFER组成,每个BUFFER指向不同的
virtualAddress表示不同的内容。你得确保你所替换的BUFFER是原包中相应的包内容。而且你还的很小心的做好资源释放工作。
 


你说的第三点能不能具体一些,我现在就是用这个方法,
copy包内容我是用
Packet->Private.Head = myPacket->Private.Head;
Packet->Private.Tail = myPacket->Private.Tail;
但是在SEND_COMPLETE_HANDLER中蓝屏了
死了都要爱......
yangyb_628
驱动牛犊
驱动牛犊
  • 注册日期2004-03-08
  • 最后登录2005-04-25
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2004-04-29 10:10
首先你得确认你的myPacket是不是新分配了资源。如果是那
Packet->Private.Head = myPacket->Private.Head;
Packet->Private.Tail = myPacket->Private.Tail;
实际是将packet得buffer头指向mypacket得buffer头,packet得buffer尾指向mypacket得buffer尾。而mypacket在SEND_COMPLETE之前已释放,进入SEND_COMPLETE中处理packet就可能会出错。
你可以将上两行屏蔽,直接copyOOB数据等。
这是我个人理解。很期待讨论。


zxcasd
驱动牛犊
驱动牛犊
  • 注册日期2001-06-14
  • 最后登录2007-08-09
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2004-04-29 10:33
首先你得确认你的myPacket是不是新分配了资源。如果是那
Packet->Private.Head = myPacket->Private.Head;
Packet->Private.Tail = myPacket->Private.Tail;
实际是将packet得buffer头指向mypacket得buffer头,packet得buffer尾指向mypacket得buffer尾。而mypacket在SEND_COMPLETE之前已释放,进入SEND_COMPLETE中处理packet就可能会出错。
你可以将上两行屏蔽,直接copyOOB数据等。
这是我个人理解。很期待讨论。


 


直接copy??还有什么方法可以直接copy包数据?copy OOB数据是没问题啊,可是我构造的包数据呢如何copy到原包中?
死了都要爱......
zxcasd
驱动牛犊
驱动牛犊
  • 注册日期2001-06-14
  • 最后登录2007-08-09
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2004-04-29 10:44

Packet->Private.Head = myPacket->Private.Head;
Packet->Private.Tail = myPacket->Private.Tail;
两行屏蔽掉是不会蓝屏了,可是这样我构造的包myPacket内容就不会指给原来的Packet了,那不就等于没起作用。如何把myPacket包内容指给原Packet而且又不会蓝屏啊?
死了都要爱......
fracker
驱动太牛
驱动太牛
  • 注册日期2001-06-28
  • 最后登录2021-03-30
  • 粉丝0
  • 关注0
  • 积分219分
  • 威望81点
  • 贡献值0点
  • 好评度23点
  • 原创分0分
  • 专家分1分
  • 社区居民
6楼#
发布于: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]
yangyb_628
驱动牛犊
驱动牛犊
  • 注册日期2004-03-08
  • 最后登录2005-04-25
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于: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分
  • 社区居民
8楼#
发布于:2004-04-29 10:50
这种方法只适用于包的长度没有变化的情况(想不出来你修改IP会引起什么长度变化,除非你在做FTP之类的东西的NAT)。

如果是使用PASSTHRU,就简单了,自己重新弄个PACKET,把你的缓冲区插进去就可以了。
zxcasd
驱动牛犊
驱动牛犊
  • 注册日期2001-06-14
  • 最后登录2007-08-09
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2004-04-29 10:54
这种方法只适用于包的长度没有变化的情况(想不出来你修改IP会引起什么长度变化,除非你在做FTP之类的东西的NAT)。

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


如果长度变化呢?因为还要修改tcp数据的内容。在ndishook中怎么做呢?
死了都要爱......
zxcasd
驱动牛犊
驱动牛犊
  • 注册日期2001-06-14
  • 最后登录2007-08-09
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
10楼#
发布于: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]


我想是这样了,我去试试看先:)
死了都要爱......
fracker
驱动太牛
驱动太牛
  • 注册日期2001-06-28
  • 最后登录2021-03-30
  • 粉丝0
  • 关注0
  • 积分219分
  • 威望81点
  • 贡献值0点
  • 好评度23点
  • 原创分0分
  • 专家分1分
  • 社区居民
11楼#
发布于: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。如果产生分片,要自行处理,论坛里面有很多人讨论这个,就不多说了。
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?我是新手,功力浅薄,还请高手不吝赐教,谢谢了
zxcasd
驱动牛犊
驱动牛犊
  • 注册日期2001-06-14
  • 最后登录2007-08-09
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
13楼#
发布于: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也返回成功,那不是发了两次?
死了都要爱......
fracker
驱动太牛
驱动太牛
  • 注册日期2001-06-28
  • 最后登录2021-03-30
  • 粉丝0
  • 关注0
  • 积分219分
  • 威望81点
  • 贡献值0点
  • 好评度23点
  • 原创分0分
  • 专家分1分
  • 社区居民
14楼#
发布于: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分
15楼#
发布于: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分
  • 社区居民
16楼#
发布于:2004-04-29 11:34
[quote][quote]
按第1种说的那样做不是有点怪么,把我自己的那个MyPacket发下去,系统传给我的那个PACKET也返回成功,那不是发了两次?

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

你的意思是系统传给我的那个包返回成功,但不返回给SEND_HANDLER是么?这样系统传给我的那个包就不会发出去了 [/quote]用MyPacket代替Packet调用SendHandler
asmsys
驱动老牛
驱动老牛
  • 注册日期2002-03-29
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望17点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
17楼#
发布于: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、重新计算校验和。这两点非常重要,而且有一些细节问题,我都说了。
zxcasd
驱动牛犊
驱动牛犊
  • 注册日期2001-06-14
  • 最后登录2007-08-09
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
18楼#
发布于: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]
死了都要爱......
youngyt
驱动牛犊
驱动牛犊
  • 注册日期2003-11-23
  • 最后登录2006-12-29
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
19楼#
发布于: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
上一页
游客

返回顶部