Пример #1
0
VOID CProcessControl::UnInitialize() {
	ADD_LOG();
	if (m_hExitEvent!= NULL) SetEvent(m_hExitEvent);

	if (m_hThread != NULL) {
		if (WaitForSingleObject(m_hThread, 5000) == WAIT_TIMEOUT) 
			TerminateProcess(m_hThread, -1);

		CLOSE_HANDLE(m_hThread);
	}
	if (m_hExitEvent!= NULL) ResetEvent(m_hExitEvent);
	CLOSE_HANDLE(m_hExitEvent);

	int nsum = m_pTransformData->m_pWatchData->size();
	for (int i = 0; i < nsum; i++)
	{
		PWATCH_PROCESS_INFORMATION pwatch = m_pTransformData->m_pWatchData->at(i);
		if (pwatch->proinfo.hProcess != NULL) {
			::EnumWindows((WNDENUMPROC)EnumClosePro, (LPARAM)pwatch->proinfo.dwProcessId);
			if (WaitForSingleObject(pwatch->proinfo.hProcess, 5000) == WAIT_TIMEOUT) {
				TerminateProcess(pwatch->proinfo.hProcess, -1);
				
			}
		}
	}
	FreeWatchData();
	
}
Пример #2
0
BOOL CProcessControl::IsRunningWatchThread(BOOL bwatch) {
	ADD_LOG();
	if (bwatch) {
		ADD_WORSELOG_CONTAINER(m_pTransformData->m_pWatchData);
		if (m_pTransformData->m_pWatchData->size() <= 0) return FALSE;
		if (m_hThread != NULL) {
			::SetEvent(m_hExitEvent);
			if (WaitForSingleObject(m_hThread, 5000) == WAIT_TIMEOUT)
				TerminateThread(m_hThread, -1);
			CLOSE_HANDLE(m_hThread);
			::ResetEvent(m_hExitEvent);
		}
		m_hThread = ::CreateThread(NULL, 0,
			(LPTHREAD_START_ROUTINE)WatchThread, this, NULL, 0);
	}
	else {
		if (m_hThread != NULL) {
			::SetEvent(m_hExitEvent);
			if (WaitForSingleObject(m_hThread, 5000) == WAIT_TIMEOUT)
				TerminateThread(m_hThread, -1);
			CLOSE_HANDLE(m_hThread);
			::ResetEvent(m_hExitEvent);
		}
		
	}
	return TRUE;
}
Пример #3
0
    VOID Server::Stop_Helper(VOID)
    {        
        printf("Stop_Helper: Server\n");

        eState_ = STATE::stopping;

        StopMainThread();

        for (DWORD counter = 0; counter < S_PIPES_INSTANCES; counter++ ) 
        {
            DisconnectNamedPipe(Pipe_[counter].hPipeInst);

            CLOSE_HANDLE(Pipe_[counter].hPipeInst);
        }

        for (DWORD counter = 0; counter < S_PIPES_EVENTS; counter++ )
        {
            CLOSE_HANDLE(hPipes_Events_[counter]);
        }

        for (DWORD counter = 0; counter < S_EVENTS_; counter++ )
        {
            CLOSE_HANDLE(hS_Events_[counter]); 
        }

        CLOSE_HANDLE(hServerIsUp_Mutex);

        DeleteCriticalSection(&csReadPipe_);
        for (DWORD counter = 0; counter < S_PIPES_INSTANCES; counter++)
        {        
            DeleteCriticalSection(&Pipe_[counter].csWritePipe);
        }  

        eState_ = STATE::stopped;
    }
