예제 #1
0
//////////////////////////////////////////////////////////////////////
// ServerStart()
// -------------------------------------------------------------------
// Responsible for setting up the server.
//////////////////////////////////////////////////////////////////////
BOOL PRIVATE ServerStart(HANDLE hModule)
{
	// Temporary string
	LPSTR t=NULL; 

	//////////////////////////////////////////////////////////////////
	// Before anything else, create the global structures we use in 
	// the hack. Make sure we delete these in ServerStop.
	//////////////////////////////////////////////////////////////////
	si =	new SERVERINFO;
	psi =	new PRIVATESERVERINFO;
	fep =	new FUNCTIONENTRYPOINTS;
	pfep=	new PRIVATEFUNCTIONENTRYPOINTS;

	thisgame=new THISGAMESTRUCT;
	thisgame->player=NULL;

	//////////////////////////////////////////////////////////////////
	// Force-load needed dll's so we can patch thei'r memory space.
	// We should unload these is ServerStop.
	//////////////////////////////////////////////////////////////////
	for (int i=0; NeededDlls[i] != NULL; i++) LoadLibrary(NeededDlls[i]);

	//////////////////////////////////////////////////////////////////
	// Build initial data of the SERVERINFO structure
	//////////////////////////////////////////////////////////////////
	si->Version=__SERVERVERSION__;

	// Get plugin path
	t=new char[_MAX_PATH];
	if (!GetModuleFileName((HINSTANCE)hModule, t, _MAX_PATH))
		{ MessageBox(NULL, "Unable to get PluginPath!", "D2Hackit Error!", MB_ICONERROR); return FALSE; }
	int p=strlen(t);
	while (p) 
	{
		if (t[p] == '\\')
			{ t[p] = 0; p=0;}
		else
			p--;
	}
	si->PluginDirectory=new char[strlen(t)+1];
	strcpy((LPSTR)si->PluginDirectory, t);

	psi->DontShowErrors=FALSE;
	//////////////////////////////////////////////////////////////////
	// Build initial data of the PRIVATESERVERINFO structure
	//////////////////////////////////////////////////////////////////
	sprintf(t, "%s\\D2HackIt.ini", t);
	psi->IniFile=new char[strlen(t)+1];
	strcpy((LPSTR)psi->IniFile, t);
	delete t;
	

	/* This block of code is replaced by the single GetCurrentProcessId()
	   call below.  This works because DLL initialization is performed
	   within the context of the process to which the DLL is attaching -
	   i.e. under that process's PID

	// Get Diablo II's hwnd
	psi->hwnd = FindWindow("Diablo II", "Diablo II");	// Get hwnd
		if (!psi->hwnd) { MessageBox(NULL, "Can't get Diablo II's window handle.", "D2Hackit Error!", MB_ICONERROR); return FALSE; }
	
	// Get Diablo II's pid & Process handle


	GetWindowThreadProcessId(psi->hwnd, &psi->pid);
	*/

    // Get the process ID and the process handle
	psi->pid = GetCurrentProcessId();
	psi->hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, psi->pid);
		if (!psi->hProcess) { MessageBox(NULL, "Can't get Diablo II's process handle.", "D2Hackit Error!", MB_ICONERROR); return FALSE;}


	// Get build date/time
	strcpy(psi->BuildDate, __DATE__);
	strcpy(psi->BuildTime, __TIME__);

	//////////////////////////////////////////////////////////////////
	// Build initial callbacks in the FUNCTIONENTRYPOINTS structure.
	//////////////////////////////////////////////////////////////////
