⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cracker.cpp

📁 Windows CE 6.0 Server 源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
            // Search out the correct location for our node and insert it         
            for(it = OrderedDelayList.begin(); it != OrderedDelayList.end(); ++it) {           
                if(pSMB->dwDelayBeforeSending > (*it)->dwDelayBeforeSending) {            
                    break;
                }    
            }   
            OrderedDelayList.insert(it, pSMB);
       } else if(0 == dwRet - WAIT_OBJECT_0) {
            TRACEMSG(ZONE_DETAIL, (L"SMBSRV-DELAYCRACKER:  got stop event--exiting thread!"));   
            hr = S_OK;
            goto Done;
        } else {
            TRACEMSG(ZONE_ERROR, (L"SMBSRV-DELAYCRACKER:  unknown response from waitformultipleobjects -- trying to continue!"));   
            ASSERT(FALSE);
        } 

        //
        // Adjust everyones timings to reflect our sleeping (so order is preserved)      
        dwStopAsleepFor = GetTickCount() - dwStartAsleepAt;
        dwStartAsleepAt = GetTickCount();
        for(itDelayAdjVar = OrderedDelayList.begin(); itDelayAdjVar != OrderedDelayList.end(); ++itDelayAdjVar) {
            if(dwStopAsleepFor <= (*itDelayAdjVar)->dwDelayBeforeSending) {
                (*itDelayAdjVar)->dwDelayBeforeSending -= dwStopAsleepFor;
            } else {
                (*itDelayAdjVar)->dwDelayBeforeSending = 0;
            }
        }  

        #ifdef DEBUG
            //
            // Perform a sanity check on the list to make sure its still in order
            ce::list<SMB_PACKET *, CRACKER_PACKETS_ALLOC >::iterator itPrev = OrderedDelayList.begin();
            ce::list<SMB_PACKET *, CRACKER_PACKETS_ALLOC >::iterator itVar = OrderedDelayList.begin();
            itVar ++;
            for(; itVar != OrderedDelayList.end(); ++itVar) {
                ASSERT((*itPrev)->dwDelayBeforeSending >= (*itVar)->dwDelayBeforeSending);
                itPrev = itVar;
            }
        #endif
        //
        // If we are here, we need to go back to sleep -- get the first packet off the list and 
        //   sleep for that long,  if the list is empty -- sleep forever    
        if(0 != OrderedDelayList.size()) {
            pSMB = OrderedDelayList.front();
            dwSleepTime = pSMB->dwDelayBeforeSending;
        
            //
            // Dont allow sleeping for more than 5 seconds (most likely an error!)
            if(5000 <= dwSleepTime) {
                dwSleepTime = 5000;
                ASSERT(FALSE);
            }       
        } else {
            dwSleepTime = INFINITE;
        }
    }

    Done:
        //
        // Purge the delayed list
        while(0 != OrderedDelayList.size()) 
        {
            SMB_PACKET *pToDel = OrderedDelayList.front();
            OrderedDelayList.pop_front();
            
            //
            // Return the memory
            SMB_Globals::g_SMB_Pool.Free(pToDel);
            
        }    
        ASSERT(0 == OrderedDelayList.size());
        return 0;
}



