阅读:2726回复:11
数据包拦截实现
通过注册假协议的方法hook ndis,要hook哪些handler呢?
我要求将所有发送出去的数据都截获,然后用自己构造的PACKET再将数据包原样发送出去。 接收到的数据也要截获,用自己构造的PACKET送入网卡。 需要怎么做啊? 发送的时候我都是NdisAllocateMemory,NdisAllocateBuffer,NdisAllocatePacket,构造了MyPacket,再调用SendHandler或SendPacketsHandler发送出去MyPacket,再处理SendCompleteHandler,释放,好像没什么问题。 接受的时候同样做NdisAllocateMemory,NdisAllocateBuffer,NdisAllocatePacket,构造了MyPacket,调用ReceiveHandler或ReceivePacketHandler接受,不知道还要怎样处理,我的要蓝屏?? 还有一问,我想在驱动初始化的时候NdisAllocateMemory,NdisAllocateBuffer,NdisAllocatePacket,分配这些,然后每次处理数据的时候就不用再重新分配了,应该效率要高一些,可是这样做要蓝屏,为什么呢? 希望有前辈们尽快帮我解决一下啊!! |
|
沙发#
发布于:2010-05-07 16:26
现在的驱网人气貌似不是很好啊
|
|
板凳#
发布于:2010-05-07 16:38
不是没有人气,而是所要知道的问题都有贴了,自己去查看一些贴就可以了。
最后一个问题不知道你怎么处理,当然不知道为什么蓝屏。 初始化就申请一个数据报内存,不蓝才怪呢。把问题描述清楚些才能知道原因。 |
|
|
地板#
发布于:2010-05-09 20:16
我的问题很简单也很清楚啊,就是把所有ndis处理的包hook了,拦截到我的包中,再将我的包发出去,包的所有内容不做任何修改。
至于说以前的帖子,不是没认真找,说实话就像大海捞针,而且很多也是问的问题而没有答案,或者不是我要的答案啊。 要是有这么一个系统的讲解这方面的帖子,该有多好啊,或者是我没看到,还望坛主指教呢。 我 是 个新手,但谁都有过这个阶段啊,如果达人们肯小小的指点一下,岂不是受益匪浅。 “初始化就申请一个数据报内存,不蓝才怪呢”,到底该怎么做呢? 不知坛主可不可以指点几篇帖子让小弟去学习学习啊? |
|
地下室#
发布于:2010-05-10 12:23
发送的时候:(oldPacket是原来的包,newPacket是你重组的包
NdisGetPacketFlags(newPacket) = Flags; NdisQueryPacket(oldPacket, NULL, NULL, &ndis_buffer, &totaLlen); status = NdisAllocateMemory((PVOID)&newBuf, totaLlen, 0, MaxAddress); if(status != NDIS_STATUS_SUCCESS) { //内存分配失败,用原包发送 NDIS_PACKET_FIRST_NDIS_BUFFER(newPacket) = NDIS_PACKET_FIRST_NDIS_BUFFER(oldPacket); NDIS_PACKET_LAST_NDIS_BUFFER(newPacket) = NDIS_PACKET_LAST_NDIS_BUFFER(oldPacket); } else { // NdisZeroMemory((PVOID)&newBuf, totaLlen); tmpBuf = newBuf; //自己分配内存构建新包 while (NULL != ndis_buffer) { NdisQueryBufferSafe(ndis_buffer, &address, ¤t_len, NormalPagePriority); NdisMoveMemory(tmpBuf, address, current_len); (PUCHAR)tmpBuf += current_len; NdisGetNextBuffer(ndis_buffer, &ndis_buffer); } NdisAllocateBuffer(&status, &myBuf, pAdapt->SendPacketPoolHandle, newBuf, totaLlen); if (NDIS_STATUS_SUCCESS != status) { DBGPRINT(("setPacketDesc-------------->NdisAllocateBuffer FAILED\n")); NdisFreeMemory(newBuf, totaLlen, 0); NDIS_PACKET_FIRST_NDIS_BUFFER(newPacket) = NDIS_PACKET_FIRST_NDIS_BUFFER(oldPacket); NDIS_PACKET_LAST_NDIS_BUFFER(newPacket) = NDIS_PACKET_LAST_NDIS_BUFFER(oldPacket); } else { // DBGPRINT(("setPacketDesc-------------->NdisAllocateBuffer SUCCESSED\n")); NdisChainBufferAtFront(newPacket, myBuf); } } 到这里只是包重组了 没做任何修改 如果你需要做修改可以在myBuf里面修改任何你想要修改的东西 接收的时候: // 将包头和 LookAheadBuffer 复制到新分配的内存中 NdisZeroMemory(pPacketContent, BUFFER_SIZE); NdisMoveMemory(pPacketContent, HeaderBuffer, HeaderBufferSize); NdisMoveMemory(pPacketContent+ HeaderBufferSize, LookAheadBuffer, LookAheadBufferSize); PacketLen = PacketSize+HeaderBufferSize; Status=NdisAllocateMemoryWithTag((PVOID *)&pPacket, 4, 'maDN'); if(Status != NDIS_STATUS_SUCCESS) { DbgPrint("PTReceive:NdisAllocateMemory Failed\n"); return(NDIS_STATUS_NOT_ACCEPTED); } if(pPacket== NULL) { DbgPrint("PTReceive:pPacket==NULL\n"); return(NDIS_STATUS_NOT_ACCEPTED); } // 在包池中分配包描述符 NdisDprAllocatePacket(&Status, &MyPacket, pAdapt->RecvPacketPoolHandle); if(Status == NDIS_STATUS_SUCCESS) { DbgPrint("--------------------------------------------------------开始关联包.\n"); // 在缓冲池中分配缓冲描述符,将包描述符与缓冲描述符关联。 NdisAllocateBuffer(&Status, &pPacketBuffer, pAdapt->RecvBufferPoolHandle, pPacketContent,PacketLen); NdisChainBufferAtFront(MyPacket, pPacketBuffer); MyPacket->Private.Head->Next = NULL; MyPacket->Private.Tail = NULL; RecvRsvd=(PRECV_RSVD)(MyPacket->MiniportReserved); RecvRsvd->OriginalPkt = NULL; NDIS_SET_PACKET_HEADER_SIZE(MyPacket, HeaderBufferSize); // 向上层协议驱动指示数据包,防真网卡行为。 NdisMIndicateReceivePacket(pAdapt->MiniportHandle, &MyPacket, 1); if(NDIS_GET_PACKET_STATUS(MyPacket) != NDIS_STATUS_PENDING) { DBGPRINT(("In PtReceive And Free Memory\n")); NdisFreeBuffer(pPacketBuffer); NdisFreeMemory(pPacketContent, BUFFER_SIZE, 0); NdisFreeMemory(pPacket, 4, 0); NdisDprFreePacket(MyPacket); } } 这里也是对包没有做任何修改 你要修改的话可以在pPacketContent做任何你想做的事情然后关联 讲的很清楚了 你要还做不出来我也没办法了 |
|
5楼#
发布于:2010-05-10 12:26
1 除了最后一个问题其他没说你描述不清楚
2 最后一个问题你没有描述清楚:是开始申请一个池,还是只有一个数据报?不知道 3 察看精华贴,有关于ndis流程的介绍。 4 每个人都在工作,既然有答案了,何必再回答? 只有我还这么无聊出来说话,呵呵! 每个人都有新手阶段,但每个人也都是这么经历过来的。所以有了资料,还是需要自己去查找整理消化。当然确实是难题的除外。 |
|
|
6楼#
发布于:2010-05-10 16:52
谢谢cyliu,谢谢vipfengxiao,我开始去消化吸收了。
如果再遇到问题不过还望你们一如既往的帮助小弟。 其实我也是从一无所知到现在的哈,我也会自己去努力学习的。 总之,谢谢你们。 |
|
7楼#
发布于:2010-05-10 17:54
这样吧,我把我的这部分代码贴上来,主要是接收包的部分,现在我只hook了ReceivePacketHandler
INT NDIS_API MyReceivePacket( IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_PACKET Packet) { INT nRet; BOOLEAN bIsMyFilterPacket = FALSE; //KdPrint(("---HOOK-----MyReceivePacket\n")); bIsMyFilterPacket = MyFilterReceivePacket(Packet); if (bIsMyFilterPacket) { //KdPrint(("FilterReceivePacket success!\n")); nRet = ((RECEIVE_PACKET_HANDLER)m_pReceivePacket)(ProtocolBindingContext, m_pMyPacket);// if (NDIS_GET_PACKET_STATUS(m_pMyPacket) != NDIS_STATUS_PENDING) { //KdPrint(("ReceivePacket free...\n")); if (m_pMyBuffer) { NdisFreeBuffer(m_pMyBuffer); m_pMyBuffer = NULL; } if (m_pBuffer) { NdisFreeMemory(m_pBuffer, m_nMyPacketLen, 0); m_pBuffer = NULL; } if (m_pMyPacket) { NdisFreePacket(m_pMyPacket); m_pMyPacket = NULL; } } } else nRet = ((RECEIVE_PACKET_HANDLER)m_pReceivePacket)(ProtocolBindingContext, Packet); return nRet; } //我的处理接收数据包的函数 BOOLEAN MyFilterReceivePacket(PNDIS_PACKET pPacket) { NTSTATUS nStatus; DWORD dwPacketSize = 0; PVOID pBuffer = NULL; PNDIS_BUFFER pCurrentBuffer,pNextBuffer; PVOID pVirtualAddress; UINT len; DWORD count = 0; //取得包的大小及第一个NDIS_BUFFER指针 //或者pCurrentBuffer = pPacket->Private.Head; NdisQueryPacket(pPacket, NULL, NULL, &pCurrentBuffer, &dwPacketSize); if (dwPacketSize < sizeof(ETHHDR)) return FALSE; //分配空间 nStatus = NdisAllocateMemoryWithTag(&pBuffer, dwPacketSize, 'NAMW'); if (nStatus != NDIS_STATUS_SUCCESS || pBuffer == NULL) return FALSE; //读取包 while (pCurrentBuffer != NULL) { //NdisQueryBufferSafe can't use in wdm1.0 NdisQueryBufferSafe(pCurrentBuffer, &pVirtualAddress, &len, NormalPagePriority); if(!pVirtualAddress) { break; } if (count + len > dwPacketSize) break; NdisMoveMemory(&((BYTE *)pBuffer)[count], pVirtualAddress, len); count += len; NdisGetNextBuffer(pCurrentBuffer, &pNextBuffer);// pCurrentBuffer = pNextBuffer; } ////////////////////////////////////////////////////////////////////////// //这部分就是将原始包拷贝到我的PACKET中,不做任何修改 m_nMyPacketLen = dwPacketSize; m_pBuffer = NULL; nStatus = NdisAllocateMemoryWithTag(&m_pBuffer, m_nMyPacketLen, 'NAMW'); if (nStatus != NDIS_STATUS_SUCCESS) return FALSE; //------------ NdisZeroMemory((BYTE*)m_pBuffer, m_nMyPacketLen); NdisMoveMemory((BYTE*)m_pBuffer, (BYTE*)pBuffer, m_nMyPacketLen); m_pMyBuffer = NULL; //m_hMyBufferPool,m_hMyPacketPool是在初始化的时候分配的 NdisAllocateBuffer(&nStatus, &m_pMyBuffer, m_hMyBufferPool, m_pBuffer, m_nMyPacketLen); if (nStatus != NDIS_STATUS_SUCCESS) return FALSE; m_pMyPacket = NULL; NdisAllocatePacket(&nStatus, &m_pMyPacket, m_hMyPacketPool); if (nStatus != NDIS_STATUS_SUCCESS) return FALSE; NdisChainBufferAtFront(m_pMyPacket, m_pMyBuffer); m_pMyPacket->Private.Head->Next=NULL; m_pMyPacket->Private.Tail=NULL; NDIS_SET_PACKET_HEADER_SIZE(m_pMyPacket,14); //NdisSetPacketFlags(m_pMyPacket, NDIS_FLAGS_DONT_LOOPBACK); //避免收到自己发送的包 //////////////////////////////////////////////////////////////////////////// //释放空间 NdisFreeMemory(pBuffer, dwPacketSize, 0); return TRUE; } 其他hook函数我没有做任何处理,仅仅是调用了原来的Handler。 可是调试的时候还是要死,不知道还要在SendCompleteHandler里做什么处理吗? 还烦cyliu,vipfengxiao有时间的话给我看看哈,谢谢了! |
|
8楼#
发布于:2010-05-11 11:05
to vipfengxiao:
" Status=NdisAllocateMemoryWithTag((PVOID *)&pPacket, 4, 'maDN'); " 请问这里分配的pPacket是用来做什么的呢? |
|
9楼#
发布于:2010-05-11 12:13
回 8楼(pdavidchang) 的帖子
这个没用 是我的程序中用到的你不用管 |
|
10楼#
发布于:2010-05-11 15:07
|
|
11楼#
发布于:2010-05-12 09:20
|
|