//	fep->GetMemoryAddressFromPattern=&GetMemoryAddressFromPattern;
	fep->GamePrintString=&GamePrintString;
	fep->GamePrintInfo=&GamePrintInfo;
	fep->GamePrintVerbose=&GamePrintVerbose;
	fep->GamePrintError=&GamePrintError;
	fep->GetHackProfileString=&GetHackProfileString;
	fep->GetHackProfileStringEx=&GetHackProfileStringEx;
	fep->GetHackProfileSectionNames=&GetHackProfileSectionNames;
	fep->GameSendMessageToChat=&GameSendMessageToChat;

	//////////////////////////////////////////////////////////////////
	// Build initial callbacks in PRIVATEFUNCTIONENTRYPOINTS 
	//////////////////////////////////////////////////////////////////
	pfep->GetBaseAddress=&GetBaseAddress;
	pfep->GetImageSize=&GetImageSize;

	//////////////////////////////////////////////////////////////////
	// Check if D2HackIi.ini exisits
	//////////////////////////////////////////////////////////////////
	if (_access(psi->IniFile, 0))
	{ 
		LPSTR t=new char[strlen(psi->IniFile)+50];
		sprintf(t, "Unable to open ini-file:\n%s", psi->IniFile);
		MessageBox(NULL, t, "D2Hackit Error!", MB_ICONERROR); 
		delete t;
		return FALSE;
	}

	//////////////////////////////////////////////////////////////////
	// Set default prompts
	//////////////////////////////////////////////////////////////////
	t=fep->GetHackProfileString("D2HackIt", "Misc", "InfoPrompt");
	lstrcpyn(psi->InfoPrompt, (strlen(t)?t:DEFAULTINFOPROMPT),MAXPROMPTLENGTH-1);
	delete t;

	t=fep->GetHackProfileString("D2HackIt", "Misc", "ErrorPrompt");
	lstrcpyn(psi->ErrorPrompt, (strlen(t)?t:DEFAULTERRORPROMPT),MAXPROMPTLENGTH-1);
	delete t;

	t=fep->GetHackProfileString("D2HackIt", "Misc", "VerbosePrompt");
	lstrcpyn(psi->VerbosePrompt, (strlen(t)?t:DEFAULTVERBOSEPROMPT),MAXPROMPTLENGTH-1);
	
	t=fep->GetHackProfileString("D2HackIt", "Misc", "Verbose");
	if (!stricmp(t, "on"))
		psi->Verbose = TRUE;
	else
		psi->Verbose = FALSE;

	delete t;

	//////////////////////////////////////////////////////////////////
	// Start by binding a way to print to screen. This is vital, so if
	// we are unable to do this, exit with an error message!
	//////////////////////////////////////////////////////////////////
	FINGERPRINTSTRUCT fps;
	if(!GetFingerprint("D2HackIt", "GamePrintStringLocation", fps))
		{ MessageBox(NULL, "Fingerprint information for 'GamePrintStringLocation'\nmissing or corrupt!", "D2Hackit Error!", MB_ICONERROR); return FALSE; }
	
	psi->GamePrintStringLocation=fps.AddressFound;
	if (!psi->GamePrintStringLocation)
		{ MessageBox(NULL, "Unable to find entrypoint for 'GamePrintStringLocation'!", "D2Hackit Error!", MB_ICONERROR); return FALSE; }


	// Get playerinfo struct
	if (!GetFingerprint("D2HackIt", "pPlayerInfoStruct", fps)) 
		{ fep->GamePrintError("Fatal error! Exiting!"); return FALSE; }

	// Messy pointers :)
	thisgame->player=(PLAYERINFOSTRUCT*)*(DWORD*)(*(DWORD*)fps.AddressFound);


	// Get gameinfo struct
	if (!GetFingerprint("D2HackIt", "pPlayerInfoStruct", fps)) 
		{ fep->GamePrintError("Fatal error! Exiting!"); return FALSE; }

	// Get GameSendMessageToChat
	psi->GameSendMessageToChatLocation = NULL;
	if(GetFingerprint("D2HackIt", "GameSendMessageToChat", fps))
		psi->GameSendMessageToChatLocation = fps.AddressFound;

	// Messy pointers :)
	//thisgame->CurrentGame=(GAMESTRUCT*)*(DWORD*)(*(DWORD*)fps.AddressFound);
	
	// Initialize critical section
	InitializeCriticalSection(&psi->csData);

	// Initialize insert receive buffers
	psi->nRecvBufferPos = 0;
	
	//////////////////////////////////////////////////////////////////
	// Print startup banner. 
	//////////////////////////////////////////////////////////////////
	t=new char[128];
	sprintf(t, "Starting D2HackIt! Mk2 version %d.%.2d (%s@%s)",
		LOWORD(si->Version), HIWORD(si->Version), psi->BuildDate, psi->BuildTime
		);
		fep->GamePrintInfo(t);

	//////////////////////////////////////////////////////////////////
	// Get loader data
	//////////////////////////////////////////////////////////////////
	BOOL UsingD2Loader=FALSE;
	psi->DontShowErrors=TRUE;
	if (!GetFingerprint("D2HackIt", "LoaderStruct", fps))
	{
		psi->DontShowErrors=FALSE;
		sprintf(fps.ModuleName, "Diablo II.exe");
		UsingD2Loader=TRUE;
		if ((fps.AddressFound=GetMemoryAddressFromPattern(fps.ModuleName, fps.FingerPrint, fps.Offset)) < 0x100)
		{
			sprintf(fps.ModuleName, "D2Loader.exe");
			if ((fps.AddressFound=GetMemoryAddressFromPattern(fps.ModuleName, fps.FingerPrint, fps.Offset)) < 0x100)
			{
				//fep->GamePrintError("Unable to find loader data in 'Game.exe', 'Diablo II.exe' or 'D2Loader.exe'!");
				//fep->GamePrintError("Fatal error! Exiting!"); return FALSE; 
				fps.AddressFound=0;
			}	
		}
	}
	
	psi->loader = (LOADERDATA*)fps.AddressFound;

	if (psi->loader) 
	{
		sprintf(t, "Loader version ÿc4%d.%.2d. ÿc0Game is %sstarted with D2Loader.",
			LOWORD(psi->loader->LoaderVersion), HIWORD(psi->loader->LoaderVersion),
			(UsingD2Loader?"":"ÿc4not ÿc0"));
	} else {
		sprintf(t, "D2Hackit was loaded without loader");
	}
	fep->GamePrintInfo(t);

		
	//////////////////////////////////////////////////////////////////
	// Continue binding entrypoints and intercepts
	//////////////////////////////////////////////////////////////////
	sprintf(t, "Found 'GamePrintStringLocation' at %.8x", psi->GamePrintStringLocation);
	fep->GamePrintVerbose(t);

	/* 
	 * No need for this
	 *
	// Get socket location
	if (!GetFingerprint("D2HackIt", "pGameSocketLocation", fps)) 
		{ fep->GamePrintError("Fatal error! Exiting!"); return FALSE; }
	psi->GameSocketLocation=*(DWORD*)fps.AddressFound;
	*/

	// Get GamePacketReceivedIntercept
	if (!GetFingerprint("D2HackIt", "GamePacketReceivedIntercept", psi->fps.GamePacketReceivedIntercept)) 
		{ fep->GamePrintError("Fatal error! Exiting!"); return FALSE; }

	Intercept(INST_CALL, psi->fps.GamePacketReceivedIntercept.AddressFound, (DWORD)&GamePacketReceivedInterceptSTUB, psi->fps.GamePacketReceivedIntercept.PatchSize);

	// Get GamePacketReceivedIntercept2
	if (!GetFingerprint("D2HackIt", "GamePacketReceivedIntercept2", psi->fps.GamePacketReceivedIntercept2)) 
	{ 
		fep->GamePrintError("Fatal error! Exiting!"); 
		Intercept(INST_CALL, (DWORD)&GamePacketReceivedInterceptSTUB, psi->fps.GamePacketReceivedIntercept.AddressFound, psi->fps.GamePacketReceivedIntercept.PatchSize);
		return FALSE; 
	}
	Intercept(INST_JMP, psi->fps.GamePacketReceivedIntercept2.AddressFound, (DWORD)&GamePacketReceivedIntercept2STUB, psi->fps.GamePacketReceivedIntercept2.PatchSize);

	// Get GamePacketSentIntercept
	if (!GetFingerprint("D2HackIt", "GamePacketSentIntercept", psi->fps.GamePacketSentIntercept)) 
	{ 
		fep->GamePrintError("Fatal error! Exiting!"); 
		Intercept(INST_JMP, (DWORD)&GamePacketReceivedIntercept2STUB, psi->fps.GamePacketReceivedIntercept.AddressFound, psi->fps.GamePacketReceivedIntercept2.PatchSize);
		Intercept(INST_CALL, (DWORD)&GamePacketReceivedInterceptSTUB, psi->fps.GamePacketReceivedIntercept.AddressFound, psi->fps.GamePacketReceivedIntercept.PatchSize);
		return FALSE; 
	}
	Intercept(INST_CALL, psi->fps.GamePacketSentIntercept.AddressFound, (DWORD)&GamePacketSentInterceptSTUB, psi->fps.GamePacketSentIntercept.PatchSize);
	

	// Get GamePlayerInfoIntercept
	if (!GetFingerprint("D2HackIt", "GamePlayerInfoIntercept", psi->fps.GamePlayerInfoIntercept)) 
	{ 
		fep->GamePrintError("Fatal error! Exiting!"); 
		Intercept(INST_CALL, (DWORD)&GamePacketSentInterceptSTUB, psi->fps.GamePacketSentIntercept.AddressFound, psi->fps.GamePacketSentIntercept.PatchSize);
		Intercept(INST_JMP, (DWORD)&GamePacketReceivedIntercept2STUB, psi->fps.GamePacketReceivedIntercept.AddressFound, psi->fps.GamePacketReceivedIntercept2.PatchSize);
		Intercept(INST_CALL, (DWORD)&GamePacketReceivedInterceptSTUB, psi->fps.GamePacketReceivedIntercept.AddressFound, psi->fps.GamePacketReceivedIntercept.PatchSize);
		return FALSE; 
	}
	Intercept(INST_CALL, psi->fps.GamePlayerInfoIntercept.AddressFound, (DWORD)&GamePlayerInfoInterceptSTUB, psi->fps.GamePlayerInfoIntercept.PatchSize);


	// Get GameSendPacketToGameLocation
	// Thanks to TechWarrior
	if (!GetFingerprint("D2HackIt", "GameSendPacketToGameLocation", fps)) 
	{ 
		fep->GamePrintError("Fatal error! Exiting!"); 
		Intercept(INST_CALL, (DWORD)&GamePacketSentInterceptSTUB, psi->fps.GamePacketSentIntercept.AddressFound, psi->fps.GamePacketSentIntercept.PatchSize);
		Intercept(INST_JMP, (DWORD)&GamePacketReceivedIntercept2STUB, psi->fps.GamePacketReceivedIntercept.AddressFound, psi->fps.GamePacketReceivedIntercept2.PatchSize);
		Intercept(INST_CALL, (DWORD)&GamePacketReceivedInterceptSTUB, psi->fps.GamePacketReceivedIntercept.AddressFound, psi->fps.GamePacketReceivedIntercept.PatchSize);
		Intercept(INST_CALL, (DWORD)&GamePlayerInfoInterceptSTUB, psi->fps.GamePlayerInfoIntercept.AddressFound, psi->fps.GamePlayerInfoIntercept.PatchSize);
		return FALSE; 
	}
	psi->GameSendPacketToGameLocation=fps.AddressFound;

	// Start TickThread, We dont care about closing it later.
	// It will be destroyed when unloading the dll.
	DWORD dummy=0;
	psi->TickShutDown = 0;
	psi->TickThreadHandle = CreateThread(NULL,0,TickThread,(void*)&ClientList,0,&dummy);
	psi->TickThreadActive = psi->TickThreadHandle!=NULL;

	// Load any clients listed in Autorun
	t=new char[1024];
	t=fep->GetHackProfileString("D2HackIt", "Misc", "Autoload");

	if (strlen(t))
	{
		char* command[2];
		command[0]=".load";
		char *p;
		p=t;

		command[1] = p;
		while (*p != 0) {
			if (*p == ',') {
				*(p++) = 0;
				GameCommandLineLoad(command,2);
			while (*p == ' ')
						p++;
				if (*p != 0)
					command[1] = p;
			} else
				p++;
		}
		GameCommandLineLoad(command,2);
	}

	delete t;

	fep->GamePrintInfo("D2HackIt! Mk2 Loaded! Type ÿc4.helpÿc0 for help on commands.");
	return TRUE;
}
예제 #2
0
파일: FPS.cpp 프로젝트: Asmodean-/dsfix
//----------------------------------------------------------------------------------------
// Game Patches
//----------------------------------------------------------------------------------------
void applyFPSPatch() {

	SDLOG(0, "Starting FPS unlock...\n");
#ifndef WITHOUT_GFWL_LIB
	SDLOG(0, "Applying GFWL compatibility\n");
	enableGFWLCompatibility();
#endif

	// Get image info
	MODULEINFO moduleInfo;
	PIMAGE_DOS_HEADER dosHeader;
	PIMAGE_NT_HEADERS ntHeader;
    IMAGE_FILE_HEADER header;

	if(GetModuleInformation(GetCurrentProcess(), GetModuleHandle(NULL), &moduleInfo, sizeof(moduleInfo)))
	{
		ImageBase = (DWORD)moduleInfo.lpBaseOfDll;
		SDLOG(0, "ImageBase at 0x%08X\n", ImageBase);

		dosHeader = (PIMAGE_DOS_HEADER)ImageBase;
		ntHeader = (PIMAGE_NT_HEADERS)((DWORD)(dosHeader) + (dosHeader->e_lfanew));
		header = ntHeader->FileHeader;
		DWORD TimeStamp = header.TimeDateStamp;
				SDLOG(0, "Executable timestamp: 0x%08X, config: 0x%08X\n", TimeStamp, EXE_TIMESTAMP);

		// Perform pattern matching if timestamp differs
		if (TimeStamp != EXE_TIMESTAMP) {
			SDLOG(0, "Trying pattern matching...\n");

			DWORD address;
			address = GetMemoryAddressFromPattern(NULL, TS_PATTERN, TS_OFFSET);
			if(address != NULL) {
				SDLOG(0, "ADDR_TS found at 0x%08X\n", address);
				ADDR_TS = address;
			}
			else {
				SDLOG(0, "Could not match ADDR_TS pattern, FPS not unlocked\n");
				return;
			}
			address = GetMemoryAddressFromPattern(NULL, PRESINT_PATTERN, PRESINT_OFFSET);
			if(address != NULL) {
				SDLOG(0, "ADDR_PRESINT found at 0x%08X\n", address);
				ADDR_PRESINT = address;
			}
			else {
				SDLOG(0, "Could not match ADDR_PRESINT pattern, FPS not unlocked\n");
				return;
			}
			address = GetMemoryAddressFromPattern(NULL, GETCMD_PATTERN, GETCMD_OFFSET);
			if(address != NULL) {
				SDLOG(0, "ADDR_GETCMD found at 0x%08X\n", address);
				ADDR_GETCMD = address;
			}
			else {
				SDLOG(0, "Could not match ADDR_GETCMD pattern, FPS not unlocked\n");
				return;
			}
			SDLOG(0, "Pattern matching successful\n");
		}
		else
			SDLOG(0, "Using configured addresses\n");
	}
	else
	{
		SDLOG(0, "GetModuleInformation failed, FPS not unlocked\n");
		return;
	}

	// Init counter for frame-rate calculations
	lastRenderTime = 0.0f;
	QueryPerformanceFrequency(&timerFreq);
	QueryPerformanceCounter(&counterAtStart);

	// Binary patches
	//--------------------------------------------------------------
	DWORD address;
	DWORD data;

	// Override D3D Presentation Interval
	address = convertAddress(ADDR_PRESINT);
	data = 5; //Set to immediate
	writeToAddress(&data, address, sizeof(data));

	// Detour call to getDrawThreadMsgCommand
	address = convertAddress(ADDR_GETCMD);
	DetourApply((BYTE*)address, (BYTE*)getDrawThreadMsgCommand, 5, CALLOP);
		
	SDLOG(0, "FPS unlocked\n");
}
예제 #3
0
//////////////////////////////////////////////////////////////////////
// GetFingerPrint
// -------------------------------------------------------------------
// Reads szFingerPrintName from the [FingerprintData] section of the
// ini-file asociated with szHackName.
// 
// It breaks up the components of the string, does some basic sanity-
// check and calls GetMemoryAddressFromPattern() to store the address
// of the fingerprint, if found.
//////////////////////////////////////////////////////////////////////
BOOL EXPORT GetFingerprint(LPCSTR szHackName, LPCSTR szFingerprintName, FINGERPRINTSTRUCT &fps)
{
	LPSTR szReturnString;
	sprintf(fps.Name, szFingerprintName);
	fps.AddressFound=0;

	int i;
	int nFields=0;
	char *t;
	szReturnString=fep->GetHackProfileString(szHackName, "FingerprintData", szFingerprintName);
	

	// No such fingerprint!
	if (!strlen(szReturnString))
	{ 
		t=new char[256];
		sprintf(t, "Can't find fingerprint for '%s' in '%s.ini'",
			szFingerprintName, szHackName);
		fep->GamePrintError(t);
		delete t, szReturnString; 
		return FALSE;
	}


	// Make sure we have 4 fields
	for (i=0; szReturnString[i]; i++)
		if (szReturnString[i] == ',')
			nFields++;

	if (nFields != 3)
	{ 
		t=new char[256];
		sprintf(t, "Fingerprint for '%s' in '%s.ini' is corrupt.",
			szFingerprintName, szHackName);
		fep->GamePrintError(t);
		delete t, szReturnString; 
		return FALSE;
	}


	// Loop backwards to get fingerprint info
	for (;i!=0;i--)
	{
		if (szReturnString[i] == ',')
		{
			szReturnString[i] = 0;
			nFields--;
			switch (nFields)
			{
			case 2:
				strcpy(fps.FingerPrint, &szReturnString[i+1]);
				break;
			case 1:
				fps.Offset=atoi(&szReturnString[i+1]);
				break;
			case 0:
				fps.PatchSize=atoi(&szReturnString[i+1]);
				break;
			}
		}
	}
	strcpy(fps.ModuleName, szReturnString);
	delete szReturnString;


	if ((fps.AddressFound=GetMemoryAddressFromPattern(fps.ModuleName, fps.FingerPrint, fps.Offset)) < 0x100)
	{
		if (psi->DontShowErrors)
			return FALSE;

		t=new char[256];
		sprintf(t, "Unable fo find location for '%s'.",
			szFingerprintName, szHackName);
		fep->GamePrintError(t);
		delete t;
		return FALSE;
	} else {
		t=new char[256];
		sprintf(t, "Found '%s' at %.8x",
			szFingerprintName, fps.AddressFound);
		fep->GamePrintVerbose(t);
		delete t;
		return TRUE;
	}
}