VOID
SendSMBResponse(SMB_PACKET *pSMB, UINT uiUsed, DWORD dwErr)
{
    SMB_HEADER *pResponseSMB = (SMB_HEADER *)(pSMB->OutSMB);
    
    //
    // Fill in error codes
    /*pResponseSMB->StatusFields.Fields.error.ErrorClass = SMB_ERR_CLASS(dwErr);
    pResponseSMB->StatusFields.Fields.error.Error = SMB_ERR_ERR(dwErr);*/
    pResponseSMB->StatusFields.Fields.dwError = dwErr;
            
    ASSERT(NULL == pSMB->pOutSMB);
    ASSERT(0 == pSMB->uiOutSize);
    
    pSMB->pOutSMB = (SMB_HEADER *)(pSMB->OutSMB);
    pSMB->uiOutSize = uiUsed;
    
    //
    // Fill in anything specific (flags etc)
    { 
        //
        // Find our connection state   
        ce::smart_ptr<ActiveConnection> pMyConnection = NULL;
        if((pMyConnection = SMB_Globals::g_pConnectionManager->FindConnection(pSMB))) {  
            pSMB->pOutSMB->Uid = pMyConnection->Uid();   
        }
    }

                       
    TRACEMSG(ZONE_SMB, (L"\n\n\n\n--------------------------------------------------------------"));
      
    //
    // If this packet is to be delayed, put it on the delay list rather than sending
    //     it now
    if(0 == pSMB->dwDelayBeforeSending) {
        
        //
        // Send out the packet, if that fails there isnt anything we can do :(
        IFDBG(pSMB->PerfPrintStatus(L"Queuing send"));
        pSMB->pfnQueueFunction(pSMB, TRUE);       
    } else {
        Cracker::LockCracker();
            ASSERT(pSMB->dwDelayBeforeSending < 5000);
            Cracker::g_PacketsToDelayCrack.push_front(pSMB);
            ReleaseSemaphore(Cracker::g_hCrackDelaySem, 1, NULL);
        Cracker::UnlockCracker();   
    }   
}



VOID  
Cracker::LockCracker()
{    
    EnterCriticalSection(&Cracker::g_csCrackLock);
}

VOID  
Cracker::UnlockCracker()
{
    LeaveCriticalSection(&Cracker::g_csCrackLock);
}


