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


/******************************************************************************\ 
 
	Vanquish Utils - 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 "Utils.h" 
#include <time.h> 
 
//VRT mutex 
LPCWSTR VRTLOG_MUTEX = L"xfr6frbvu"; 
 
//the log 
LPCWSTR VANQUISH_LOG = L"c:\\vsqb.log"; 
 
//buffer for log 
LPSTR lpVRTLogBuffer = NULL; 
LPSTR lpVRTAppName = NULL; 
LPSTR lpVRTLogDate = NULL; 
 
const DWORD VRTLOGBUFFER_SZ = 1024; 
const DWORD VRTAPPNAME_SZ = 256; 
const DWORD VRTLOGDATE_SZ = 128; 
const DWORD VRTHEAP_DEFAULT = 81920; //twenty pages; should that be enough? 
const DWORD VRTSKIP_CEXESYNC = 0xffffffff; 
const DWORD STACKINFO_SZ = 1024; 
 
//old exception filter 
LPTOP_LEVEL_EXCEPTION_FILTER lpOldTLEF; 
 
extern HMODULE hVanquishModule; //in Vanquish_dll.cpp or Autoloader.cpp 
 
HANDLE hHeap, hMutexVRT; 
 
///////////////////////////////LOG FUNCTIONS//////////////////////////////////// 
 
void __cdecl VRTWriteLog(BOOL bWinError, DWORD dwError, HMODULE hModule, LPCSTR lpFmt, ...) 
{ 
	LPSTR lpWinError = NULL; 
	va_list vaList; 
 
	//process sync so that there is only one log write at a time in the system 
	if (dwError != VRTSKIP_CEXESYNC) VRTCommonExecutionBegin(); 
 
	//get current date&&time 
	GetTimeFormatA(LOCALE_NEUTRAL, LOCALE_NOUSEROVERRIDE, NULL, NULL, lpVRTLogDate, VRTLOGDATE_SZ); 
	VRTWriteLogLOWLEVEL("\r\nApplication: %s\r\nTime: %s\r\n", lpVRTAppName, lpVRTLogDate); 
	GetDateFormatA(LOCALE_NEUTRAL, LOCALE_NOUSEROVERRIDE, NULL, NULL, lpVRTLogDate, VRTLOGDATE_SZ); 
	VRTWriteLogLOWLEVEL("Date: %s\r\n", lpVRTLogDate); 
 
	//get the win error message 
	if (bWinError && dwError) 
	{ 
		// | FORMAT_MESSAGE_FROM_HMODULE 
		FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, (hModule == NULL) ? NULL : hModule, dwError, 0, (LPSTR)&lpWinError, 0, NULL); 
		//VRTWriteLogLOWLEVEL("0x%08x: %s", dwError, (lpWinError == NULL) ? "???" : lpWinError); 
		LocalFree(lpWinError); 
	} 
 
	//write it 
	va_start(vaList, lpFmt); 
	VRTvWriteLogLOWLEVEL(lpFmt, vaList); 
	va_end(vaList); 
 
	//release the sync system (other DLLs can write now!) 
	if (dwError != VRTSKIP_CEXESYNC) VRTCommonExecutionEnd(); 
} 
 
void __cdecl VRTvWriteLogLOWLEVEL(LPCSTR lpFmt, va_list vaList) 
{ 
	HANDLE hFile; 
	DWORD dwSize, dwActual; 
	SECURITY_ATTRIBUTES sa; 
	SECURITY_DESCRIPTOR sd; 
 
	//printf to buffer 
	dwSize = wvsprintfA(lpVRTLogBuffer, lpFmt, vaList); 
 
	//init security shit 
	InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION); 
	sa.nLength = sizeof(SECURITY_ATTRIBUTES); 
	sa.bInheritHandle = FALSE; 
	sa.lpSecurityDescriptor = &sd; 
 
	//open file 
	hFile = CreateFileW(VANQUISH_LOG, GENERIC_WRITE, FILE_SHARE_READ, &sa, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH, NULL); 
	if (!hFile) return; //quit silently; (no c:\ access) 
 
	//append 
	SetFilePointer(hFile, 0, NULL, FILE_END); 
 
	//write data 
	WriteFile(hFile, lpVRTLogBuffer, dwSize, &dwActual, NULL); 
 
	//FlushFileBuffers(hFile); 
	CloseHandle(hFile); 
} 
 
void __cdecl VRTWriteLogLOWLEVEL(LPCSTR lpFmt, ...) 
{ 
	HANDLE hFile; 
	DWORD dwSize, dwActual; 
	SECURITY_ATTRIBUTES sa; 
	SECURITY_DESCRIPTOR sd; 
	va_list vaList; 
 
	//printf to buffer 
	va_start(vaList, lpFmt); 
	dwSize = wvsprintfA(lpVRTLogBuffer, lpFmt, vaList); 
	va_end(vaList); 
 
	//init security shit 
	InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION); 
	sa.nLength = sizeof(SECURITY_ATTRIBUTES); 
	sa.bInheritHandle = FALSE; 
	sa.lpSecurityDescriptor = &sd; 
 
	//open file 
	hFile = CreateFileW(VANQUISH_LOG, GENERIC_WRITE, FILE_SHARE_READ, &sa, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH, NULL); 
	if (!hFile) return; //quit silently; (no c:\ access) 
 
	//append 
	SetFilePointer(hFile, 0, NULL, FILE_END); 
 
	//write data 
	WriteFile(hFile, lpVRTLogBuffer, dwSize, &dwActual, NULL); 
 
	//FlushFileBuffers(hFile); 
	CloseHandle(hFile); 
} 
 
LONG WINAPI VRTExceptionFilter(LPEXCEPTION_POINTERS lpEp) 
{ 
	//determine first if it is our fault or not 
	BOOL bUs = FALSE; 
	DWORD dwAddr = 0; 
    LPDWORD pFrame, pPrevFrame; 
	MEMORY_BASIC_INFORMATION mbi; 
	LPSTR lpStackInfo; 
	LPVOID lpMemory; 
 
	lpMemory = VRTAlloc(STACKINFO_SZ); 
	if (!lpMemory) 
		goto notus; //do default exception handling 
	lpStackInfo = (LPSTR)lpMemory; 
	lpStackInfo[0] = 0; //empty string 
 
	//let's parse the stack... 
	dwAddr = lpEp->ContextRecord->Eip; 
    pFrame = (LPDWORD)lpEp->ContextRecord->Ebp; 
 
	for(;;) 
	{ 
		CHAR szModule[MAX_PATH]; 
 
		if (!VirtualQuery((LPCVOID)dwAddr, &mbi, sizeof(MEMORY_BASIC_INFORMATION))) 
			goto notus; //cannot determine if it is our fault 
 
		if (!GetModuleFileName((HMODULE)mbi.AllocationBase, szModule, MAX_PATH)) 
			lpStackInfo += wsprintf(lpStackInfo, "???[0x%08x]: 0x%08x\r\n", szModule, (DWORD)mbi.AllocationBase, dwAddr); 
		else 
		{ 
			bUs = TRUE; 
			lpStackInfo += wsprintf(lpStackInfo, "%s[0x%08x]: 0x%08x\r\n", szModule, (DWORD)mbi.AllocationBase, dwAddr); 
		} 
 
		dwAddr = pFrame[1]; 
		pPrevFrame = pFrame; 
		pFrame = (LPDWORD)pFrame[0]; //precede to next higher frame on stack 
         
		//frame pointer is always aligned 
		if ((DWORD)pFrame & 3) break; 
 
		//we are going backwards through stack => up in memory, not down 
		if (pFrame <= pPrevFrame) break; 
 
		//check if we can read two DWORDs 
        if (IsBadReadPtr(pFrame, sizeof(DWORD) << 1)) break; 
	} 
 
notus: 
	bUs = FALSE; 
	if (bUs) 
	{ 
		//write info to log 
		VRTWriteLog( 
			FALSE, 0, NULL, 
			"exception! Plzz forward this information to the author.\r\n" 
			"Base: [censored] * Exception Adress: [censored]\r\n" 
			"EAX: [censored]  EBX: [censored]  ECX: [censored]  EDX: [censored]\r\nESI: [censored]  EDI: [censored]\r\n" 
			"EBP: [censored]  ESP: [censored] EIP: [censored]\r\n" 
			"[censored]\r\n" 
			"%s\r\n", 
			(DWORD)hVanquishModule, 
			(DWORD)lpEp->ExceptionRecord->ExceptionAddress, 
			lpEp->ContextRecord->Eax, 
			lpEp->ContextRecord->Ebx, 
			lpEp->ContextRecord->Ecx, 
			lpEp->ContextRecord->Edx, 
			lpEp->ContextRecord->Esi, 
			lpEp->ContextRecord->Edi, 
			lpEp->ContextRecord->Ebp, 
			lpEp->ContextRecord->Esp, 
			lpEp->ContextRecord->Eip, 
			lpMemory 
		); 
 
		if (lpMemory) VRTFree(lpMemory); 
		return EXCEPTION_EXECUTE_HANDLER; //probably will terminate 
	} 
	else 
	{ 
		if (lpMemory) VRTFree(lpMemory); 
		if (lpOldTLEF) 
			return lpOldTLEF(lpEp); 
		else 
			return EXCEPTION_CONTINUE_SEARCH; 
	} 
} 
 
///////////////////////////////VRT FUNCTIONS//////////////////////////////////// 
 
VOID VRTInit() 
{ 
	SECURITY_ATTRIBUTES sa; 
	SECURITY_DESCRIPTOR sd; 
 
	//setup heap 
	hHeap = HeapCreate(0, VRTHEAP_DEFAULT, 0); 
	if (!HeapValidate(hHeap, 0, NULL)) 
	{ 
		//MessageBox(NULL, "Whoops! Your computer will now crash...", "BAU!", MB_OK); 
		ExitProcess(0); //cannot validate/create any heap 
	} 
 
	//setup some space for logs 
	lpVRTLogBuffer = (LPSTR)VRTAlloc(VRTLOGBUFFER_SZ); 
	lpVRTAppName = (LPSTR)VRTAlloc(VRTAPPNAME_SZ); 
	lpVRTLogDate = (LPSTR)VRTAlloc(VRTLOGDATE_SZ); 
 
	//fail hard 
	if (!(lpVRTLogBuffer && lpVRTAppName && lpVRTLogDate)) 
	{ 
		//MessageBox(NULL, "Whoops! Your computer will now crash (no log)...", "BAU!", MB_OK); 
		ExitProcess(0); 
	} 
 
	//exception handling 
	lpOldTLEF = SetUnhandledExceptionFilter(VRTExceptionFilter); 
 
	//get app name 
	GetModuleFileNameA(NULL, lpVRTAppName, VRTAPPNAME_SZ); 
 
	//init security shit 
	InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION); 
	sa.nLength = sizeof(SECURITY_ATTRIBUTES); 
	sa.bInheritHandle = FALSE; 
	sa.lpSecurityDescriptor = &sd; 
 
	//process/thread sync 
	/*FRIGGIN'MUTEX -- Some strange things happen under SP2 here ;) (let me know if someone fixes this) 
	hMutexVRT = CreateMutexW(&sa, FALSE, VRTLOG_MUTEX); 
	if (hMutexVRT == NULL) 
	{ 
		VRTWriteLog(FALSE, 0, NULL, "Fatal: Cannot initialize VRT process synchronization.\r\n"); 
		ExitProcess(0); 
	} 
	*/ 
} 
 