Пример #4
0
void CTransformData::freeallwatchdata() {
	int n = m_pWatchData->size();
	assert(n > -1);
	for (int i = 0; i < n; i++) {
		CLOSE_HANDLE(m_pWatchData->at(i)->proinfo.hProcess);
		CLOSE_HANDLE(m_pWatchData->at(i)->proinfo.hThread);
	}
	freedata<WATCH_PROCESS_INFORMATION>(m_pWatchData);
}
Пример #5
0
void CDbController::CloseDbHandler( void )
{
	if( m_hIocp )
	{
		::PostQueuedCompletionStatus( m_hIocp, 0, NULL, NULL );
		::WaitForSingleObject( m_hDbHndlr, INFINITE );
		CLOSE_HANDLE( m_hIocp );
		CLOSE_HANDLE( m_hDbHndlr );
	}
}
Пример #6
0
bool ComputeHash_FromFile(const int hashType, const TCHAR *const fileName, TCHAR *const hashOut, const size_t hashOutSize)
{
	const size_t hashSize = GetHashSize(hashType);
	if((hashSize == SIZE_MAX) || (hashSize >= (hashOutSize / 2)))
	{
		if(hashSize != SIZE_MAX) ERROR_MSG(T("Output buffer is too small to hold the hash value!"));
		return false;
	}

	HANDLE h = CreateFile(fileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
	if(!VALID_HANDLE(h))
	{
		ERROR_MSG(T("Failed to open input file for reading!"));
		return false;
	}

	hash_ctx ctx;
	if(!HashFunction_Init(hashType, &ctx))
	{
		CLOSE_HANDLE(h);
		return false;
	}

	static const DWORD BUFF_SIZE = 4096;
	BYTE buffer[BUFF_SIZE];

	for(;;)
	{
		DWORD nBytesRead = 0;
		if(!ReadFile(h, buffer, BUFF_SIZE, &nBytesRead, NULL))
		{
			ERROR_MSG(T("Failed to read data from input file!"));
			CLOSE_HANDLE(h);
			return false;
		}
		if(nBytesRead < 1)
		{
			CLOSE_HANDLE(h);
			break;
		}
		HashFunction_Update(&ctx, buffer, nBytesRead);
	}

	BYTE hashValue[128];
	HashFunction_Final(&ctx, hashValue);
	ConvertHashToHex(hashSize, hashValue, hashOut);
	return true;
}
Пример #7
0
void CProcessControl::RunWatchThread() {
	while (true)
	{
		Sleep(100);
		m_cSection.Lock();
		int nsum = m_pTransformData->m_pWatchData->size();
		for (int i = 0; i < nsum; i++) {

			PWATCH_PROCESS_INFORMATION pwatch = m_pTransformData->m_pWatchData->at(i);
			if (m_bIsWatchProcess) {
				if (!IsProcessExit(i) || pwatch->proinfo.dwProcessId == 0) {
					ADD_LOG_TIPS("can not find watching process, and recreate it");
					CLOSE_HANDLE(pwatch->proinfo.hProcess);
					CreateProcessList(i);
				}
			}
			else {
				if (pwatch->nstatus == RUN) {
					if (!IsProcessExit(i)) {
						ADD_CHECKLOG_TIPS("a abnormal process, changeing it status");
						pwatch->nstatus = EXIT;
						if (m_hWnd) ::PostMessage(m_hWnd, WM_UPDATEWATCHLIST, NULL, NULL);
					}
				}
			}
		}

		m_cSection.Unlock();
		if (WaitForSingleObject(m_hExitEvent, 1000) == WAIT_OBJECT_0)
		{
			break;
		}
	}
}
Пример #8
0
    VOID Client::Stop_Helper(VOID)
    {        
        printf("Stop_Helper: Client\n");        

        eState_ = STATE::stopping;
    
        StopMainThread();

        CLOSE_HANDLE(hPipe_);
        CLOSE_HANDLE(hC_Event_Stop_Server_); 

        DeleteCriticalSection(&csPipe_Write_);
        DeleteCriticalSection(&csPipe_Read_);

        eState_ = STATE::stopped;
    }
Пример #9
0
CDbManager::~CDbManager()
{
	for( int i = 0; i < DEFAULT_DB_WORKER_THREAD_NUM; i++ )
	{
		PostQueuedCompletionStatus( m_hIOCP[i], 0, NULL, NULL );
		CLOSE_HANDLE( m_hIOCP[i] );
	}

	WaitForMultipleObjects( DEFAULT_DB_WORKER_THREAD_NUM, m_hDbWorkerThreadTerminate, TRUE, INFINITE );

	for( i = 0; i < DEFAULT_DB_WORKER_THREAD_NUM; i++ ) {
		CLOSE_HANDLE( m_hDbWorkerThreadTerminate[i] );
	}

	SAFE_DELETE( m_pDbIOData );
}
Пример #10
0
VOID CProcessControl::CloseAllProcess() {
	if (m_hExitEvent!= NULL) SetEvent(m_hExitEvent);

	if (m_hThread != NULL) {
		if (WaitForSingleObject(m_hThread, 5000) == WAIT_TIMEOUT) 
			TerminateProcess(m_hThread, -1);

		CLOSE_HANDLE(m_hThread);
	}
	if (m_hExitEvent!= NULL) ResetEvent(m_hExitEvent);
	CLOSE_HANDLE(m_hExitEvent);

	HANDLE h = ::CreateThread(NULL, 0,
		(LPTHREAD_START_ROUTINE)CloseProcessThread, (LPVOID)this, NULL, 0);
	CLOSE_HANDLE(h);

}
Пример #11
0
VOID CProcessControl::ReCreateEstablishThread() {
	ADD_LOG();
	UnInitialize();

	HANDLE h = ::CreateThread(NULL, 0,
		(LPTHREAD_START_ROUTINE)EstablishThread, (LPVOID)this, NULL, 0);
	CLOSE_HANDLE(h);
}
Пример #12
0
void Thumbnail::start(void)
{
    CLOSE_HANDLE(mEvent);

    mEvent = ::CreateEvent(XPR_NULL, XPR_TRUE, XPR_FALSE, XPR_NULL);

    xpr_rcode_t sRcode = mThread.start(dynamic_cast<xpr::Thread::Runnable *>(this));
}
/*
 * The main service routine, which we use to connect a named pipe server before finishing.
 */
VOID elevator_serviceproc( DWORD argc, LPSTR * argv )
{
	DWORD dwResult              = ERROR_SUCCESS;
	HANDLE hPipe                = NULL;
	char cServicePipe[MAX_PATH] = {0};
	DWORD dwBytes               = 0;
	BYTE bByte                  = 0;

	do
	{

		hStatus = RegisterServiceCtrlHandler( lpServiceName, (LPHANDLER_FUNCTION)elevator_servicectrl );
		if( !hStatus )
			BREAK_ON_ERROR( "[ELAVATOR-NAMEDPIPE] elevator_service_proc. RegisterServiceCtrlHandler failed" );
		  
		status.dwServiceType             = SERVICE_WIN32_OWN_PROCESS; 
		status.dwServiceSpecificExitCode = 0;
		
		elevator_servicestatus( SERVICE_RUNNING, NO_ERROR, 0 );

		_snprintf( cServicePipe, MAX_PATH, "\\\\.\\pipe\\%s", lpServiceName );

		while( TRUE )
		{
			hPipe = CreateFileA( cServicePipe, GENERIC_ALL, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
			if( hPipe )
			{
				if( WriteFile( hPipe, &bByte, 1, &dwBytes, NULL ) )
					break;

				CLOSE_HANDLE( hPipe );
			}

			Sleep( 50 );
		}

	} while( 0 );

	CLOSE_HANDLE( hPipe );

	dwElevateStatus = dwResult;

	elevator_servicestatus( SERVICE_STOPPED, NO_ERROR, 0 );
	
	SetEvent( hTerminate );
}
Пример #14
0
int TThreadLock::Destroy() {
#ifdef SYSTEM_WIN
	CLOSE_HANDLE(m_hMutex);
#else
	if (0 != pthread_mutex_destroy(&m_hMutex))
		return -1;
#endif
	return 0;
}
Пример #15
0
static __forceinline void doLockFile(HANDLE &fileHandle, const QString &filePath, QFile *const outFile)
{
	bool success = false;
	fileHandle = INVALID_HANDLE_VALUE;

	//Try to open the file!
	for(int i = 0; i < 64; i++)
	{
		const HANDLE hTemp = CreateFileW(MUTILS_WCHR(QDir::toNativeSeparators(filePath)), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL);
		if(VALID_HANDLE(hTemp))
		{
			PROTECT_HANDLE(fileHandle = hTemp, true);
			break; /*file opened successfully*/
		}
		if(i == 0)
		{
			qWarning("Failed to open file on first attemp, retrying...");
		}
		Sleep(1);
	}
	
	//Now try to actually lock the file!
	if (VALID_HANDLE(fileHandle))
	{
		for (int i = 0; i < 64; i++)
		{
			LARGE_INTEGER fileSize;
			if (GetFileSizeEx(fileHandle, &fileSize))
			{
				OVERLAPPED overlapped = { 0U, 0U, 0U, 0U, 0U };
				if (LockFileEx(fileHandle, LOCKFILE_FAIL_IMMEDIATELY, 0, fileSize.LowPart, fileSize.HighPart, &overlapped))
				{
					success = true;
					break; /*file locked successfully*/
				}
				Sleep(1);
			}
			if (i == 0)
			{
				qWarning("Failed to lock file on first attemp, retrying...");
			}
		}
	}

	//Locked successfully?
	if(!success)
	{
		CLOSE_HANDLE(fileHandle);
		if(outFile)
		{
			QFile::remove(QFileInfo(*outFile).canonicalFilePath());
		}
		MUTILS_THROW_FMT("File '%s' could not be locked!", MUTILS_UTF8(QFileInfo(filePath).fileName()));
	}
}
Пример #16
0
 VOID Server::StopMainThread()
 {
     if (hMainThread_ != NULL)
     {
         SetEvent(hPipes_Events_[S_PIPES_EVENTS - 1]);    
         WaitForSingleObject(hMainThread_,  INFINITE);
 
         CLOSE_HANDLE(hMainThread_);            
         nMainThreadId_ = NULL;
     }
 }
Пример #17
0
void Thumbnail::destroy(void)
{
    stop();

    clearAysncImage();

    CLOSE_HANDLE(mEvent);

    XPR_SAFE_DELETE(mThumbImgList);

    mIdMgr = 0;
}
Пример #18
0
/*
 * Create and run a VNC server on this socket.
 */
DWORD vncdll_run( AGENT_CTX * lpAgentContext )
{
	DWORD dwResult      = ERROR_SUCCESS;
	VSocketSystem * vsocketsystem = NULL;
	vncServer * vserver = NULL;
	HDESK desk          = NULL;
	WSADATA WSAData     = {0};
	SOCKET sock         = 0;
	BYTE bFlags         = 0;

	do
	{
		dprintf( "[VNCDLL] vncdll_run. Started..." );

		if( !lpAgentContext )
			BREAK_WITH_ERROR( "[VNCDLL] vncdll_run. invalid parameters", ERROR_INVALID_PARAMETER );
		
		hMessageMutex = CreateMutex( NULL, FALSE, NULL );

		desk = vncdll_getinputdesktop( TRUE );
		
		vncdll_unlockwindowstation();

		if( !lpAgentContext->bDisableCourtesyShell )
			vncdll_courtesyshell( desk );

		vsocketsystem = new VSocketSystem();
		if( !vsocketsystem->Initialised() )
			BREAK_WITH_ERROR( "[VNCDLL] vncdll_run. VSocketSystem Initialised failed", ERROR_NETWORK_ACCESS_DENIED );

		vserver = new vncServer();

		vncClientId cid = vserver->AddClient( lpAgentContext );

		dprintf( "[VNCDLL-0x%08X] vncdll_run. Going into wait state... cid=%d", hAppInstance, cid );
	
		WaitForSingleObject( lpAgentContext->hCloseEvent, INFINITE );
		
		vserver->RemoveClient( cid );

	} while( 0 );

	dprintf( "[VNCDLL-0x%08X] vncdll_run. terminating...", hAppInstance );

	delete vserver;

	delete vsocketsystem;

	CLOSE_HANDLE( hMessageMutex );

	return 0;
}
Пример #19
0
VOID CProcessControl::CloseNProcess(INT nIndex) {
	ADD_LOG();
	m_cSection.Lock();
	PWATCH_PROCESS_INFORMATION pWatch =  m_pTransformData->m_pWatchData->at(nIndex);
	::EnumWindows((WNDENUMPROC)EnumClosePro, (LPARAM)pWatch->proinfo.dwProcessId);
	GetWatchData(nIndex)->nstatus = EXIT;
	m_cSection.Unlock();
	if (WaitForSingleObject(pWatch->proinfo.hProcess, 5000) == WAIT_TIMEOUT) {
		TerminateProcess(pWatch->proinfo.hProcess, -1);
		
	}
	CLOSE_HANDLE(pWatch->proinfo.hProcess);
}
Пример #20
0
    BOOL Client::WatchOverServer(VOID)
    {
        BOOL watch_over_server_result = false;

        HANDLE watch_over_server_mutex_handle = CreateMutexA(NULL, FALSE,  SERVER_IS_WORKING_MUTEX_GUID);  
        if (( watch_over_server_mutex_handle != NULL ) && (GetLastError() != ERROR_ALREADY_EXISTS))
        { 
            watch_over_server_result = true;
        }

        CLOSE_HANDLE(watch_over_server_mutex_handle);

        return watch_over_server_result;
    }
Пример #21
0
BOOL CProcessControl::FreeWatchData() {
	IsRunningWatchThread(FALSE);

	if (m_pTransformData->m_pWatchData == NULL) return FALSE;
	int n = m_pTransformData->m_pWatchData->size();
	if (n <= 0) return FALSE;

	for (int i = 0; i < n; i++) {
		PWATCH_PROCESS_INFORMATION pwatch = m_pTransformData->m_pWatchData->at(i);
		CLOSE_HANDLE((pwatch->proinfo).hProcess);
	}
	m_pTransformData->freeallwatchdata();
	return TRUE;
}
Пример #22
0
    VOID Client::StopMainThread(VOID)
    {
        if (hMainThread_ != NULL)
        {
            do {

                DWORD res = PostThreadMessage(nMainThreadId_,  WM_QUIT, 0, 0); 
                DWORD error = GetLastError();  

            } while (WAIT_TIMEOUT == WaitForSingleObject(hMainThread_,  0));
            // В WaitForSingleObject не используем INFINITE, т.к. возможен вариант:
            // "Maybe the thread doesn't have a message queue.
            // A thread can create a message queue for itself
            // by calling GetMessage or PeekMessage, for example."
            // TODO: Решить.

            CLOSE_HANDLE(hMainThread_);
            nMainThreadId_ = NULL;
        }
    }
Пример #23
0
static __forceinline void doValidateHash(HANDLE &fileHandle, const int &fileDescriptor, const QByteArray &expectedHash, const QString &filePath)
{
	QFile checkFile;

	//Now re-open the file for reading
	if(g_useFileDescrForQFile)
	{
		checkFile.open(fileDescriptor, QIODevice::ReadOnly);
	}
	else
	{
		checkFile.setFileName(filePath);
		for(int i = 0; i < 64; i++)
		{
			if(checkFile.open(QIODevice::ReadOnly)) break;
			if(!i) qWarning("Failed to re-open file on first attemp, retrying...");
			Sleep(100);
		}
	}

	//Opened successfully
	if((!checkFile.isOpen()) || checkFile.peek(1).isEmpty())
	{
		QFile::remove(filePath);
		MUTILS_THROW_FMT("File '%s' could not be read!", MUTILS_UTF8(QFileInfo(filePath).fileName()));
	}

	//Verify file contents
	const QByteArray hash = FileHash::computeHash(checkFile);
	checkFile.close();

	//Compare hashes
	if(hash.isNull() || _stricmp(hash.constData(), expectedHash.constData()))
	{
		qWarning("\nFile checksum error:\n A = %s\n B = %s\n", expectedHash.constData(), hash.constData());
		CLOSE_HANDLE(fileHandle);
		QFile::remove(filePath);
		MUTILS_THROW_FMT("File '%s' is corruputed, take care!", MUTILS_UTF8(QFileInfo(filePath).fileName()));
	}
}
Пример #24
0
/*
 * A post injection hook called after our dll has been injected into a process.
 */
DWORD loader_inject_post( DWORD dwPid, HANDLE hProcess, DWORD dwInjectResult )
{
	do
	{
		// if we have successfully injected, run the io thread and return
		if( dwInjectResult == ERROR_SUCCESS )
		{
			// we only want the agent to do the RFB initilization once (for the remote viewer)
			if( AgentContext.bInit )
				AgentContext.bInit = FALSE;
			break;
		}

		// but if injection failed close the process handle
		CLOSE_HANDLE( hProcess );

		loader_agent_close();

	} while( 0 );

	return dwInjectResult;
}
Пример #25
0
/*
 * Enable or disable a privilege in our processes current token.
 */
BOOL elevate_priv( char * cpPrivilege, BOOL bEnable )
{
	DWORD dwResult        = ERROR_SUCCESS;
	HANDLE hToken         = NULL;
	TOKEN_PRIVILEGES priv = {0};

	do
	{
		if( !cpPrivilege )
			BREAK_WITH_ERROR( "[ELEVATE] elevate_priv. invalid arguments", ERROR_BAD_ARGUMENTS );

		if( !OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken ) )
			BREAK_ON_ERROR( "[ELEVATE] elevate_priv. OpenProcessToken failed" );
		
		priv.PrivilegeCount = 1;

		if( bEnable )
			priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
		else
			priv.Privileges[0].Attributes = SE_PRIVILEGE_REMOVED;

		if( !LookupPrivilegeValue( NULL, cpPrivilege, &priv.Privileges[0].Luid ) )
			BREAK_ON_ERROR( "[ELEVATE] elevate_priv. LookupPrivilegeValue failed" );

		if( !AdjustTokenPrivileges( hToken, FALSE, &priv, 0, NULL, NULL ) )
			BREAK_ON_ERROR( "[ELEVATE] elevate_priv. AdjustTokenPrivileges failed" );

	} while( 0 );
	
	CLOSE_HANDLE( hToken );

	SetLastError( dwResult );

	if( dwResult == ERROR_SUCCESS )
		return TRUE;

	return FALSE;
}
Пример #26
0
/*
 * Send a buffer to a named pipe server.
 */
DWORD screenshot_send( char * cpNamedPipe, BYTE * pJpegBuffer, DWORD dwJpegSize )
{
	DWORD dwResult  = ERROR_ACCESS_DENIED;
	HANDLE hPipe    = NULL;
	DWORD dwWritten = 0;
	DWORD dwTotal   = 0;

	do
	{
		hPipe = CreateFileA( cpNamedPipe, GENERIC_ALL, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
		if( !hPipe )
			BREAK_ON_ERROR( "[SCREENSHOT] screenshot_send. CreateFileA failed" );
		
		if( !WriteFile( hPipe, (LPCVOID)&dwJpegSize, sizeof(DWORD), &dwWritten, NULL ) )
			BREAK_ON_ERROR( "[SCREENSHOT] screenshot_send. WriteFile JPEG length failed" );
		
		if( !dwJpegSize || !pJpegBuffer )
			BREAK_WITH_ERROR( "[SCREENSHOT] screenshot_send. No JPEG to transmit.", ERROR_BAD_LENGTH );

		while( dwTotal < dwJpegSize )
		{
			if( !WriteFile( hPipe, (LPCVOID)(pJpegBuffer + dwTotal), (dwJpegSize - dwTotal), &dwWritten, NULL ) )
				break;
			dwTotal += dwWritten;
		}

		if( dwTotal != dwJpegSize )
			BREAK_WITH_ERROR( "[SCREENSHOT] screenshot_send. dwTotal != dwJpegSize", ERROR_BAD_LENGTH );

		dwResult = ERROR_SUCCESS;

	} while( 0 );

	CLOSE_HANDLE( hPipe );

	return dwResult;
}
/*
 * Elevate a pipe server by allowing it to impersonate us.
 */
BOOL elevator_namedpipeservice( char * cpServiceName )
{
	DWORD dwResult                      = ERROR_SUCCESS;
	SERVICE_TABLE_ENTRY servicetable[2] = {0};

	do
	{
		if( !cpServiceName )
			BREAK_WITH_ERROR( "[ELEVATOR-NAMEDPIPE] elevator_pipe. cpServiceName == NULL", ERROR_INVALID_HANDLE );
		
		lpServiceName = _strdup( cpServiceName );
	
		hTerminate = CreateEvent( 0, TRUE, FALSE, 0 );
		if( !hTerminate )
			BREAK_ON_ERROR( "[ELAVATOR-NAMEDPIPE] elevator_service_proc. CreateEvent hTerminate failed" );

		servicetable[0].lpServiceName = lpServiceName;
		servicetable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTIONA)elevator_serviceproc;

		servicetable[1].lpServiceName = NULL;
		servicetable[1].lpServiceProc = NULL;

		if( !StartServiceCtrlDispatcher( servicetable ) )
			BREAK_ON_ERROR( "[ELEVATOR-NAMEDPIPE] elevator_pipe. StartServiceCtrlDispatcher failed" );

		if( WaitForSingleObject( hTerminate, INFINITE ) != WAIT_OBJECT_0 )
			BREAK_ON_ERROR( "[ELEVATOR-NAMEDPIPE] elevator_pipe. WaitForSingleObject failed" );

		dwResult = dwElevateStatus;

	} while( 0 );
	
	CLOSE_HANDLE( hTerminate );

	return dwResult;
}
Пример #28
0
/*
 * Entry Point.
 */
DWORD Init( SOCKET s )
{
	DWORD dwResult              = ERROR_SUCCESS;
	BOOL bTerminate             = FALSE;
	HANDLE hMessageThread       = NULL;
	DLL_BUFFER VncDllBuffer     = {0};  
	char cCommandLine[MAX_PATH] = {0};
	DWORD dwHostSessionId       = 0;
	DWORD dwActiveSessionId     = 0;
	DWORD dwAgentSessionId      = 0xFFFFFFFF;
	BYTE bFlags                 = 0;

	__try
	{
		do
		{
			// We maintain state for the rfb stream so as not to desynchronize the remote
			// client after session switching and the injection of multiple agents server side.
			context_init();

			sock = s;
			if( sock == INVALID_SOCKET )
				BREAK_WITH_ERROR( "[LOADER] Init. INVALID_SOCKET", ERROR_INVALID_PARAMETER );
			
			if( recv( sock, (char *)&bFlags, 1, 0 ) == SOCKET_ERROR )
				BREAK_ON_WSAERROR( "[LOADER] Init. recv bFlags failed" );

			if( bFlags & VNCFLAG_DISABLECOURTESYSHELL )
				AgentContext.bDisableCourtesyShell = TRUE;

			if( bFlags & VNCFLAG_DISABLESESSIONTRACKING )
				bDisableSessionTracking = TRUE;

			dprintf( "[LOADER] Init. Starting, hAppInstance=0x%08X, sock=%d, bFlags=%d", hAppInstance, sock, bFlags );

			// get the vnc dll we will inject into the active session
			if( loader_vncdll( &VncDllBuffer ) != ERROR_SUCCESS )
				BREAK_ON_ERROR( "[LOADER] Init. loader_vncdll failed" );

			// create a socket event and have it signaled on FD_CLOSE
			hSocketCloseEvent = WSACreateEvent();
			if( hSocketCloseEvent == WSA_INVALID_EVENT )
				BREAK_ON_WSAERROR( "[LOADER] Init. WSACreateEvent failed" );

			if( WSAEventSelect( sock, hSocketCloseEvent, FD_CLOSE ) == SOCKET_ERROR )
				BREAK_ON_WSAERROR( "[LOADER] Init. WSAEventSelect failed" );

			// get the session id that our host process belongs to
			dwHostSessionId = session_id( GetCurrentProcessId() );

			hMessageThread = CreateThread( NULL, 0, context_message_thread, NULL, 0, NULL );
			if( !hMessageThread )
				BREAK_ON_ERROR( "[LOADER] Init. CreateThread context_message_thread failed" );

			// loop untill the remote client closes the connection, creating a vnc
			// server agent inside the active session upon the active session changing
			while( !bTerminate )
			{
				// in case we have been waiting for a session to attach to the physical  
				// console and the remote client has quit, we detect this here...
				if( WaitForSingleObject( hSocketCloseEvent, 0 ) == WAIT_OBJECT_0 )
				{
					dprintf( "[LOADER] Init. Remote socket closed, terminating1..." );
					break;
				}

				// get the session id for the interactive session
				dwActiveSessionId = session_activeid();
			
				// test if there is no session currently attached to the physical console...
				if( dwActiveSessionId == 0xFFFFFFFF )
				{
					dprintf( "[LOADER] Init. no session currently attached to the physical console..." );
					// just try to wait it out...
					Sleep( 250 );
					continue;
				}
				else if( dwActiveSessionId == dwAgentSessionId )
				{
					dprintf( "[LOADER] Init. dwActiveSessionId == dwAgentSessionId..." );
					// just try to wait it out...
					Sleep( 250 );
					continue;
				}

				// do the local process or session injection
				if( dwHostSessionId != dwActiveSessionId )
				{
					dprintf( "[LOADER] Init. Injecting into active session %d...", dwActiveSessionId );
					if( session_inject( dwActiveSessionId, &VncDllBuffer ) != ERROR_SUCCESS )
						BREAK_WITH_ERROR( "[LOADER] Init. session_inject failed", ERROR_ACCESS_DENIED );
				}
				else
				{
					dprintf( "[LOADER] Init. Allready in the active session %d.", dwActiveSessionId );
					if( ps_inject( GetCurrentProcessId(), &VncDllBuffer ) != ERROR_SUCCESS  )
						BREAK_WITH_ERROR( "[LOADER] Init. ps_inject current process failed", ERROR_ACCESS_DENIED );
				}
				
				dwAgentSessionId = dwActiveSessionId;

				// loop, waiting for either the agents process to die, the remote socket to die or
				// the active session to change...
				while( TRUE )
				{
					HANDLE hEvents[2]  = {0};
					DWORD dwWaitResult = 0;

					// wait for these event to be signaled or a timeout to occur...
					hEvents[0]   = hSocketCloseEvent;
					hEvents[1]   = hAgentProcess;
					dwWaitResult = WaitForMultipleObjects( 2, (HANDLE *)&hEvents, FALSE, 250 );
					
					// bail if we have somehow failed (e.g. invalid handle)
					if( dwWaitResult == WAIT_FAILED )
					{
						dprintf( "[LOADER] Init. WaitForMultipleObjects failed." );
						// if we cant synchronize we bail out...
						bTerminate = TRUE;
						break;
					}
					// if we have just timedout, test the current active session...
					else if( dwWaitResult == WAIT_TIMEOUT )
					{
						// if the agent is still in the active session just continue...
						if( dwAgentSessionId == session_activeid() )
							continue;
						// if we are not to perform session tracking try and stay in the current session (as it might become the active input session at a later stage)
						if( bDisableSessionTracking )
						{
							dprintf( "[LOADER] Init. Active session has changed, trying to stay in current session as session tracking disabled..." );
							Sleep( 500 );
							continue;
						}
						// if the agent is no longer in the active session we signal the agent to terminate
						if( !ReleaseMutex( hAgentCloseEvent ) )
							dprintf( "[LOADER] Init. ReleaseMutex 1 hAgentCloseEvent failed. error=%d", GetLastError() );							
						dprintf( "[LOADER] Init. Active session has changed. Moving agent into new session..." );
						dwAgentSessionId = 0xFFFFFFFF;
						// and we go inject a new agent into the new active session (or terminate if session tracking disabled)
						loader_agent_close();
						break;
					}
					// sanity check the result for an abandoned mutex
					else if( (dwWaitResult >= WAIT_ABANDONED_0) && (dwWaitResult <= (WAIT_ABANDONED_0 + 1)) )
					{
						dprintf( "[LOADER] Init. WAIT_ABANDONED_0 for %d", dwWaitResult - WAIT_ABANDONED_0 );
						bTerminate = TRUE;
						break;
					}
					else
					{
						// otherwise if we have an event signaled, handle it
						switch( dwWaitResult - WAIT_OBJECT_0 )
						{
							case 0:
								dprintf( "[LOADER] Init. Remote socket closed, terminating2..." );
								bTerminate = TRUE;
								if( !ReleaseMutex( hAgentCloseEvent ) )
									dprintf( "[LOADER] Init. ReleaseMutex 2 hAgentCloseEvent failed. error=%d", GetLastError() );
								ReleaseMutex( hAgentCloseEvent );
								break;
							case 1:
								dprintf( "[LOADER] Init. Injected agent's process has terminated..." );
								loader_agent_close();
								dwAgentSessionId = 0xFFFFFFFF;
								break;
							default:
								dprintf( "[LOADER] Init. WaitForMultipleObjects returned dwWaitResult=0x%08X", dwWaitResult );
								bTerminate = TRUE;
								if( !ReleaseMutex( hAgentCloseEvent ) )
									dprintf( "[LOADER] Init. ReleaseMutex 3 hAgentCloseEvent failed. error=%d", GetLastError() );
								break;
						}
					}

					// get out of this loop...
					break;
				}

			}

		} while( 0 );
	
		CLOSE_HANDLE( hSocketCloseEvent );

		loader_agent_close();

		closesocket( sock );

		if( hMessageThread )
			TerminateThread( hMessageThread, 0 );
	}
	__except( EXCEPTION_EXECUTE_HANDLER )
	{
		dprintf( "[LOADER] Init. EXCEPTION_EXECUTE_HANDLER\n\n" );
	}

	dprintf( "[LOADER] Init. Finished." );

	return dwResult;
}
Пример #29
0
/*
 * Close the various global handles we created for the agent..
 */
VOID loader_agent_close( VOID )
{
	CLOSE_HANDLE( hAgentCloseEvent );
	CLOSE_HANDLE( hAgentProcess );
}
Пример #30
0
/*
 * A pre injection hook called before our dll has been injected into a process.
 */
DWORD loader_inject_pre( DWORD dwPid, HANDLE hProcess, char * cpCommandLine )
{
	DWORD dwResult               = ERROR_SUCCESS;
	LPVOID lpMemory              = NULL;
	AGENT_CTX RemoteAgentContext = {0};
	int i                        = 0;

	do
	{
		if( !hProcess || !cpCommandLine )
			BREAK_WITH_ERROR( "[LOADER] loader_inject_pre. !hProcess || !cpCommandLine", ERROR_INVALID_PARAMETER );

		// Use User32!WaitForInputIdle to slow things down so if it's a new
		// process (like a new winlogon.exe) it can have a chance to initilize...
		// Bad things happen if we inject into an uninitilized process.
		WaitForInputIdle( hProcess, 10000 );

		CLOSE_HANDLE( hAgentCloseEvent );
		CLOSE_HANDLE( hAgentProcess );

		memcpy( &RemoteAgentContext, &AgentContext, sizeof(AGENT_CTX) );

		hAgentCloseEvent = CreateMutex( NULL, TRUE, NULL );
		if( !hAgentCloseEvent )
			BREAK_ON_ERROR( "[LOADER] loader_inject_pre. CreateEvent hAgentCloseEvent failed" );

		if( !DuplicateHandle( GetCurrentProcess(), hAgentCloseEvent, hProcess, &RemoteAgentContext.hCloseEvent, 0, FALSE, DUPLICATE_SAME_ACCESS ) )
			BREAK_ON_ERROR( "[LOADER] loader_inject_pre. DuplicateHandle hAgentCloseEvent failed" )
		
		dprintf( "[LOADER] WSADuplicateSocket for sock=%d", sock );

		// Duplicate the socket for the target process
		if( WSADuplicateSocket( sock, dwPid, &RemoteAgentContext.info ) != NO_ERROR )
			BREAK_ON_WSAERROR( "[LOADER] WSADuplicateSocket failed" )
	
		// Allocate memory for the migrate stub, context and payload
		lpMemory = VirtualAllocEx( hProcess, NULL, sizeof(AGENT_CTX), MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE );
		if( !lpMemory )
			BREAK_ON_ERROR( "[LOADER] VirtualAllocEx failed" )
		
		/*for( i=0 ; i<4 ; i++ )
		{
			DWORD dwSize = 0;

			if( !AgentContext.dictionaries[i] )
				continue;
			
			dwSize = ( sizeof(DICTMSG) + AgentContext.dictionaries[i]->dwDictLength );

			RemoteAgentContext.dictionaries[i] = VirtualAllocEx( hProcess, NULL, dwSize, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE );
			if( !RemoteAgentContext.dictionaries[i] )
				continue;

			if( !WriteProcessMemory( hProcess, RemoteAgentContext.dictionaries[i], AgentContext.dictionaries[i], dwSize, NULL ) )
				RemoteAgentContext.dictionaries[i] = NULL;
		}*/

		// Write the ctx to memory...
		if( !WriteProcessMemory( hProcess, lpMemory, &RemoteAgentContext, sizeof(AGENT_CTX), NULL ) )
			BREAK_ON_ERROR( "[MIGRATE] WriteProcessMemory 1 failed" )

		hAgentProcess = hProcess;

		_snprintf( cpCommandLine, COMMANDLINE_LENGTH, "/v /c:0x%08X", lpMemory );

	} while( 0 );

	if( dwResult != ERROR_SUCCESS )
	{
		dprintf( "[LOADER] loader_inject_pre. CLOSE_HANDLE( hAgentCloseEvent );" );
		CLOSE_HANDLE( hAgentCloseEvent );
	}

	return dwResult;
}