All pastes #974973 Raw Edit

LauncherDLL.c

public cpp v1 · immutable
·published 2008-04-07 05:46 UTC
rendered paste body
#include <Windows.h>#ifndef _DEBUG#define DLLNAME "CellAOLauncher.dll"#else#define DLLNAME "CellAOLauncher.dbg.dll"#endif#define FUNCOM_KEY_PUBLIC		"9c32cc23d559ca90fc31be72df817d0e124769e809f936bc14360ff4bed758f260a0d596584eacbbc2b88bdd410416163e11dbf62173393fbc0c6fefb2d855f1a03dec8e9f105bbad91b3437d8eb73fe2f44159597aa4053cf788d2f9d7012fb8d7c4ce3876f7d6cd5d0c31754f4cd96166708641958de54a6def5657b9f2e92"#define FUNCOM_KEY_PRIME		"eca2e8c85d863dcdc26a429a71a9815ad052f6139669dd659f98ae159d313d13c6bf2838e10a69b6478b64a24bd054ba8248e8fa778703b418408249440b2c1edd28853e240d8a7e49540b76d120d3b1ad2878b1b99490eb4a2a5e84caa8a91cecbdb1aa7c816e8be343246f80c637abc653b893fd91686cf8d32d6cfe5f2a6f"#define FUNCOM_KEY_GENERATOR	"5"// The Private Key here is for reference purposes only#define CELLAO_KEY_PRIVATE		"7ad852c6494f664e8df21446285ecd6f400cf20e1d872ee96136d7744887424b"#define CELLAO_KEY_PUBLIC		"26b5a3b4ac1177f24a2d9de44bafef477ff23ef1cb5f646919b1be26516053030b65d5afb60cef6f49de539958ba0b7922a099319b8016a8673cb27a696ae4b60fdece25ddcdad42e7f0056b87fc35687fe033b242e17e960d79806fd46c4a79cbc64f558660a50cabc1c242dace70de6af452e3433f97e30e202567f187de70"// We keep the same prime and generator as funcom uses for simplicity sake. Although the launcher does support changing both#define CELLAO_KEY_PRIME		"eca2e8c85d863dcdc26a429a71a9815ad052f6139669dd659f98ae159d313d13c6bf2838e10a69b6478b64a24bd054ba8248e8fa778703b418408249440b2c1edd28853e240d8a7e49540b76d120d3b1ad2878b1b99490eb4a2a5e84caa8a91cecbdb1aa7c816e8be343246f80c637abc653b893fd91686cf8d32d6cfe5f2a6f"#define CELLAO_KEY_GENERATOR	"5"int match(unsigned char *memory, unsigned char *matchone, unsigned char *matchtwo, unsigned long max){	if (IsBadReadPtr(memory, max))		return 0;	/*	 * Yes i know this is hackish, however since the strings are so long it is unlikely	 * that it will fail, and it is faster this way. Also the strings are checked later	 * a second time in findkeys() after this matches it. So there is no risk doing this.	 *         -- NV	 */	while(max--)	{		if ((*memory != *matchone) && (*memory != *matchtwo))			return 0;		matchone++;		matchtwo++;		memory++;	}	return 1;}unsigned long fixprotect(void *ptr, unsigned long size){	MEMORY_BASIC_INFORMATION	mbi;	VirtualQuery(ptr, &mbi, sizeof(mbi));	switch(mbi.Protect & 0xFF)	{		case PAGE_EXECUTE:		case PAGE_EXECUTE_READ:		case PAGE_EXECUTE_READWRITE:		case PAGE_EXECUTE_WRITECOPY:			mbi.Protect = PAGE_EXECUTE_READWRITE;			break;		case PAGE_NOACCESS:		case PAGE_READONLY:		case PAGE_READWRITE:		case PAGE_WRITECOPY:			mbi.Protect = PAGE_READWRITE;			break;	}	VirtualProtect(ptr, size, mbi.Protect, &mbi.Protect);	return mbi.Protect;}void findkeys(unsigned char *base, unsigned long size){	unsigned char	*ptr;	unsigned long	remaining;	unsigned long	oldprotect;	ptr = base;	remaining = size;	while (remaining >= min(sizeof(FUNCOM_KEY_PUBLIC), sizeof(FUNCOM_KEY_PRIME)))	{		if (match(ptr, FUNCOM_KEY_PUBLIC, FUNCOM_KEY_PRIME, min(sizeof(FUNCOM_KEY_PUBLIC), sizeof(FUNCOM_KEY_PRIME))))		{			if (!memcmp(ptr, FUNCOM_KEY_PUBLIC, sizeof(FUNCOM_KEY_PUBLIC)))			{				oldprotect = fixprotect(ptr, sizeof(CELLAO_KEY_PUBLIC));				memcpy(ptr, CELLAO_KEY_PUBLIC, sizeof(CELLAO_KEY_PUBLIC));				VirtualProtect(ptr, sizeof(FUNCOM_KEY_PUBLIC), oldprotect, &oldprotect);				ptr += sizeof(FUNCOM_KEY_PUBLIC) - 1;				remaining -= sizeof(FUNCOM_KEY_PUBLIC) - 1;			} else if (!memcmp(ptr, FUNCOM_KEY_PRIME, sizeof(FUNCOM_KEY_PRIME)))			{				oldprotect = fixprotect(ptr, sizeof(FUNCOM_KEY_PRIME));				memcpy(ptr, CELLAO_KEY_PRIME, sizeof(CELLAO_KEY_PRIME));				VirtualProtect(ptr, sizeof(FUNCOM_KEY_PRIME), oldprotect, &oldprotect);				ptr += sizeof(FUNCOM_KEY_PRIME) - 1;				remaining -= sizeof(FUNCOM_KEY_PRIME) - 1;			} else			{				MessageBox(0, "Danger, Will Robinson.\nThis should not happen!", "CellAO Launcher", MB_ICONEXCLAMATION);					ExitProcess(0);			}		}		ptr++;		remaining--;	}}BOOL WINAPI execv_Hook(const char *cmdname, const char *const *argv){	STARTUPINFO			si;	PROCESS_INFORMATION	pi;	HANDLE				hKernel;	void				*dllname;	char				*buffer;	memset(&si, 0, sizeof(si));	si.cb = sizeof(si);	buffer = malloc(1024);	strcpy_s(buffer, 1024, *argv++);	while(*argv != NULL)	{		strcat_s(buffer, 1024, " ");		strcat_s(buffer, 1024, *argv);		argv++;	}	if (!CreateProcess(cmdname, buffer, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi))	{		MessageBox(0, "Failed to load Client.exe!", "CellAO Launcher", MB_ICONEXCLAMATION);		ExitProcess(1);	}	hKernel = GetModuleHandle("Kernel32.dll");	dllname = VirtualAllocEx(pi.hProcess, NULL, sizeof(DLLNAME), MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);	WriteProcessMemory(pi.hProcess, dllname, DLLNAME, sizeof(DLLNAME), NULL);	if (CreateRemoteThread(pi.hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)GetProcAddress(hKernel, "LoadLibraryA"), dllname, 0, NULL) == NULL)	{		MessageBox(0, "Failed to create remote thread in Client.exe.\nPlease check Anti-Virus software/etc that could be preventing this", "CellAO Launcher", MB_ICONEXCLAMATION);	}	CloseHandle(hKernel);	ResumeThread(pi.hThread);	CloseHandle(pi.hProcess);	CloseHandle(pi.hThread);	free(buffer);	ExitProcess(0);	return 0;}void InstallHook(){	void						*hModule;	PIMAGE_DOS_HEADER			pDosHeader;	PIMAGE_NT_HEADERS			pNTHeaders;	PIMAGE_IMPORT_DESCRIPTOR	pImportDescriptor;	PIMAGE_THUNK_DATA			pThunkData;	void						*origexecv;	hModule = LoadLibrary("msvcr71.dll");	origexecv = GetProcAddress(hModule, "_execv");	pDosHeader = (void*)GetModuleHandle(NULL);	if( IsBadReadPtr(pDosHeader, sizeof(IMAGE_DOS_HEADER)))		return;	if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)		return;	pNTHeaders = (PIMAGE_NT_HEADERS)((unsigned long)pDosHeader + (unsigned long)pDosHeader->e_lfanew);	if (IsBadReadPtr(pNTHeaders, sizeof(IMAGE_NT_HEADERS)))		return;	if (pNTHeaders->Signature != IMAGE_NT_SIGNATURE)		return;	pImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)((unsigned long)pDosHeader + (unsigned long)(pNTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress));	if (pImportDescriptor == (PIMAGE_IMPORT_DESCRIPTOR)pNTHeaders)            return;	while(pImportDescriptor->Name)	{		if (!_stricmp((char*)pDosHeader + pImportDescriptor->Name, "msvcr71.dll"))		{			// Found msvcr71.dll Thunks			pThunkData = (PIMAGE_THUNK_DATA)((unsigned long)pDosHeader + (unsigned long)pImportDescriptor->FirstThunk);			while(pThunkData->u1.Function)			{				if((unsigned long)pThunkData->u1.Function == (unsigned long)origexecv)				{					unsigned long oldprotect;					oldprotect = fixprotect(&pThunkData->u1.Function, 4);					pThunkData->u1.Function = (unsigned long)execv_Hook;					VirtualProtect(&pThunkData->u1.Function, 4, oldprotect, &oldprotect);					break;				}				pThunkData++;			}			break;		}		pImportDescriptor++;	}}BOOL APIENTRY DllMain(HINSTANCE hModule, DWORD dwReason, PVOID lpReserved){	switch(dwReason)	{		case DLL_PROCESS_ATTACH:		{			SYSTEM_INFO					si;			MEMORY_BASIC_INFORMATION	mbi;			void						*current;			GetSystemInfo(&si);			current = si.lpMinimumApplicationAddress;			while (current < si.lpMaximumApplicationAddress)			{				VirtualQuery(current, &mbi, sizeof(mbi));				current = mbi.BaseAddress;				if ((mbi.State & MEM_COMMIT) && (mbi.Type & MEM_IMAGE))				{					findkeys(current, mbi.RegionSize);				}				current = (void*)((unsigned long)current + mbi.RegionSize);			}			InstallHook();			break;		}		case DLL_PROCESS_DETACH:			break;	}	return TRUE;}