VOID VRTDeInit() 
{ 
	//close handles 
	/*FRIGGIN'MUTEX 
	CloseHandle(hMutexVRT); 
	*/ 
 
	//destroy log buffers 
	VRTFree(lpVRTLogDate); 
	VRTFree(lpVRTAppName); 
	VRTFree(lpVRTLogBuffer); 
 
	//exception handling; restore OLD 
	SetUnhandledExceptionFilter(lpOldTLEF); 
 
	//bye bye heap 
	HeapDestroy(hHeap); 
} 
 
LPVOID VRTAlloc(DWORD dwSize) 
{ 
	//allocate heap 
	return HeapAlloc(hHeap, 0, dwSize); 
} 
 
LPVOID VRTReAlloc(LPVOID lpOldMem, DWORD dwSize) 
{ 
	//reallocate heap; check if valid first 
	if (HeapValidate(hHeap, 0, lpOldMem)) 
		return HeapReAlloc(hHeap, 0, lpOldMem, dwSize); 
	else 
	{ 
	//	VRTWriteLog(FALSE, 0, NULL, "Tried to realloc an invalid memory block.\r\n"); 
		return NULL; 
	} 
} 
 
VOID VRTFree(LPVOID lpMem) 
{ 
	//free heap 
	if (HeapValidate(hHeap, 0, lpMem)) 
		HeapFree(hHeap, 0, lpMem); 
	else; 
		//VRTWriteLog(FALSE, 0, NULL, "Tried to free an invalid memory block.\r\n"); 
} 
 
LPVOID VRTCopyMemory(LPVOID dst, LPCVOID src, DWORD count) 
{ 
	//dirty copy memory algorithm 
	LPVOID ret = dst; 
 
	while (count--) 
	{ 
		*(char *)dst = *(char *)src; 
		dst = (char *)dst + 1; 
		src = (char *)src + 1; 
	} 
 
	return ret; 
} 
 
LPVOID VRTFillMemory(LPVOID dst, DWORD count, BYTE fill) 
{ 
	//dirty fill memory algorithm 
	void *start = dst; 
 
	while (count--) 
	{ 
		*(char *)dst = (char)fill; 
		dst = (char *)dst + 1; 
	} 
 
	return start; 
} 
 
VOID VRTCommonExecutionBegin() 
{ 
/*FRIGGIN'MUTEX 
	//common execution subsystem 
	DWORD dwWaitR; 
 
	dwWaitR = WaitForSingleObject(hMutexVRT, WAITTIMEOUT); 
	if (dwWaitR == WAIT_FAILED) 
	{ 
		VRTWriteLog(FALSE, VRTSKIP_CEXESYNC, NULL, "VRT wait synchronization failed.\r\n"); 
	} 
*/ 
} 
 
VOID VRTCommonExecutionEnd() 
{ 
/*FRIGGIN'MUTEX 
	//common execution subsystem 
	if (!ReleaseMutex(hMutexVRT)) 
	{ 
		VRTWriteLog(FALSE, VRTSKIP_CEXESYNC, NULL, "VRT release synchronization failed.\r\n"); 
	} 
*/ 
}