NTSTATUS GetPortRules(PVOID pBuffer, ULONG *pBufferLen) { ULONG utmp=0; FIREWALL_ASKUSER *pFAS=NULL; LIST_ENTRY *pNext =NULL; AcceptedPort *pAPort =NULL; PLOCK_STATE pLockState1=NULL; pFAS = (FIREWALL_ASKUSER*)pBuffer; pLockState1 = kmalloc(sizeof(LOCK_STATE)); NdisAcquireReadWriteLock(&g_AcceptedPortListLock2, KKRWLOCK_FOR_READ, pLockState1); pNext = g_AcceptedPortListHeader.Next.Flink; while(pNext&&(pNext!=&g_AcceptedPortListHeader.Next)) { pAPort = CONTAINING_RECORD(pNext, AcceptedPort, Next); if (pAPort==NULL) { DbgBreakPoint(); } utmp++; pNext = pNext->Flink; } NdisReleaseReadWriteLock(&g_AcceptedPortListLock2, pLockState1); if (*pBufferLen<utmp*sizeof(FIREWALL_ASKUSER)) { //只是想获取buffer长度 *pBufferLen = utmp*sizeof(FIREWALL_ASKUSER); return STATUS_INFO_LENGTH_MISMATCH; } utmp=0; NdisAcquireReadWriteLock(&g_AcceptedPortListLock2, KKRWLOCK_FOR_READ, pLockState1); pNext = g_AcceptedPortListHeader.Next.Flink; while(pNext&&(pNext!=&g_AcceptedPortListHeader.Next)) { pAPort = CONTAINING_RECORD(pNext, AcceptedPort, Next); if (pAPort==NULL) { DbgBreakPoint(); } pFAS[utmp].PStatus = pAPort->PStatus; pFAS[utmp].uPort = pAPort->uPort; utmp++; pNext = pNext->Flink; } NdisReleaseReadWriteLock(&g_AcceptedPortListLock2, pLockState1); kfree(pLockState1); *pBufferLen=utmp*sizeof(FIREWALL_ASKUSER); return STATUS_SUCCESS; }
////////////////////////////////////////////////////////////////////////// //把记录的端口是否放行信息链表释放掉 NTSTATUS FWReleasePortRuleList() { AcceptedPort *pAPort =NULL; PLOCK_STATE pLockState1=NULL; PLIST_ENTRY pNext =NULL; kprintf("Enter FWReleasePortRuleList()\n"); pLockState1 = kmalloc(sizeof(LOCK_STATE)); NdisAcquireReadWriteLock(&g_AcceptedPortListLock2, KKRWLOCK_FOR_WRITE, pLockState1); while(!IsListEmpty(&g_AcceptedPortListHeader.Next)) { pNext = RemoveHeadList(&g_AcceptedPortListHeader.Next); if (pNext==NULL) { break; } pAPort = CONTAINING_RECORD(pNext, AcceptedPort, Next); if (pAPort==NULL) { break; } kprintf("Releasing Port :%d, Rule:%s\n", pAPort->uPort, pAPort->PStatus==PortDeny?"Deny":"Accept"); kfree(pAPort); } NdisReleaseReadWriteLock(&g_AcceptedPortListLock2, pLockState1); kfree(pLockState1); kprintf("Leave FWReleasePortRuleList()\n"); return STATUS_SUCCESS; }
BOOLEAN FindPort(USHORT uPort, PortStatus *PStatus) { BOOLEAN bFound = FALSE; LIST_ENTRY *pNext =NULL; AcceptedPort *pAPort =NULL; PLOCK_STATE pLockState1=NULL; pLockState1 = kmalloc(sizeof(LOCK_STATE)); NdisAcquireReadWriteLock(&g_AcceptedPortListLock2, KKRWLOCK_FOR_READ, pLockState1); pNext = g_AcceptedPortListHeader.Next.Flink; while(pNext&&(pNext!=&g_AcceptedPortListHeader.Next)) { pAPort = CONTAINING_RECORD(pNext, AcceptedPort, Next); if (pAPort==NULL) { DbgBreakPoint(); } if (pAPort->uPort==uPort) { bFound = TRUE; *PStatus = pAPort->PStatus; break; } pNext = pNext->Flink; } NdisReleaseReadWriteLock(&g_AcceptedPortListLock2, pLockState1); kfree(pLockState1); return bFound; }
VOID MpReleaseOldRWLock( PMP_READ_WRITE_LOCK Lock, PMP_RW_LOCK_STATE LockState ) #pragma warning (suppress:28167) // IRQL change { NdisReleaseReadWriteLock(&Lock->OldRWLock, &(LockState->OldLockState)); }
VOID MpReleaseOldRWLock( PMP_READ_WRITE_LOCK Lock, PMP_RW_LOCK_STATE LockState ) #pragma warning (suppress:28167) // IRQL change { _Analysis_assume_lock_acquired_(LockState->OldLockState); NdisReleaseReadWriteLock(&Lock->OldRWLock, &(LockState->OldLockState)); }
// Returns with added reference on adapter context. PTAP_ADAPTER_CONTEXT tapAdapterContextFromDeviceObject(__in PDEVICE_OBJECT DeviceObject) { LOCK_STATE lockState; // Acquire global adapter list lock. NdisAcquireReadWriteLock(&GlobalData.Lock, FALSE, // Acquire for read &lockState); if (!IsListEmpty(&GlobalData.AdapterList)) { PLIST_ENTRY entry = GlobalData.AdapterList.Flink; PTAP_ADAPTER_CONTEXT adapter; while (entry != &GlobalData.AdapterList) { adapter = CONTAINING_RECORD(entry, TAP_ADAPTER_CONTEXT, AdapterListLink); // Match on DeviceObject if (adapter->DeviceObject == DeviceObject) { // Add reference to adapter context. tapAdapterContextReference(adapter); // Release global adapter list lock. NdisReleaseReadWriteLock(&GlobalData.Lock, &lockState); return adapter; } // Move to next entry entry = entry->Flink; } } // Release global adapter list lock. NdisReleaseReadWriteLock(&GlobalData.Lock, &lockState); return (PTAP_ADAPTER_CONTEXT)NULL; }
////////////////////////////////////////////////////////////////////////// //设置端口规则 NTSTATUS SetupPortStatus(FIREWALL_ASKUSER *pFAS, ULONG uNumbers) { NTSTATUS status = STATUS_SUCCESS; AcceptedPort *pAPort =NULL; PLOCK_STATE pLockState1=NULL; PLIST_ENTRY pNext =NULL; ULONG utmp=0; BOOLEAN bFound = FALSE; kprintf("Enter SetupPortStatus()\n"); pLockState1 = kmalloc(sizeof(LOCK_STATE)); NdisAcquireReadWriteLock(&g_AcceptedPortListLock2, KKRWLOCK_FOR_WRITE, pLockState1); for (utmp=0; utmp<uNumbers; utmp++) { pNext = g_AcceptedPortListHeader.Next.Flink; while(pNext&&(pNext!=&g_AcceptedPortListHeader.Next)) { pAPort = CONTAINING_RECORD(pNext, AcceptedPort, Next); if (pAPort==NULL) { DbgBreakPoint(); } if (pAPort->uPort==pFAS[utmp].uPort) { bFound = TRUE;//找到,则更新状态 pAPort->PStatus = pFAS[utmp].PStatus; break; } pNext = pNext->Flink; } if (!bFound) { //如果找不到,说明是新加的, pAPort = kmalloc(sizeof(AcceptedPort)); pAPort->uPort = pFAS[utmp].uPort; pAPort->PStatus = pFAS[utmp].PStatus; InsertHeadList(&g_AcceptedPortListHeader.Next, &pAPort->Next); } } NdisReleaseReadWriteLock(&g_AcceptedPortListLock2, pLockState1); kfree(pLockState1); return status; }
PVOID GetTcpipArpRcvOldHandler(PVOID pSgin,PVOID pNewHandler) { LIST_ENTRY *pNextHook =NULL; PNDIS_HOOK_INFO pHI =NULL; PVOID uHandler =0; //DbgBreakPoint(); PLOCK_STATE pLockState1=NULL; pLockState1 = kmalloc(sizeof(LOCK_STATE)); NdisAcquireReadWriteLock(&g_HookTcpipFireWallLock, KKRWLOCK_FOR_READ, pLockState1); pNextHook = g_HookTcpipFireWallList.Next.Flink; while (pNextHook != &g_HookTcpipFireWallList.Next) { if (pNextHook) { pHI = CONTAINING_RECORD(pNextHook, NDIS_HOOK_INFO, Next); if (pHI->NewHandler == pNewHandler&& pHI->OldHandler!=NULL) { //如果同一个newhandler 对应多个oldhandler,会有问题 if (pHI->pSignContext==pSgin) { uHandler= pHI->OldHandler; goto __find_OldHandler; } } pNextHook = pNextHook->Flink; } else { kprintf("GetTcpipArpRcvOldHandler () what the f**k??!!!\n"); } } __find_OldHandler: if (pLockState1) { NdisReleaseReadWriteLock(&g_HookTcpipFireWallLock, pLockState1); kfree(pLockState1); } return uHandler; }
NTSTATUS FWUnhookTcpipRecvHandler() { PKK_NDIS_PROTOCOL_BLOCK pTcpipProtocolBlcok=NULL; PKK_NDIS_PROTOCOL_BLOCK pProtocolBlockHeader=NULL; ULONG ut1,ut2; PNDIS_COMMON_OPEN_BLOCK_2k3_early pOpenBlock=NULL; NTSTATUS status = STATUS_SUCCESS; PNDIS_HOOK_INFO pHI ; PULONG ptmp; PLIST_ENTRY pNext = NULL; PLOCK_STATE pLockState1=NULL; pLockState1 = kmalloc(sizeof(LOCK_STATE)); kprintf("Enter FWUnhookTcpipRecvHandler()\n"); NdisAcquireReadWriteLock(&g_HookTcpipFireWallLock, KKRWLOCK_FOR_WRITE, pLockState1); while (!IsListEmpty(&g_HookTcpipFireWallList.Next)) { pNext = RemoveHeadList(&g_HookTcpipFireWallList.Next); if (pNext==NULL) { kprintf("FWUnhookTcpipRecvHandler() fail Return Null on ExInterlockedRemoveHeadList\n"); DbgBreakPoint(); } pHI = CONTAINING_RECORD(pNext, NDIS_HOOK_INFO, Next); if (pHI==NULL) { kprintf("FWUnhookTcpipRecvHandler() fail Return Null on CONTAINING_RECORD\n"); DbgBreakPoint(); } kprintf("FWUnhookTcpipRecvHandler Name:%s, OldHandler:0x%x\n", pHI->szFuncname, pHI->OldHandler); *(PULONG_PTR)pHI->Address2Restore = (ULONG_PTR)pHI->OldHandler; kfree(pHI); } NdisReleaseReadWriteLock(&g_HookTcpipFireWallLock, pLockState1); kprintf("Leave FWUnhookTcpipRecvHandler()\n"); if (pLockState1) { kfree(pLockState1); } return status; }
VOID tapAdapterContextRemoveFromGlobalList(__in PTAP_ADAPTER_CONTEXT Adapter) { LOCK_STATE lockState; // Acquire global adapter list lock. NdisAcquireReadWriteLock(&GlobalData.Lock, TRUE, // Acquire for write &lockState); // Remove the adapter context from the global list. RemoveEntryList(&Adapter->AdapterListLink); // Safe for multiple removes. NdisInitializeListHead(&Adapter->AdapterListLink); // Remove reference added in tapAdapterContextAddToGlobalList. tapAdapterContextDereference(Adapter); // Release global adapter list lock. NdisReleaseReadWriteLock(&GlobalData.Lock, &lockState); }
VOID tapAdapterContextAddToGlobalList(__in PTAP_ADAPTER_CONTEXT Adapter) { LOCK_STATE lockState; PLIST_ENTRY listEntry = &Adapter->AdapterListLink; // Acquire global adapter list lock. NdisAcquireReadWriteLock(&GlobalData.Lock, TRUE, // Acquire for write &lockState); // Adapter context should NOT be in any list. ASSERT((listEntry->Flink == listEntry) && (listEntry->Blink == listEntry)); // Add reference to persist until after removal. tapAdapterContextReference(Adapter); // Add the adapter context to the global list. InsertTailList(&GlobalData.AdapterList, &Adapter->AdapterListLink); // Release global adapter list lock. NdisReleaseReadWriteLock(&GlobalData.Lock, &lockState); }
////////////////////////////////////////////////////////////////////////// //当用户对某个端口的访问做好决定后会调用这个函数 //此函数不同SetupPortStatus,ResponsePortAsk函数还要负责调用向上indicate一个 syn包 NTSTATUS ResponsePortAsk(FIREWALL_ASKUSER *pPAsk) { NTSTATUS status = STATUS_SUCCESS; AcceptedPort *pAPort =NULL; PLOCK_STATE pLockState1=NULL; PLIST_ENTRY pNext =NULL; ULONG utmp=0; BOOLEAN bFound = FALSE; PAcceptedPort pIndicateContext=NULL; #ifdef VMPROTECT VMProtectBeginVirtualization("Response ask"); #endif pIndicateContext = kmalloc(sizeof(AcceptedPort)); // pLockState1 = kmalloc(sizeof(LOCK_STATE)); NdisAcquireReadWriteLock(&g_AcceptedPortListLock2, KKRWLOCK_FOR_READ, pLockState1); pNext = g_AcceptedPortListHeader.Next.Flink; while(pNext&&(pNext!=&g_AcceptedPortListHeader.Next)) { pAPort = CONTAINING_RECORD(pNext, AcceptedPort, Next); if (pAPort==NULL) { DbgBreakPoint(); } if (pAPort->uPort==pPAsk->uPort&&pAPort->SrcIP==pPAsk->SrcIP) { bFound = TRUE;//找到,则更新状态 pAPort->PStatus = pPAsk->PStatus; break; } pNext = pNext->Flink; } if (bFound) { *pIndicateContext = *pAPort; //为了安全,做一份拷贝吧 } NdisReleaseReadWriteLock(&g_AcceptedPortListLock2, pLockState1); if (bFound&&pPAsk->PStatus==PortAccept) { //找到,并且是接收状态,则需要上传一个第一次握手的syn数据包 PIO_WORKITEM pWorkItem = NULL; PASKUserWorkItemContext pAskContext =NULL; pWorkItem = IoAllocateWorkItem(g_CtlDevice); pAskContext = kmalloc(sizeof(ASKUserWorkItemContext)); pAskContext->pWorkItem = pWorkItem; pAskContext->pContext = pIndicateContext; IoQueueWorkItem(pWorkItem, ResponsePortAskWorkerForIndicateupPacket, DelayedWorkQueue, pAskContext); pIndicateContext=NULL; } if (pIndicateContext) { kfree(pIndicateContext);pIndicateContext=NULL; } kfree(pLockState1); #ifdef VMPROTECT VMProtectEnd(); #endif return status; }
NTSTATUS FWHookTcpipRecvHandler() { PKK_NDIS_PROTOCOL_BLOCK pTcpipProtocolBlcok=NULL; PKK_NDIS_PROTOCOL_BLOCK pProtocolBlockHeader=NULL; ULONG ut1,ut2; PNDIS_COMMON_OPEN_BLOCK_2k3_early pOpenBlock=NULL; NTSTATUS status = STATUS_SUCCESS; PNDIS_HOOK_INFO pHI ; PULONG ptmp; PLOCK_STATE pLockState1=NULL; #ifdef VMPROTECT VMProtectBeginVirtualization("FWHookTcpipRecvHandler"); #endif pLockState1 = kmalloc(sizeof(LOCK_STATE)); ut1 = ut2 = 0; do { pTcpipProtocolBlcok = (PKK_NDIS_PROTOCOL_BLOCK)GetTcpipProtocolBlock(); if (pTcpipProtocolBlcok==0) { status = STATUS_UNSUCCESSFUL; break; } pOpenBlock = pTcpipProtocolBlcok->OpenQueue; NdisAcquireReadWriteLock(&g_HookTcpipFireWallLock, KKRWLOCK_FOR_WRITE, pLockState1); while(pOpenBlock) { // if (!IsPhysicalMiniport(pOpenBlock->MiniportHandle)) // { // goto __nextpOpenBlock; // } pHI = kmalloc(sizeof(NDIS_HOOK_INFO)); ptmp=NULL; RtlZeroMemory(pHI, sizeof(NDIS_HOOK_INFO)); pHI->OldHandler = (PVOID)pOpenBlock->ReceiveHandler; pHI->Address2Restore = &(pOpenBlock->ReceiveHandler); pHI->pMiniBlock = (ULONG)pOpenBlock->MiniportHandle; pHI->pSignContext = (PVOID)pOpenBlock->ProtocolBindingContext; pHI->pProtocolBindingContext = (ULONG)pOpenBlock->ProtocolBindingContext; pHI->pOpenblock = (ULONG_PTR)pOpenBlock; pHI->szFuncname = "KKNewTcpipArpRcv"; pHI->NewHandler = (PVOID)KKNewTcpipArpRcv; *(PULONG)&(pOpenBlock->ReceivePacketHandler)=0; //把这个清0了 InsertHeadList(&g_HookTcpipFireWallList.Next, &pHI->Next); ptmp = (ULONG*)pHI->Address2Restore; *ptmp = (ULONG)KKNewTcpipArpRcv; //__nextpOpenBlock: pOpenBlock = (PNDIS_COMMON_OPEN_BLOCK_2k3_early)pOpenBlock->ProtocolNextOpen; } NdisReleaseReadWriteLock(&g_HookTcpipFireWallLock, pLockState1); } while (0); if (pLockState1) { kfree(pLockState1); } #ifdef VMPROTECT VMProtectEnd(); #endif return status; }
NDIS_STATUS KKNewTcpipArpRcv( IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_HANDLE MacReceiveContext, IN PVOID HeaderBuffer, IN UINT HeaderBufferSize, IN PVOID LookAheadBuffer, IN UINT LookAheadBufferSize, IN UINT PacketSize ) { Tcp_Header *pTcpHdr = NULL; Ip_Header *pIPHdr = NULL; Dlc_Header *pDlcHdr = NULL; NTSTATUS status = STATUS_SUCCESS; PortStatus PStatus; BOOLEAN bFound = FALSE; //不拦截,直接bypass if (g_InterceptTCPIPRcv==0) { goto __BypassTcpipArpRcv; } if (HeaderBufferSize!=sizeof(Dlc_Header)) { goto __BypassTcpipArpRcv; } if ( LookAheadBufferSize<=(sizeof(Tcp_Header)+sizeof(Ip_Header)) ) { //非完整TCP包,不管了,也不transfdata了 goto __BypassTcpipArpRcv; } pDlcHdr = (Dlc_Header *)HeaderBuffer; pIPHdr = (Ip_Header *)LookAheadBuffer; pTcpHdr = (Tcp_Header *) ((PUCHAR)LookAheadBuffer + sizeof(Ip_Header)); if (pDlcHdr->ethertype!=ntohs(ETHPROTO_IP)) { kprintf("KKNewTcpipArpRcv(),ethertype!= ETHPROTO_IP\n"); goto __BypassTcpipArpRcv; } if (pIPHdr->proto!=IPPROTO_TCP) { goto __BypassTcpipArpRcv;; } if ( LookAheadBufferSize>=(sizeof(Tcp_Header)+sizeof(Ip_Header)+20) ) { //太大了,肯定不是syn包 goto __BypassTcpipArpRcv; } if (!CheckIsSynConnectPacket(pTcpHdr)) { goto __BypassTcpipArpRcv; } bFound = FindPort(ntohs(pTcpHdr->dstport), &PStatus); if (bFound) { //找到,说明正在在处理,或者处理过了 if (PStatus==PortAccept) { kprintf("Port:%d accepted\n", ntohs(pTcpHdr->dstport)); goto __BypassTcpipArpRcv; } if (PStatus==PortDeny) { kprintf("Port:%d PortDeny\n", ntohs(pTcpHdr->dstport)); } goto __DROP; //deny肯定要drop,unkown的话,说明正在访问用户,也drop } else { //没找到,那就得弹窗口询问用户了 //先把这个端口加到链表中 AcceptedPort *pAPort =NULL; PIO_WORKITEM pWorkItem = NULL; PASKUserWorkItemContext pAskContext =NULL; PLOCK_STATE pLockState1=NULL; PFIREWALL_ASKUSER pFAS=NULL; pLockState1 = kmalloc(sizeof(LOCK_STATE)); pWorkItem = IoAllocateWorkItem(g_CtlDevice); pAskContext = kmalloc(sizeof(ASKUserWorkItemContext)); pFAS = kmalloc(sizeof(FIREWALL_ASKUSER)); pAPort = kmalloc(sizeof(AcceptedPort)); pAPort->uPort = ntohs(pTcpHdr->dstport); pAPort->PStatus = PortUnknow; pAskContext->pWorkItem = pWorkItem; pAskContext->pContext = (PVOID)pFAS; pAPort->ProtocolBindingContext = (ULONG_PTR)ProtocolBindingContext; pAPort->MacReceiveContext = (ULONG_PTR)MacReceiveContext; RtlMoveMemory(pAPort->cMacSrcDst, HeaderBuffer, sizeof(pAPort->cMacSrcDst)); pAPort->SrcIP = pIPHdr->sourceIP; pAPort->DstIP = pIPHdr->destIP; //存好这些信息,后面查找向上提syn包时可以用到 pFAS->DstIP = pAPort->DstIP; pFAS->SrcIP = pAPort->SrcIP; pFAS->uPort = pAPort->uPort; //直接保存下来,后来提交的时候直接往上交就行了,不用自己组包 pAPort->HeaderBufferSize = HeaderBufferSize; RtlMoveMemory(pAPort->HeaderBuffer, HeaderBuffer, HeaderBufferSize); pAPort->LookAheadBufferSize = LookAheadBufferSize; RtlMoveMemory(pAPort->LookAheadBuffer, LookAheadBuffer, LookAheadBufferSize); NdisAcquireReadWriteLock(&g_AcceptedPortListLock2, KKRWLOCK_FOR_WRITE, pLockState1); InsertHeadList(&g_AcceptedPortListHeader.Next, &pAPort->Next); NdisReleaseReadWriteLock(&g_AcceptedPortListLock2, pLockState1); kfree(pLockState1); IoQueueWorkItem(pWorkItem, AskUserWorker, DelayedWorkQueue, pAskContext); goto __DROP; } __BypassTcpipArpRcv: return BypassTcpipArpRcv(ProtocolBindingContext, MacReceiveContext, HeaderBuffer, HeaderBufferSize, LookAheadBuffer, LookAheadBufferSize, PacketSize); __DROP: return NDIS_STATUS_NOT_ACCEPTED; }