DWORD WINAPI CrackPacket_Helper(LPVOID _pSMB)
{  
    HRESULT hr=E_FAIL;
    SMB_PACKET *pSMB = (SMB_PACKET *)_pSMB;    
    
    ASSERT(SMB_NORMAL_PACKET == pSMB->uiPacketType ||
           SMB_CONNECTION_DROPPED == pSMB->uiPacketType ||
           SMB_CLIENT_IDLE_TIMEOUT == pSMB->uiPacketType);

    //
    // Check for proper SMB signature
    if(SMB_NORMAL_PACKET == pSMB->uiPacketType) {    
        
        char pSig[4];
        pSig[0] = (char)0xFF;
        pSig[1] = (char)'S';
        pSig[2] = (char)'M';
        pSig[3] = (char)'B';
    
        //
        // Verify the SMB signature is correct (it should be 0xFF,S,M,B)
        if(0 != memcmp(pSMB->pInSMB->Protocol, pSig, 4)) {
            TRACEMSG(ZONE_SMB,(L"CRACKPACKET: Error with SMB- protocol header is incorrect!"));
            ASSERT(FALSE);
            hr = E_FAIL;
            goto Done;
        }
    }
    
    //
    // Inspect the packet type to see what we are supposed to do
    //   (meaning -- is this a reg SMB or what?)
    if(SMB_NORMAL_PACKET == pSMB->uiPacketType) {                    
        UINT uiSize = SMB_Globals::MAX_PACKET_SIZE;        
        UINT uiUsed = sizeof(SMB_HEADER);
        DWORD dwErr;

        //
        // PERFPERF: *ICK*.  we need to make sure we zero or set everything
        //   this will require reviewing most of the code however.  
        //   maybe fix up helper functions to do it?  tough call.  leaving it for now

        //
        // NOTE: removing this *FOR SURE* will break 9x clients in FindFirstFile.. there prob
        //  are others as well, be careful removing this!
        memset(pSMB->OutSMB, 0, sizeof(pSMB->OutSMB));    
        
        //
        // Write in SMB header (copy and mask server flag)        
        SMB_HEADER *pResponseSMB = (SMB_HEADER *)(pSMB->OutSMB);
        ASSERT(0 == ((UINT)pResponseSMB % 2));
        memcpy(pResponseSMB, pSMB->pInSMB, sizeof(SMB_HEADER)); 
        pResponseSMB->Flags |= SMB_FLAG1_SERVER_TO_REDIR; //SMB_FLAG1_CASELESS | 
        //pResponseSMB->Flags = (SMB_FLAG1_CASELESS | SMB_FLAG1_SERVER_TO_REDIR);
        //pResponseSMB->Flags2 = pSMB->pInSMB->Flags2 & SMB_FLAGS2_UNICODE;
        uiSize -= sizeof(SMB_HEADER);
                    
        //
        // Crack the command
        UINT uiUsedByCracker = 0;
        IFDBG(pSMB->PerfPrintStatus(L"Going to cracker"));
        if (0 == (dwErr = PC_NET_PROG::CrackSMB(pSMB->pInSMB, 
                                   pSMB->uiInSize, 
                                   pResponseSMB, 
                                   uiSize, 
                                   &uiUsedByCracker, 
                                   pSMB))) {
            TRACEMSG(ZONE_SMB, (L"SMBSRV-CRACKER: SUCCESS! -- cracked by PC_NETWORK_PROGRAM_1.0"));                   
        } 
        else {
            TRACEMSG(ZONE_SMB, (L"SMBSRV-CRACKER: FAILURE! -- sending error message"));              
        }
        IFDBG(pSMB->PerfPrintStatus(L"back from cracker"));
        if(SMB_ERR(ERRInternal, PACKET_QUEUED) != dwErr) {                
            uiUsed += uiUsedByCracker;  
            SendSMBResponse(pSMB, uiUsed, dwErr);                
        }
    }
    //
    //  if the connection has dropped, we need to clean up any memory
    //    that might be outstanding
    else if(SMB_CONNECTION_DROPPED == pSMB->uiPacketType) {
        ASSERT(NULL == pSMB->pInSMB &&
               NULL == pSMB->pOutSMB &&
               0 == pSMB->uiInSize &&
               0 == pSMB->uiOutSize);  
        
        // 
        // Remove all connections on this ID from the active list           
        if(FAILED(SMB_Globals::g_pConnectionManager->RemoveConnection(pSMB->ulConnectionID, 0xFFFF))) {
            TRACEMSG(ZONE_SMB, (L"SMBSRV-CRACKER: FAILURE! -- we tried to remove a connection that doesnt exist!"));
        } else {
            TRACEMSG(ZONE_SMB, (L"SMBSRV-CRACKER: removed all info for connectionID 0x%x", pSMB->ulConnectionID));
        } 
                               
        //     
        // Process the SMB (this will cause memory to be deleted if its required) 
        hr = pSMB->pfnQueueFunction(pSMB, TRUE);
        ASSERT(SUCCEEDED(hr));
    } else if(SMB_CLIENT_IDLE_TIMEOUT == pSMB->uiPacketType) {
        //
        // If this is an idle timeout we may not close up here (b/c they
        //   may have connections opened already)            
        ce::list<ce::smart_ptr<ActiveConnection>, ACTIVE_CONN_PTR_LIST > ConnList;
        BOOL fInUse = FALSE;
        
        //
        // Find our connection state        
        SMB_Globals::g_pConnectionManager->FindAllConnections(pSMB->ulConnectionID, ConnList);
         
        while(ConnList.size()) {
            ce::smart_ptr<ActiveConnection> pConn = ConnList.front();
            ConnList.pop_front();

            ASSERT(pConn->ConnectionID() == pSMB->ulConnectionID);

            if(pConn->HasOpenedResources()) {
                fInUse = TRUE;
                break;
            }
        }
        
        if(!fInUse) {
            CloseConnectionTransport(pSMB->ulConnectionID);                            
        } 

        //     
        // Process the SMB (this will cause memory to be deleted if its required) 
        hr = pSMB->pfnQueueFunction(pSMB, TRUE);
        ASSERT(SUCCEEDED(hr));
        
    } else {
        ASSERT(FALSE);
    }
    
    
    Done:
        ReleaseSemaphore(SMB_Globals::g_CrackingSem, 1, NULL);
        return hr;
}


HRESULT CrackPacket(SMB_PACKET *pSMB)
{
    WaitForSingleObject(SMB_Globals::g_CrackingSem, INFINITE);
       
    if(!SMB_Globals::g_pCrackingPool->ScheduleEvent(CrackPacket_Helper, (LPVOID)pSMB)) {
        return E_FAIL;
    } else {
        return S_OK;
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -