📄 cracker.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft shared
// source or premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license agreement,
// you are not authorized to use this source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the SOURCE.RTF on your install media or the root of your tools installation.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
#include "SMB_Globals.h"
#include "PC_NET_PROG.h"
#include "SMBErrors.h"
#include "Cracker.h"
#include "CriticalSection.h"
#include "ShareInfo.h"
#include "FileServer.h"
#include "ConnectionManager.h"
//
// Init global variables defined in Cracker.h
ce::list<SMB_PACKET *, CRACKER_PACKETS_ALLOC> Cracker::g_PacketsToDelayCrack;
CRITICAL_SECTION Cracker::g_csCrackLock;
HANDLE Cracker::g_hStopEvent = NULL;
HANDLE Cracker::g_hCrackDelaySem = NULL;
HANDLE Cracker::g_hCrackerDelayThread = NULL;
const UINT Cracker::g_uiMaxPacketsInQueue = 100;
BOOL Cracker::g_fIsRunning = FALSE;
#ifdef DEBUG
CRITICAL_SECTION Cracker::g_csPerfLock;
DOUBLE Cracker::g_dblPerfAvePacketTime[0xFF];
DWORD Cracker::g_dwPerfPacketsProcessed[0xFF];
#endif
//
// Forward Declared fn's()
extern HRESULT CloseConnectionTransport(ULONG ulConnectionID);
HRESULT
StopCracker() {
HRESULT hr = E_FAIL;
//
// If the cracker isnt running just return failure
if(FALSE == Cracker::g_fIsRunning) {
TRACEMSG(ZONE_DETAIL, (L"CRACKER: not running, so stopping doesnt do anything"));
return S_OK;
}
//
// First things first set a stop event
if(0 == SetEvent(Cracker::g_hStopEvent)) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV-CRACKER: setting stop event FAILED!!"));
ASSERT(FALSE);
hr = E_FAIL;
goto Done;
}
//
// Wait for the delay write thread to terminate
if(WAIT_FAILED == WaitForSingleObject(Cracker::g_hCrackerDelayThread, INFINITE)) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV-CRACKER: error waiting for cracker thread to exit!! (%d)", GetLastError()));
ASSERT(FALSE);
}
//
// Delete our cracking pool
ASSERT(SMB_Globals::g_pCrackingPool);
if(SMB_Globals::g_pCrackingPool) {
delete SMB_Globals::g_pCrackingPool;
SMB_Globals::g_pCrackingPool = NULL;
}
#ifdef DEBUG
{for(UINT i=0; i<0xFF; i++) {
if(0 != Cracker::g_dwPerfPacketsProcessed[i]) {
TRACEMSG(ZONE_STATS, (L"SMBSRV-CRACKER: Perf for packet (0x%x -- %10s) -- %d calls ave time %d", i, GetCMDName(i) ,Cracker::g_dwPerfPacketsProcessed[i], (UINT)Cracker::g_dblPerfAvePacketTime[i]));
}
}
DeleteCriticalSection(&Cracker::g_csPerfLock);
}
#endif
//
// Clean up handles and critical sections
CloseHandle(Cracker::g_hStopEvent);
Cracker::g_hStopEvent = NULL;
DeleteCriticalSection(&Cracker::g_csCrackLock);
hr = S_OK;
Done:
if(SUCCEEDED(hr)) {
Cracker::g_fIsRunning = FALSE;
}
return hr;
}
HRESULT
StartCracker() {
HRESULT hr = E_FAIL;
WORD wErr = 0;
//
// If the cracker is running just return okay
if(TRUE == Cracker::g_fIsRunning) {
ASSERT(FALSE);
TRACEMSG(ZONE_DETAIL, (L"CRACKER: is already running, so starting dosent do anything"));
return E_FAIL;
}
//
// Init our critical section
InitializeCriticalSection(&(Cracker::g_csCrackLock));
//
// Create a thread pool for packets
if(NULL == SMB_Globals::g_pCrackingPool) {
if(!(SMB_Globals::g_pCrackingPool = new SVSThreadPool(SMB_Globals::g_uiMaxCrackingThreads))) {
hr = E_UNEXPECTED;
goto Done;
}
if(NULL == (SMB_Globals::g_CrackingSem = CreateSemaphore(NULL, SMB_Globals::g_uiMaxCrackingThreads, SMB_Globals::g_uiMaxCrackingThreads, NULL))) {
hr = E_OUTOFMEMORY;
goto Done;
}
}
//
// Init data to pre-processing state (so if error we can cleanup)
//
// NOTE: these all should be null (or else we have leaked something)
ASSERT(NULL == Cracker::g_hStopEvent);
Cracker::g_hStopEvent = NULL;
Cracker::g_hCrackerDelayThread = NULL;
Cracker::g_hCrackDelaySem = NULL;
Cracker::g_hStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if(NULL == Cracker::g_hStopEvent) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV-CRACKER: cant create stop event!"));
ASSERT(FALSE);
hr = E_UNEXPECTED;
goto Done;
}
#ifdef DEBUG
//
// Init perf measurements
{
for(UINT i=0; i<0xFF; i++) {
Cracker::g_dblPerfAvePacketTime[i] = 0;
Cracker::g_dwPerfPacketsProcessed[i] = 0;
}
InitializeCriticalSection(&Cracker::g_csPerfLock);
}
#endif
//
// Init our delay semaphore the # in the semaphore represents the # of packets in the delay queue
Cracker::g_hCrackDelaySem = CreateSemaphore(NULL, 0, Cracker::g_uiMaxPacketsInQueue, NULL);
if(NULL == Cracker::g_hCrackDelaySem) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV-CRACKER: cant create delay semaphore!"));
ASSERT(FALSE);
hr = E_UNEXPECTED;
goto Done;
}
if(NULL == (Cracker::g_hCrackerDelayThread = CreateThread(NULL, 0, Cracker::SMBSRVR_CrackerDelayThread, 0, CREATE_SUSPENDED, NULL))) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV-CRACKER: cant make cracker delay thread"));
ASSERT(FALSE);
hr = E_FAIL;
goto Done;
}
TRACEMSG(ZONE_ERROR, (L"SMBSRV-CRACKER: cracker delay thread created 0x%x", (UINT)Cracker::g_hCrackerDelayThread));
hr = S_OK;
Done:
if(FAILED(hr)) {
if(SMB_Globals::g_pCrackingPool)
delete SMB_Globals::g_pCrackingPool;
if(Cracker::g_hStopEvent)
CloseHandle(Cracker::g_hStopEvent);
if(SMB_Globals::g_CrackingSem)
CloseHandle(SMB_Globals::g_CrackingSem);
SMB_Globals::g_pCrackingPool = NULL;
Cracker::g_hStopEvent = NULL;
SMB_Globals::g_CrackingSem = NULL;
} else {
//
// Everything went okay, set the running flag
Cracker::g_fIsRunning = TRUE;
}
if(NULL != Cracker::g_hCrackerDelayThread) {
ResumeThread(Cracker::g_hCrackerDelayThread);
}
return hr;
}
DWORD Cracker::SMBSRVR_CrackerDelayThread(LPVOID unused)
{
HANDLE hWaitEvents[2];
HRESULT hr;
ce::list<SMB_PACKET *, CRACKER_PACKETS_ALLOC> OrderedDelayList;
ce::list<SMB_PACKET *, CRACKER_PACKETS_ALLOC >::iterator it;
DWORD dwSleepTime = INFINITE;
//
// If the stop events are nulled (invalid) we cant run! just exit with failure
if(NULL == Cracker::g_hStopEvent || NULL == Cracker::g_hCrackDelaySem) {
ASSERT(FALSE);
hr = E_FAIL;
goto Done;
}
//
/// This thread does the following:
//
// 1. Waits for one of these 3 things:
// a. timeout (meaning a packet is ready to go)
// b. a new packet (at which time it will be inserted in order of delay on the ORderedDelayList)
// c. shutdown
// 2. When it wakes up for:
// a. timeout -- the first packet will be sent, and the timer will be set for the next
// closest value
// b. a new packet comes in, it will be inserted in order and the timer will be set
// to be what it should for the next newest packet
// c. shutdown -- we just exit
hWaitEvents[0] = Cracker::g_hStopEvent;
hWaitEvents[1] = Cracker::g_hCrackDelaySem;
for(;;) {
SMB_PACKET *pSMB = NULL;
ce::list<SMB_PACKET *, CRACKER_PACKETS_ALLOC >::iterator itDelayAdjVar;
//
// Wait for either a packet to come in, or for a STOP event
DWORD dwStartAsleepAt = GetTickCount();
DWORD dwStopAsleepFor;
DWORD dwRet = WaitForMultipleObjects(2, hWaitEvents, FALSE, dwSleepTime);
if(dwRet == WAIT_TIMEOUT) {
if(0 != OrderedDelayList.size()) {
//
// Get the first node off the list
pSMB = OrderedDelayList.front();
OrderedDelayList.pop_front();
//
// Send the packet to its transport
hr = pSMB->pfnQueueFunction(pSMB, TRUE);
ASSERT(SUCCEEDED(hr));
} else {
ASSERT(FALSE);
}
}
else if(1 == dwRet - WAIT_OBJECT_0) {
//
// Get an SMB from the queue (we know there is one since we were woken up)
LockCracker();
ASSERT(0 != Cracker::g_PacketsToDelayCrack.size());
pSMB = Cracker::g_PacketsToDelayCrack.front();
TRACEMSG(ZONE_DETAIL, (L"SMBSRV: Delay Cracker has packet: %x", (UINT)pSMB));
Cracker::g_PacketsToDelayCrack.pop_front();
ASSERT(NULL != pSMB);
UnlockCracker();
//
// 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;
}
}
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -