📄 cracker.cpp
字号:
// 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 + -