cyliu
论坛版主
论坛版主
  • 注册日期2003-06-13
  • 最后登录2014-04-11
  • 粉丝5
  • 关注0
  • 积分1238分
  • 威望2531点
  • 贡献值0点
  • 好评度577点
  • 原创分14分
  • 专家分10分
阅读:1879回复:5

[急]直接修改网络数据是否有问题?

楼主#
更多 发布于:2005-06-16 16:12
高手们,我在ReceiveHandler,ReceivePacketHandler,SendHandler,SendPacketsHandler中直接修改了Buffer 和Packet中的数据(就是修改了网络桢中Frame类型字段数值).
没有这样做:先拷贝数据到我们自己分配的空间,然后修改拷贝的数据最后发送修改后自己打包数据.

直接修改从网络驱动传来或协议栈传来Buffer,Packet中数据,这样做会有问题吗?
走走看看开源好 Solaris vs Linux
cyliu
论坛版主
论坛版主
  • 注册日期2003-06-13
  • 最后登录2014-04-11
  • 粉丝5
  • 关注0
  • 积分1238分
  • 威望2531点
  • 贡献值0点
  • 好评度577点
  • 原创分14分
  • 专家分10分
沙发#
发布于:2005-06-17 15:07
Hi,zhaock!

NDIS_STATUS NDIS_API
XF_TcpipReceiveHandler(
    IN NDIS_HANDLE NdisBindingContext,
    IN NDIS_HANDLE MacReceiveContext,
    IN PVOID HeaderBuffer,
    IN UINT HeaderBufferSize,
    IN PVOID LookAheadBuffer,
    IN UINT LookaheadBufferSize,
    IN UINT PacketSize
)
{
NDIS_STATUS status;

dprintf((\"XF_TcpipReceiveHandler\\n\"));

if(g_isAclFrame )
CheckTcpipRecvBuffer(HeaderBuffer,HeaderBufferSize, LookAheadBuffer,LookaheadBufferSize,PacketSize);

status = m_pTcpipReceiveHandler (
NdisBindingContext,
MacReceiveContext,
HeaderBuffer,
HeaderBufferSize,
LookAheadBuffer,
LookaheadBufferSize,
PacketSize
);
return status;
}

INT NDIS_API
XF_TcpipReceivePacketHandler(
IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_PACKET Packet
)
{
NDIS_STATUS status;

dprintf((\"XF_TcpipReceivePacketHandler\\n\"));


if(g_isAclFrame)
CheckTcpipRecvPacket(Packet);

status = m_pTcpipReceivePacketHandler(ProtocolBindingContext, Packet);

return status;
}

UINT NDIS_API
XF_TcpipCoReceivePacketHandler(
IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_HANDLE ProtocolVcContext,
IN PNDIS_PACKET Packet)
{
dprintf((\"XF_TcpipCoReceivePacketHandler\\n\"));

if(g_isAclFrame)
CheckTcpipRecvPacket(Packet);

return m_pTcpipCoReceivePacketHandler( ProtocolBindingContext, ProtocolVcContext, Packet);
}

NDIS_STATUS NDIS_API
XF_TcpipSendHandler(
IN  PTCPIP_FUNCTION_MAP FunctionMap,
IN NDIS_HANDLE MacBindingHandle,
IN PNDIS_PACKET Packet
)
{
NDIS_STATUS status;

dprintf((\"XF_TcpipSendHandler\\n\"));

if(m_pSendPacketAddress == 0)
{
m_pSendPacketAddress = (ULONG)FunctionMap -> old_SendHandler;
m_pSendPacketsAddress = (ULONG)FunctionMap -> old_SendPacketsHandler;
}

if(g_isAclFrame)
CheckTcpipSendPacket(Packet);

status = FunctionMap -> old_SendHandler(MacBindingHandle, Packet);

return (status);
}

VOID NDIS_API
XF_TcpipSendPacketsHandler(
IN PTCPIP_FUNCTION_MAP FunctionMap,
IN NDIS_HANDLE NdisBindingHandle,
IN PPNDIS_PACKET PacketArray,
IN UINT NumberOfPackets
)
{
UINT i = 0;

dprintf((\"XF_TcpipSendPacketsHandler\\n\"));
 
if(g_isAclFrame)
{
for (i = 0; i < NumberOfPackets; i++)
{
CheckTcpipSendPacket(PacketArray);
}
}

FunctionMap -> old_SendPacketsHandler(NdisBindingHandle, PacketArray, NumberOfPackets);
}

int CheckSendPacket(IN OUT PNDIS_PACKET packet)
{
PNDIS_BUFFER FirstBuffer = NULL;
PVOID VirtualAddress = 0;
int Length = 0;
PETHERNET_FRAME pEthernetFrame = 0;

NdisQueryPacket(packet
, NULL
, NULL
, &FirstBuffer
, NULL
);

if(FirstBuffer != NULL)
{
NdisQueryBufferSafe(FirstBuffer, &VirtualAddress, &Length, HighPagePriority);

if(Length < ETHERNET_FRAME_LENGTH)
return XF_SUCCESS;

pEthernetFrame = (PETHERNET_FRAME)VirtualAddress;

dprintf((\"CheckSendPacket<FrameType>: pre 0x%x \\n\",ntohs(pEthernetFrame -> FrameType)));
pEthernetFrame -> FrameType = encrypto(pEthernetFrame -> FrameType);
dprintf((\"CheckSendPacket<FrameType>: pos 0x%x \\n\\n\",ntohs(pEthernetFrame -> FrameType)));
}
else
dprintf((\"CheckSendPacket: invalid ether packet \\n\\n\"));

return XF_SUCCESS;
}

//解密接收到数据包
int CheckRecvPacket(IN OUT PNDIS_PACKET packet)
{
PNDIS_BUFFER FirstBuffer = NULL;
PVOID VirtualAddress = 0;
int Length = 0;
PETHERNET_FRAME pEthernetFrame = 0;

NdisQueryPacket(packet
, NULL
, NULL
, &FirstBuffer
, NULL);

if(FirstBuffer != NULL)
{
NdisQueryBufferSafe(FirstBuffer, &VirtualAddress, &Length, HighPagePriority);

if(Length < ETHERNET_FRAME_LENGTH)
return XF_SUCCESS;

pEthernetFrame = (PETHERNET_FRAME)VirtualAddress;

dprintf((\"CheckRecvPacket<FrameType>: pre 0x%x \\n\",ntohs(pEthernetFrame -> FrameType)));
pEthernetFrame -> FrameType = decrypto(pEthernetFrame -> FrameType);
dprintf((\"CheckRecvPacket<FrameType>: pos 0x%x \\n\\n\",ntohs(pEthernetFrame -> FrameType)));
}
else
dprintf((\"CheckRecvPacket: invalid ether packet \\n\\n\"));

return XF_SUCCESS;
}
//解密接收到数据包
int CheckRecvBuffer(IN OUT PVOID HeaderBuffer,
IN UINT HeaderBufferSize,
IN PVOID LookAheadBuffer,
IN UINT LookaheadBufferSize,
IN UINT PacketSize)
{
PETHERNET_FRAME pEthernetFrame = 0;

if(HeaderBuffer &&
(HeaderBufferSize >= ETHERNET_FRAME_LENGTH))
{
pEthernetFrame = (PETHERNET_FRAME)HeaderBuffer;

dprintf((\"CheckRecvBuffer<FrameType>: pre 0x%x \\n\",ntohs(pEthernetFrame -> FrameType)));
pEthernetFrame -> FrameType = decrypto(pEthernetFrame -> FrameType);
dprintf((\"CheckRecvBuffer<FrameType>: pos 0x%x \\n\\n\",ntohs(pEthernetFrame -> FrameType)));
}
else
dprintf((\"CheckRecvBuffer: invalid ether packet \\n\\n\"));

return XF_SUCCESS;
}

zhaock , 你帮我看看这里有什么不妥的地方吗? 为何有的网卡对tcp数据没有反应啊?
谢谢
走走看看开源好 Solaris vs Linux
cyliu
论坛版主
论坛版主
  • 注册日期2003-06-13
  • 最后登录2014-04-11
  • 粉丝5
  • 关注0
  • 积分1238分
  • 威望2531点
  • 贡献值0点
  • 好评度577点
  • 原创分14分
  • 专家分10分
板凳#
发布于:2005-06-17 10:29
Thanks , zhaock!

今天我跟踪了一下代码,发现一个问题,大家分享一下:

_NDIS_OPEN_BLOCK的ProtocolHandle应该指向协议栈,类型为PNDIS_PROTOCOL_BLOCK.NDIS_PROTOCOL_BLOCK中_NDIS_PROTOCOL_CHARACTERISTICS指向协议

hook完成后,发现_NDIS_PROTOCOL_CHARACTERISTICS中的ReceiveHandler,ReceivePacketHandler数值根本没有改变.反而是_NDIS_OPEN_BLOCK中ReceiveHandler,ReceivePacketHandler指向了我们的函数.

也许系统都是调用_NDIS_OPEN_BLOCK中有关接口来接收发发送数据的.而_NDIS_PROTOCOL_CHARACTERISTICS中的接收函数不起作用了.
走走看看开源好 Solaris vs Linux
zhaock
驱动太牛
驱动太牛
  • 注册日期2002-01-26
  • 最后登录2018-06-02
  • 粉丝3
  • 关注2
  • 积分73328分
  • 威望362317点
  • 贡献值1点
  • 好评度226点
  • 原创分0分
  • 专家分0分
  • 社区居民
地板#
发布于:2005-06-16 19:02
1。ReceiveHandler,ReceivePacketHandler不会存在对同一数据解密两次以上的操作的可能性。
2。对于你hook的tcp/ip的ReceiveHandler,ReceivePacketHandler,直接修改了数据,如果你还装有其他协议,比如装了sniffer,在链表中位于tcp/ip协议的后面,那它看到的将是修改后的数据。你不用考虑这种情况
3。现在在做64位移植,写情景分析,不得不往后推了,呵呵


cyliu
论坛版主
论坛版主
  • 注册日期2003-06-13
  • 最后登录2014-04-11
  • 粉丝5
  • 关注0
  • 积分1238分
  • 威望2531点
  • 贡献值0点
  • 好评度577点
  • 原创分14分
  • 专家分10分
地下室#
发布于:2005-06-16 17:59
zhaock,现在问题很关键,一定帮我搞清楚啊!

过程:

A机器通过SendHandler,SendPacketsHandler加密数据,发送数据;
B机器通过ReceiveHandler,ReceivePacketHandler接收数据,解密数据,然后上传数据.

A和B的所谓加解密数据就是简单修改各种报头数据,如Frame,IP,Tcp等,而且是直接修改接收到Packet,Buffer.

你的\"对于ReceiveHandler,ReceivePacketHandler,如果还有其他协议,如此修改,之后的协议看到的将是修改后的数据\"是什么意思?

我现在不明白在ReceiveHandler,ReceivePacketHandler中是否存在对同一数据(如Frame头内容或者TP,TCP头内容)解密两次以上的操作的可能性?

为什么会有这个担心呢?
因为驱动接收到数据后会上传一部分协议头数据给tcpip协议栈,判断是否接收该协议数据.如果接收,再上传所有数据.这时候上传所有数据时(是否会再次调用ReceiveHandler,ReceivePacketHandler ?),如果同时加上已经修改的协议数据(因为我是直接修改的数据,所以这时候Frame,ip,tcp报头数据是改动了),在ReceiveHandler,ReceivePacketHandler 中该数据就会有第二次解密过程,从而造成数据错误?

现在我没有处理TransferDataHandler函数,因为我只处理Frame ,ip,tcp的报头数据,我认为TransferDataHandler不会出现这些数据!

我是否说清楚了?

zhaock,等待你的答复.

同时还想早日能够看到你的Windows情景...的文章啊!

走走看看开源好 Solaris vs Linux
zhaock
驱动太牛
驱动太牛
  • 注册日期2002-01-26
  • 最后登录2018-06-02
  • 粉丝3
  • 关注2
  • 积分73328分
  • 威望362317点
  • 贡献值1点
  • 好评度226点
  • 原创分0分
  • 专家分0分
  • 社区居民
5楼#
发布于:2005-06-16 17:25
1对于SendHandler,SendPacketsHandler不会有什么问题
2但对于ReceiveHandler,ReceivePacketHandler,如果还有其他协议
,如此修改,之后的协议看到的将是修改后的数据
游客

返回顶部