示例#1
0
int __stdcall thcrap_plugin_init()
{
	int base_tasofro_removed = stack_remove_if_unneeded("base_tasofro");
	if (base_tasofro_removed == 1) {
		return 1;
	}

	const char *game = json_object_get_string(runconfig_get(), "game");
	game_id = game_id_from_string(game);

	if(base_tasofro_removed == -1) {
		if(game_id == TH145) {
			log_mboxf(NULL, MB_OK | MB_ICONINFORMATION,
				"Support for TH14.5 has been moved out of the sandbox.\n"
				"\n"
				"Please reconfigure your patch stack; otherwise, you might "
				"encounter errors or missing functionality after further "
				"updates.\n"
			);
		} else {
			return 1;
		}
	}

	if (game_id >= TH135) {
		return th135_init();
	}
	else {
		return nsml_init();
	}

	return 0;
}
示例#2
0
文件: inject.c 项目: GovanifY/thcrap
BOOL thcrap_inject_into_new(const char *exe_fn, char *args, const char *run_cfg_fn)
{
	int ret = 0;
	json_t *run_cfg = json_load_file_report(run_cfg_fn);
	if(!run_cfg) {
		return 1;
	};
	json_object_set_new(run_cfg, "run_cfg_fn", json_string(run_cfg_fn));
	runconfig_set(run_cfg);
	{
		STRLEN_DEC(exe_fn);
		VLA(char, exe_dir_local, exe_fn_len);
		VLA(char, exe_fn_local, exe_fn_len);
		STARTUPINFOA si = {0};
		PROCESS_INFORMATION pi = {0};
		char *exe_dir = NULL;

		strcpy(exe_fn_local, exe_fn);
		str_slash_normalize_win(exe_fn_local);

		strcpy(exe_dir_local, exe_fn);
		if(PathRemoveFileSpec(exe_dir_local)) {
			exe_dir = exe_dir_local;
		}

		/**
		  * Sure, the alternative would be to set up the entire engine
		  * with all plug-ins and modules to correctly run any additional
		  * detours. While it would indeed be nice to allow those to control
		  * initial startup, it really shouldn't be necessary for now - and
		  * it really does run way too much unnecessary code for my taste.
		  */
		ret = W32_ERR_WRAP(inject_CreateProcessU(
			exe_fn_local, args, NULL, NULL, TRUE, 0, NULL, exe_dir, &si, &pi
		));
		if(ret) {
			char *msg_str = "";

			FormatMessage(
				FORMAT_MESSAGE_FROM_SYSTEM |
				FORMAT_MESSAGE_ALLOCATE_BUFFER |
				FORMAT_MESSAGE_IGNORE_INSERTS,
				NULL, ret, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
				(LPSTR)&msg_str, 0, NULL
			);

			log_mboxf(NULL, MB_OK | MB_ICONEXCLAMATION,
				"Failed to start %s: %s",
				exe_fn, msg_str
			);
			LocalFree(msg_str);
		}
		VLA_FREE(exe_fn_local);
		VLA_FREE(exe_dir_local);
	}
	return ret;
}
示例#3
0
文件: inject.c 项目: GovanifY/thcrap
int WaitUntilEntryPoint(HANDLE hProcess, HANDLE hThread, const char *module)
{
	// Try to get the entry point by various means, sorted by both efficiency
	// and probability of them working.
	void *entry_addr = NULL;

	/**
	  * Method 1: Initial value of EAX
	  * After creating a process in suspended state, EAX is guaranteed to contain
	  * the correct address of the entry point, even when the executable has the
	  * DYNAMICBASE flag activated in its header.
	  *
	  * (Works on Windows, but not on Wine)
	  */
	if(!(entry_addr = entry_from_context(hThread))) {
		HMODULE module_base;

		/**
		  * Method 2: EnumProcessModules, then parse the PE header.
		  *
		  * (Works on Wine, but not on Windows immediately after the target process
		  * was created in suspended state.)
		  */
		if(!(module_base = GetRemoteModuleHandle(hProcess, module))) {
			/**
			  * Method 3: Guessing 0x400000
			  * This is the default value in many compilers and should thus work for
			  * most non-ASLR Windows applications.
			  */
			module_base = (HMODULE)0x400000;
		}
		entry_addr = GetRemoteModuleEntryPoint(hProcess, module_base);
	}

	if(entry_addr) {
		return ThreadWaitUntil(hProcess, hThread, entry_addr);
	} else {
		log_mboxf(NULL, MB_OK | MB_ICONEXCLAMATION,
			"Couldn't determine the entry point of %s!\n"
			"\n"
			"Seems as if %s won't work with this game on your system.\n",
			PathFindFileNameA(module), PROJECT_NAME_SHORT()
		);
		return 1;
	}
}
示例#4
0
static LRESULT CALLBACK loader_update_proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	static loader_update_state_t *state = nullptr;

	switch (uMsg) {
	case WM_CREATE: {
		CREATESTRUCTW *param = (CREATESTRUCTW*)lParam;
		state = (loader_update_state_t*)param->lpCreateParams;
		break;
	}

	case WM_COMMAND:
		switch LOWORD(wParam) {
		case HWND_BUTTON_RUN:
			if (HIWORD(wParam) == BN_CLICKED) {
				if (state->background_updates == false) {
					state->cancel_update = true;
				}
				EnterCriticalSection(&state->cs);
				state->game_started = true;
				LeaveCriticalSection(&state->cs);
				thcrap_inject_into_new(state->exe_fn, state->args, NULL, NULL);
			}
			break;

		case HWND_BUTTON_UPDATE:
			if (HIWORD(wParam) == BN_CLICKED) {
				SetEvent(state->event_require_update);
			}
			break;

		case HWND_CHECKBOX_KEEP_UPDATER:
			if (HIWORD(wParam) == BN_CLICKED) {
				BOOL enable_state;
				if (SendMessage(state->hwnd[HWND_CHECKBOX_KEEP_UPDATER], BM_GETCHECK, 0, 0) == BST_CHECKED) {
					state->background_updates = true;
					enable_state = TRUE;
				}
				else {
					state->background_updates = false;
					enable_state = FALSE;
				}
				EnableWindow(state->hwnd[HWND_STATIC_UPDATES_INTERVAL], enable_state);
				EnableWindow(state->hwnd[HWND_EDIT_UPDATES_INTERVAL], enable_state);
				EnableWindow(state->hwnd[HWND_UPDOWN], enable_state);
			}
			break;

		case HWND_EDIT_UPDATES_INTERVAL:
			if (HIWORD(wParam) == EN_CHANGE) {
				BOOL success;
				UINT n = GetDlgItemInt(state->hwnd[HWND_MAIN], HWND_EDIT_UPDATES_INTERVAL, &success, FALSE);
				if (success) {
					EnterCriticalSection(&state->cs);
					state->time_between_updates = n;
					LeaveCriticalSection(&state->cs);
				}
			}
			break;

		case HWND_CHECKBOX_UPDATE_AT_EXIT:
			if (HIWORD(wParam) == BN_CLICKED) {
				if (SendMessage(state->hwnd[HWND_CHECKBOX_UPDATE_AT_EXIT], BM_GETCHECK, 0, 0) == BST_CHECKED) {
					state->update_at_exit = true;
				}
				else {
					state->update_at_exit = false;
				}
			}
			break;

		case HWND_CHECKBOX_UPDATE_OTHERS:
			if (HIWORD(wParam) == BN_CLICKED) {
				if (SendMessage(state->hwnd[HWND_CHECKBOX_UPDATE_OTHERS], BM_GETCHECK, 0, 0) == BST_CHECKED) {
					state->update_others = true;
				}
				else {
					state->update_others = false;
				}
			}
			break;

		case HWND_BUTTON_DISABLE_UPDATES:
			if (HIWORD(wParam) == BN_CLICKED) {
				int len = GetCurrentDirectory(0, NULL);
				VLA(char, current_directory, len + 1);
				GetCurrentDirectory(len + 1, current_directory);
				if (log_mboxf(NULL, MB_YESNO, "Do you really want to completely disable updates?\n\n"
					"If you want to enable them again, you will need to run\n"
					"%s\\thcrap_enable_updates.bat",
					current_directory) == IDYES) {
					MoveFile("thcrap_update" DEBUG_OR_RELEASE ".dll", "thcrap_update_disabled" DEBUG_OR_RELEASE ".dll");
					const char *bat_file =
						"@echo off\n"
						"if not exist \"%~dp0\"\\thcrap_update" DEBUG_OR_RELEASE ".dll (\n"
						"move \"%~dp0\"\\thcrap_update_disabled" DEBUG_OR_RELEASE ".dll \"%~dp0\"\\thcrap_update" DEBUG_OR_RELEASE ".dll\n"
						"echo Updates enabled\n"
						") else (\n"
						"echo Updates are already enabled\n"
						")\n"
						"pause\n"
						"(goto) 2>nul & del \"%~f0\"\n";
					file_write("thcrap_enable_updates.bat", bat_file, strlen(bat_file));
					log_mbox(NULL, MB_OK, "Updates are now disabled.");
					PostQuitMessage(0);
				}
				VLA_FREE(current_directory);
			}
			break;

		case HWND_BUTTON_EXPAND_LOGS:
			if (HIWORD(wParam) == BN_CLICKED) {
				if (state->settings_visible) {
					// Hide log window
					SetWindowPos(state->hwnd[HWND_MAIN], 0, 0, 0, 500, 165, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER);
					state->settings_visible = false;
				}
				else {
					// Show log window
					SetWindowPos(state->hwnd[HWND_MAIN], 0, 0, 0, 500, 435, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER);
					state->settings_visible = true;
				}
			}
			break;
		}
		break;

	case WM_CTLCOLORSTATIC:
		if ((HWND)lParam == state->hwnd[HWND_LABEL_STATUS] ||
			(HWND)lParam == state->hwnd[HWND_CHECKBOX_UPDATE_AT_EXIT] ||
			(HWND)lParam == state->hwnd[HWND_CHECKBOX_KEEP_UPDATER] ||
			(HWND)lParam == state->hwnd[HWND_CHECKBOX_UPDATE_OTHERS] ||
			(HWND)lParam == state->hwnd[HWND_STATIC_UPDATES_INTERVAL] ||
			(HWND)lParam == state->hwnd[HWND_STATIC_UPDATE_AT_EXIT]) {
			HDC hdc = (HDC)wParam;
			SetTextColor(hdc, RGB(0, 0, 0));
			SetBkMode(hdc, TRANSPARENT);
			return (LRESULT)GetSysColorBrush(COLOR_WINDOW);
		}
		break;

	case WM_DESTROY:
		state->cancel_update = true;
		PostQuitMessage(0);
		break;
	}