mirror of
https://github.com/Detanup01/gbe_fork.git
synced 2024-11-23 19:25:35 +08:00
refactored the entire win client loader to use C++ + use relative paths to the exe itself + added a debug log
This commit is contained in:
parent
d1fdde23cc
commit
00ace6727d
@ -1,9 +1,10 @@
|
|||||||
// My own modified version of ColdClientLoader originally written by Rat431
|
// a Modified version of ColdClientLoader originally written by Rat431
|
||||||
// https://github.com/Rat431/ColdAPI_Steam/tree/master/src/ColdClientLoader
|
// https://github.com/Rat431/ColdAPI_Steam/tree/master/src/ColdClientLoader
|
||||||
|
|
||||||
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
#include "common_helpers/common_helpers.hpp"
|
||||||
// Windows Header Files
|
#include "pe_helpers/pe_helpers.hpp"
|
||||||
#include <windows.h>
|
#include "dbg_log/dbg_log.hpp"
|
||||||
|
|
||||||
// C RunTime Header Files
|
// C RunTime Header Files
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
@ -12,260 +13,236 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "pe_helpers/pe_helpers.hpp"
|
|
||||||
|
|
||||||
bool IsNotRelativePathOrRemoveFileName(WCHAR* output, bool Remove)
|
static const std::wstring IniFile = pe_helpers::get_current_exe_path_w() + L"ColdClientLoader.ini";
|
||||||
|
static const std::wstring dbg_file = pe_helpers::get_current_exe_path_w() + L"COLD_LDR_LOG.txt";
|
||||||
|
constexpr static const char STEAM_UNIVERSE[] = "Public";
|
||||||
|
|
||||||
|
std::wstring get_ini_value(LPCWSTR section, LPCWSTR key, LPCWSTR default_val = NULL)
|
||||||
{
|
{
|
||||||
int LG = lstrlenW(output);
|
std::vector<wchar_t> buff(INT16_MAX);
|
||||||
for (int i = LG; i > 0; i--) {
|
DWORD read_chars = GetPrivateProfileStringW(section, key, default_val, &buff[0], (DWORD)buff.size(), IniFile.c_str());
|
||||||
if (output[i] == '\\') {
|
if (!read_chars) {
|
||||||
if(Remove)
|
std::wstring();
|
||||||
RtlFillMemory(&output[i], (LG - i) * sizeof(WCHAR), NULL);
|
}
|
||||||
return true;
|
|
||||||
}
|
// "If neither lpAppName nor lpKeyName is NULL and the supplied destination buffer is too small to hold the requested string, the return value is equal to nSize minus one"
|
||||||
}
|
int trials = 3;
|
||||||
return false;
|
while ((read_chars == (buff.size() - 1)) && trials > 0) {
|
||||||
|
buff.resize(buff.size() * 2);
|
||||||
|
read_chars = GetPrivateProfileStringW(section, key, default_val, &buff[0], (DWORD)buff.size(), IniFile.c_str());
|
||||||
|
--trials;
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::wstring(&buff[0], read_chars);
|
||||||
}
|
}
|
||||||
|
|
||||||
int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow)
|
int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow)
|
||||||
{
|
{
|
||||||
WCHAR CurrentDirectory[MAX_PATH] = { 0 };
|
dbg_log::init(dbg_file.c_str());
|
||||||
WCHAR Client64Path[MAX_PATH] = { 0 };
|
|
||||||
WCHAR ClientPath[MAX_PATH] = { 0 };
|
|
||||||
WCHAR ExeFile[MAX_PATH] = { 0 };
|
|
||||||
WCHAR ExeRunDir[MAX_PATH] = { 0 };
|
|
||||||
WCHAR ExeCommandLine[4096] = { 0 };
|
|
||||||
WCHAR AppId[128] = { 0 };
|
|
||||||
|
|
||||||
int Length = GetModuleFileNameW(GetModuleHandleW(NULL), CurrentDirectory, sizeof(CurrentDirectory)) + 1;
|
if (!common_helpers::file_exist(IniFile)) {
|
||||||
for (int i = Length; i > 0; i--) {
|
dbg_log::write(L"Couldn't find the configuration file: " + dbg_file);
|
||||||
if (CurrentDirectory[i] == '\\') {
|
MessageBoxA(NULL, "Couldn't find the configuration file ColdClientLoader.ini.", "ColdClientLoader", MB_ICONERROR);
|
||||||
lstrcpyW(&CurrentDirectory[i + 1], L"ColdClientLoader.ini");
|
dbg_log::close();
|
||||||
break;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (GetFileAttributesW(CurrentDirectory) == INVALID_FILE_ATTRIBUTES) {
|
std::wstring Client64Path = common_helpers::to_absolute(
|
||||||
MessageBoxA(NULL, "Couldn't find the configuration file(ColdClientLoader.ini).", "ColdClientLoader", MB_ICONERROR);
|
get_ini_value(L"SteamClient", L"SteamClient64Dll"),
|
||||||
return 1;
|
pe_helpers::get_current_exe_path_w()
|
||||||
}
|
);
|
||||||
|
|
||||||
GetPrivateProfileStringW(L"SteamClient", L"SteamClient64Dll", L"", Client64Path, MAX_PATH, CurrentDirectory);
|
std::wstring ClientPath = common_helpers::to_absolute(
|
||||||
GetPrivateProfileStringW(L"SteamClient", L"SteamClientDll", L"", ClientPath, MAX_PATH, CurrentDirectory);
|
get_ini_value(L"SteamClient", L"SteamClientDll"),
|
||||||
GetPrivateProfileStringW(L"SteamClient", L"Exe", NULL, ExeFile, MAX_PATH, CurrentDirectory);
|
pe_helpers::get_current_exe_path_w()
|
||||||
GetPrivateProfileStringW(L"SteamClient", L"ExeRunDir", NULL, ExeRunDir, MAX_PATH, CurrentDirectory);
|
);
|
||||||
GetPrivateProfileStringW(L"SteamClient", L"ExeCommandLine", NULL, ExeCommandLine, 4096, CurrentDirectory);
|
std::wstring ExeFile = common_helpers::to_absolute(
|
||||||
GetPrivateProfileStringW(L"SteamClient", L"AppId", NULL, AppId, sizeof(AppId), CurrentDirectory);
|
get_ini_value(L"SteamClient", L"Exe"),
|
||||||
|
pe_helpers::get_current_exe_path_w()
|
||||||
|
);
|
||||||
|
std::wstring ExeRunDir = common_helpers::to_absolute(
|
||||||
|
get_ini_value(L"SteamClient", L"ExeRunDir"),
|
||||||
|
pe_helpers::get_current_exe_path_w()
|
||||||
|
);
|
||||||
|
std::wstring ExeCommandLine = get_ini_value(L"SteamClient", L"ExeCommandLine");
|
||||||
|
std::wstring AppId = get_ini_value(L"SteamClient", L"AppId");
|
||||||
|
|
||||||
|
// log everything
|
||||||
|
dbg_log::write(L"SteamClient64Dll: " + Client64Path);
|
||||||
|
dbg_log::write(L"SteamClient: " + ClientPath);
|
||||||
|
dbg_log::write(L"Exe: " + ExeFile);
|
||||||
|
dbg_log::write(L"ExeRunDir: " + ExeRunDir);
|
||||||
|
dbg_log::write(L"ExeCommandLine: " + ExeCommandLine);
|
||||||
|
dbg_log::write(L"AppId: " + AppId);
|
||||||
|
|
||||||
if (AppId[0]) {
|
if (AppId.size() && AppId[0]) {
|
||||||
SetEnvironmentVariableW(L"SteamAppId", AppId);
|
SetEnvironmentVariableW(L"SteamAppId", AppId.c_str());
|
||||||
SetEnvironmentVariableW(L"SteamGameId", AppId);
|
SetEnvironmentVariableW(L"SteamGameId", AppId.c_str());
|
||||||
SetEnvironmentVariableW(L"SteamOverlayGameId", AppId);
|
SetEnvironmentVariableW(L"SteamOverlayGameId", AppId.c_str());
|
||||||
} else {
|
} else {
|
||||||
MessageBoxA(NULL, "You forgot to set the AppId.", "ColdClientLoader", MB_ICONERROR);
|
dbg_log::write("You forgot to set the AppId");
|
||||||
return 1;
|
MessageBoxA(NULL, "You forgot to set the AppId.", "ColdClientLoader", MB_ICONERROR);
|
||||||
}
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
WCHAR TMP[MAX_PATH] = { 0 };
|
if (!common_helpers::file_exist(Client64Path)) {
|
||||||
if (!IsNotRelativePathOrRemoveFileName(Client64Path, false)) {
|
dbg_log::write("Couldn't find the requested SteamClient64Dll");
|
||||||
lstrcpyW(TMP, Client64Path);
|
MessageBoxA(NULL, "Couldn't find the requested SteamClient64Dll.", "ColdClientLoader", MB_ICONERROR);
|
||||||
SecureZeroMemory(Client64Path, sizeof(Client64Path));
|
dbg_log::close();
|
||||||
GetFullPathNameW(TMP, MAX_PATH, Client64Path, NULL);
|
return 1;
|
||||||
}
|
}
|
||||||
if (!IsNotRelativePathOrRemoveFileName(ClientPath, false)) {
|
|
||||||
lstrcpyW(TMP, ClientPath);
|
|
||||||
SecureZeroMemory(ClientPath, sizeof(ClientPath));
|
|
||||||
GetFullPathNameW(TMP, MAX_PATH, ClientPath, NULL);
|
|
||||||
}
|
|
||||||
if (!IsNotRelativePathOrRemoveFileName(ExeFile, false)) {
|
|
||||||
lstrcpyW(TMP, ExeFile);
|
|
||||||
SecureZeroMemory(ExeFile, sizeof(ExeFile));
|
|
||||||
GetFullPathNameW(TMP, MAX_PATH, ExeFile, NULL);
|
|
||||||
}
|
|
||||||
if (!IsNotRelativePathOrRemoveFileName(ExeRunDir, false)) {
|
|
||||||
lstrcpyW(TMP, ExeRunDir);
|
|
||||||
SecureZeroMemory(ExeRunDir, sizeof(ExeRunDir));
|
|
||||||
GetFullPathNameW(TMP, MAX_PATH, ExeRunDir, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetFileAttributesW(Client64Path) == INVALID_FILE_ATTRIBUTES) {
|
if (!common_helpers::file_exist(ClientPath)) {
|
||||||
MessageBoxA(NULL, "Couldn't find the requested SteamClient64Dll.", "ColdClientLoader", MB_ICONERROR);
|
dbg_log::write("Couldn't find the requested SteamClientDll");
|
||||||
return 1;
|
MessageBoxA(NULL, "Couldn't find the requested SteamClientDll.", "ColdClientLoader", MB_ICONERROR);
|
||||||
}
|
dbg_log::close();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (GetFileAttributesW(ClientPath) == INVALID_FILE_ATTRIBUTES) {
|
if (!common_helpers::file_exist(ExeFile)) {
|
||||||
MessageBoxA(NULL, "Couldn't find the requested SteamClientDll.", "ColdClientLoader", MB_ICONERROR);
|
dbg_log::write("Couldn't find the requested Exe file");
|
||||||
return 1;
|
MessageBoxA(NULL, "Couldn't find the requested Exe file.", "ColdClientLoader", MB_ICONERROR);
|
||||||
}
|
dbg_log::close();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (GetFileAttributesW(ExeFile) == INVALID_FILE_ATTRIBUTES) {
|
if (!common_helpers::dir_exist(ExeRunDir)) {
|
||||||
MessageBoxA(NULL, "Couldn't find the requested Exe file.", "ColdClientLoader", MB_ICONERROR);
|
dbg_log::write("Couldn't find the requested Exe run dir");
|
||||||
return 1;
|
MessageBoxA(NULL, "Couldn't find the requested Exe run dir.", "ColdClientLoader", MB_ICONERROR);
|
||||||
}
|
dbg_log::close();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
HKEY Registrykey = { 0 };
|
HKEY Registrykey = { 0 };
|
||||||
// Declare some variables to be used for Steam registry.
|
// Declare some variables to be used for Steam registry.
|
||||||
DWORD UserId = 0x03100004771F810D & 0xffffffff;
|
DWORD UserId = 0x03100004771F810D & 0xffffffff;
|
||||||
DWORD ProcessID = GetCurrentProcessId();
|
DWORD ProcessID = GetCurrentProcessId();
|
||||||
|
|
||||||
bool orig_steam = false;
|
bool orig_steam = false;
|
||||||
DWORD keyType = REG_SZ;
|
DWORD keyType = REG_SZ;
|
||||||
WCHAR OrgSteamCDir[MAX_PATH] = { 0 };
|
WCHAR OrgSteamCDir[8192] = { 0 };
|
||||||
WCHAR OrgSteamCDir64[MAX_PATH] = { 0 };
|
WCHAR OrgSteamCDir64[8192] = { 0 };
|
||||||
DWORD Size1 = MAX_PATH;
|
DWORD Size1 = _countof(OrgSteamCDir);
|
||||||
DWORD Size2 = MAX_PATH;
|
DWORD Size2 = _countof(OrgSteamCDir64);
|
||||||
if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\Valve\\Steam\\ActiveProcess", 0, KEY_ALL_ACCESS, &Registrykey) == ERROR_SUCCESS)
|
if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\Valve\\Steam\\ActiveProcess", 0, KEY_ALL_ACCESS, &Registrykey) == ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
orig_steam = true;
|
orig_steam = true;
|
||||||
// Get original values to restore later.
|
// Get original values to restore later.
|
||||||
RegQueryValueExW(Registrykey, L"SteamClientDll", 0, &keyType, (LPBYTE)& OrgSteamCDir, &Size1);
|
RegQueryValueExW(Registrykey, L"SteamClientDll", 0, &keyType, (LPBYTE)& OrgSteamCDir, &Size1);
|
||||||
RegQueryValueExW(Registrykey, L"SteamClientDll64", 0, &keyType, (LPBYTE)& OrgSteamCDir64, &Size2);
|
RegQueryValueExW(Registrykey, L"SteamClientDll64", 0, &keyType, (LPBYTE)& OrgSteamCDir64, &Size2);
|
||||||
} else {
|
} else {
|
||||||
if (RegCreateKeyExW(HKEY_CURRENT_USER, L"Software\\Valve\\Steam\\ActiveProcess", 0, 0, REG_OPTION_NON_VOLATILE,
|
if (RegCreateKeyExW(HKEY_CURRENT_USER, L"Software\\Valve\\Steam\\ActiveProcess", 0, 0, REG_OPTION_NON_VOLATILE,
|
||||||
KEY_ALL_ACCESS, NULL, &Registrykey, NULL) != ERROR_SUCCESS)
|
KEY_ALL_ACCESS, NULL, &Registrykey, NULL) != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
MessageBoxA(NULL, "Unable to patch Steam process informations on the Windows registry.", "ColdClientLoader", MB_ICONERROR);
|
dbg_log::write("Unable to patch Steam process informations on the Windows registry (ActiveProcess), error = " + std::to_string(GetLastError()));
|
||||||
return 1;
|
MessageBoxA(NULL, "Unable to patch Steam process informations on the Windows registry.", "ColdClientLoader", MB_ICONERROR);
|
||||||
}
|
dbg_log::close();
|
||||||
}
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Set values to Windows registry.
|
// Set values to Windows registry.
|
||||||
RegSetValueExA(Registrykey, "ActiveUser", NULL, REG_DWORD, (LPBYTE)& UserId, sizeof(DWORD));
|
RegSetValueExA(Registrykey, "ActiveUser", NULL, REG_DWORD, (const BYTE *)&UserId, sizeof(DWORD));
|
||||||
RegSetValueExA(Registrykey, "pid", NULL, REG_DWORD, (LPBYTE)& ProcessID, sizeof(DWORD));
|
RegSetValueExA(Registrykey, "pid", NULL, REG_DWORD, (const BYTE *)&ProcessID, sizeof(DWORD));
|
||||||
|
RegSetValueExW(Registrykey, L"SteamClientDll", NULL, REG_SZ, (const BYTE *)ClientPath.c_str(), (ClientPath.size() + 1) * sizeof(ClientPath[0]));
|
||||||
|
RegSetValueExW(Registrykey, L"SteamClientDll64", NULL, REG_SZ, (const BYTE *)Client64Path.c_str(), (Client64Path.size() + 1) * sizeof(Client64Path[0]));
|
||||||
|
RegSetValueExA(Registrykey, "Universe", NULL, REG_SZ, (const BYTE *)STEAM_UNIVERSE, (DWORD)sizeof(STEAM_UNIVERSE));
|
||||||
|
|
||||||
{
|
// Close the HKEY Handle.
|
||||||
// Before saving to the registry check again if the path was valid and if the file exist
|
RegCloseKey(Registrykey);
|
||||||
if (GetFileAttributesW(ClientPath) != INVALID_FILE_ATTRIBUTES) {
|
|
||||||
RegSetValueExW(Registrykey, L"SteamClientDll", NULL, REG_SZ, (LPBYTE)ClientPath, (DWORD)(lstrlenW(ClientPath) * sizeof(WCHAR)) + 1);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
RegSetValueExW(Registrykey, L"SteamClientDll", NULL, REG_SZ, (LPBYTE)"", 0);
|
|
||||||
}
|
|
||||||
if (GetFileAttributesW(Client64Path) != INVALID_FILE_ATTRIBUTES) {
|
|
||||||
RegSetValueExW(Registrykey, L"SteamClientDll64", NULL, REG_SZ, (LPBYTE)Client64Path, (DWORD)(lstrlenW(Client64Path) * sizeof(WCHAR)) + 1);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
RegSetValueExW(Registrykey, L"SteamClientDll64", NULL, REG_SZ, (LPBYTE)"", 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
RegSetValueExA(Registrykey, "Universe", NULL, REG_SZ, (LPBYTE)"Public", (DWORD)lstrlenA("Public") + 1);
|
|
||||||
|
|
||||||
// Close the HKEY Handle.
|
// dll to inject
|
||||||
RegCloseKey(Registrykey);
|
bool inject_extra_dll = false;
|
||||||
|
std::wstring extra_dll = common_helpers::to_absolute(
|
||||||
|
get_ini_value(L"Extra", L"InjectDll"),
|
||||||
|
pe_helpers::get_current_exe_path_w()
|
||||||
|
);
|
||||||
|
if (extra_dll.size()) {
|
||||||
|
dbg_log::write(L"InjectDll: " + extra_dll);
|
||||||
|
if (!common_helpers::file_exist(extra_dll)) {
|
||||||
|
dbg_log::write("Couldn't find the requested dll to inject");
|
||||||
|
MessageBoxA(NULL, "Couldn't find the requested dll to inject.", "ColdClientLoader", MB_ICONERROR);
|
||||||
|
dbg_log::close();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
inject_extra_dll = true;
|
||||||
|
}
|
||||||
|
|
||||||
// dll to inject
|
// spawn the exe
|
||||||
bool inject_extra_dll = false;
|
STARTUPINFOW info = { 0 };
|
||||||
std::wstring extra_dll(8192, L'\0');
|
SecureZeroMemory(&info, sizeof(info));
|
||||||
{
|
info.cb = sizeof(info);
|
||||||
auto read_chars = GetPrivateProfileStringW(L"Extra", L"InjectDll", L"", &extra_dll[0], extra_dll.size(), CurrentDirectory);
|
|
||||||
if (extra_dll[0]) {
|
|
||||||
extra_dll = extra_dll.substr(0, read_chars);
|
|
||||||
} else {
|
|
||||||
extra_dll.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (extra_dll.size()) {
|
|
||||||
if (!IsNotRelativePathOrRemoveFileName(&extra_dll[0], false)) {
|
|
||||||
std::wstring tmp = extra_dll;
|
|
||||||
read_chars = GetFullPathNameW(tmp.c_str(), extra_dll.size(), &extra_dll[0], NULL);
|
|
||||||
if (!read_chars) {
|
|
||||||
MessageBoxA(NULL, "Unable to get full path of dll to inject.", "ColdClientLoader", MB_ICONERROR);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (read_chars >= extra_dll.size()) {
|
PROCESS_INFORMATION processInfo = { 0 };
|
||||||
extra_dll.resize(read_chars);
|
SecureZeroMemory(&processInfo, sizeof(processInfo));
|
||||||
read_chars = GetFullPathNameW(tmp.c_str(), extra_dll.size(), &extra_dll[0], NULL);
|
|
||||||
if (!read_chars) {
|
|
||||||
MessageBoxA(NULL, "Unable to get full path of dll to inject after resizing buffer.", "ColdClientLoader", MB_ICONERROR);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extra_dll = extra_dll.substr(0, read_chars);
|
WCHAR CommandLine[16384] = { 0 };
|
||||||
}
|
_snwprintf(CommandLine, _countof(CommandLine), L"\"%ls\" %ls %ls", ExeFile.c_str(), ExeCommandLine.c_str(), lpCmdLine);
|
||||||
|
if (!CreateProcessW(ExeFile.c_str(), CommandLine, NULL, NULL, TRUE, CREATE_SUSPENDED, NULL, ExeRunDir.c_str(), &info, &processInfo))
|
||||||
if (GetFileAttributesW(extra_dll.c_str()) == INVALID_FILE_ATTRIBUTES) {
|
{
|
||||||
MessageBoxA(NULL, "Couldn't find the requested dll to inject.", "ColdClientLoader", MB_ICONERROR);
|
dbg_log::write("Unable to load the requested EXE file");
|
||||||
return 1;
|
MessageBoxA(NULL, "Unable to load the requested EXE file.", "ColdClientLoader", MB_ICONERROR);
|
||||||
}
|
dbg_log::close();
|
||||||
inject_extra_dll = true;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
if (inject_extra_dll) {
|
||||||
|
const char *err_inject = nullptr;
|
||||||
|
DWORD code = pe_helpers::loadlib_remote(processInfo.hProcess, extra_dll, &err_inject);
|
||||||
|
if (code != ERROR_SUCCESS) {
|
||||||
|
TerminateProcess(processInfo.hProcess, 1);
|
||||||
|
std::string err_full =
|
||||||
|
"Failed to inject the requested dll:\n" +
|
||||||
|
std::string(err_inject) + "\n" +
|
||||||
|
pe_helpers::get_err_string(code) + "\n" +
|
||||||
|
"Error code = " + std::to_string(code) + "\n";
|
||||||
|
dbg_log::write(err_full);
|
||||||
|
MessageBoxA(NULL, err_full.c_str(), "ColdClientLoader", MB_ICONERROR);
|
||||||
|
dbg_log::close();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// spawn the exe
|
bool run_exe = true;
|
||||||
STARTUPINFOW info = { 0 };
|
|
||||||
SecureZeroMemory(&info, sizeof(info));
|
|
||||||
info.cb = sizeof(info);
|
|
||||||
|
|
||||||
PROCESS_INFORMATION processInfo = { 0 };
|
|
||||||
SecureZeroMemory(&processInfo, sizeof(processInfo));
|
|
||||||
|
|
||||||
WCHAR CommandLine[16384] = { 0 };
|
|
||||||
_snwprintf(CommandLine, _countof(CommandLine), L"\"%ls\" %ls %ls", ExeFile, ExeCommandLine, lpCmdLine);
|
|
||||||
if (!ExeFile[0] || !CreateProcessW(ExeFile, CommandLine, NULL, NULL, TRUE, CREATE_SUSPENDED, NULL, ExeRunDir, &info, &processInfo))
|
|
||||||
{
|
|
||||||
MessageBoxA(NULL, "Unable to load the requested EXE file.", "ColdClientLoader", MB_ICONERROR);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (inject_extra_dll) {
|
|
||||||
const char *err_inject = nullptr;
|
|
||||||
DWORD code = pe_helpers::loadlib_remote(processInfo.hProcess, extra_dll, &err_inject);
|
|
||||||
if (code != ERROR_SUCCESS) {
|
|
||||||
TerminateProcess(processInfo.hProcess, 1);
|
|
||||||
std::string err_full =
|
|
||||||
"Failed to inject the requested dll:\n" +
|
|
||||||
std::string(err_inject) + "\n" +
|
|
||||||
pe_helpers::get_err_string(code) + "\n" +
|
|
||||||
"Error code = " + std::to_string(code) + "\n";
|
|
||||||
MessageBoxA(NULL, err_full.c_str(), "ColdClientLoader", MB_ICONERROR);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool run_exe = true;
|
|
||||||
#ifndef EMU_RELEASE_BUILD
|
#ifndef EMU_RELEASE_BUILD
|
||||||
{
|
std::wstring resume_by_dbg = get_ini_value(L"Debug", L"ResumeByDebugger");
|
||||||
std::wstring dbg_file(50, L'\0');
|
dbg_log::write(L"Debug::ResumeByDebugger: " + resume_by_dbg);
|
||||||
auto read_chars = GetPrivateProfileStringW(L"Debug", L"ResumeByDebugger", L"", &dbg_file[0], dbg_file.size(), CurrentDirectory);
|
for (auto &c : resume_by_dbg) {
|
||||||
if (dbg_file[0]) {
|
c = (wchar_t)std::tolower((int)c);
|
||||||
dbg_file = dbg_file.substr(0, read_chars);
|
}
|
||||||
} else {
|
if (resume_by_dbg == L"1" || resume_by_dbg == L"y" || resume_by_dbg == L"yes" || resume_by_dbg == L"true") {
|
||||||
dbg_file.clear();
|
run_exe = false;
|
||||||
}
|
std::string msg = "Attach a debugger now to PID " + std::to_string(processInfo.dwProcessId) + " and resume its main thread";
|
||||||
for (auto &c : dbg_file) {
|
dbg_log::write(msg);
|
||||||
c = (wchar_t)std::tolower((int)c);
|
MessageBoxA(NULL, msg.c_str(), "ColdClientLoader", MB_OK);
|
||||||
}
|
}
|
||||||
if (dbg_file == L"1" || dbg_file == L"y" || dbg_file == L"yes" || dbg_file == L"true") {
|
|
||||||
run_exe = false;
|
|
||||||
std::string msg = "Attach a debugger now to PID " + std::to_string(processInfo.dwProcessId) + " and resume its main thread";
|
|
||||||
MessageBoxA(NULL, msg.c_str(), "ColdClientLoader", MB_OK);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// run
|
// run
|
||||||
if (run_exe) {
|
if (run_exe) {
|
||||||
ResumeThread(processInfo.hThread);
|
ResumeThread(processInfo.hThread);
|
||||||
}
|
}
|
||||||
// wait
|
// wait
|
||||||
WaitForSingleObject(processInfo.hThread, INFINITE);
|
WaitForSingleObject(processInfo.hThread, INFINITE);
|
||||||
|
|
||||||
CloseHandle(processInfo.hThread);
|
CloseHandle(processInfo.hThread);
|
||||||
CloseHandle(processInfo.hProcess);
|
CloseHandle(processInfo.hProcess);
|
||||||
|
|
||||||
if (orig_steam) {
|
if (orig_steam) {
|
||||||
if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\Valve\\Steam\\ActiveProcess", 0, KEY_ALL_ACCESS, &Registrykey) == ERROR_SUCCESS)
|
if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\Valve\\Steam\\ActiveProcess", 0, KEY_ALL_ACCESS, &Registrykey) == ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
// Restore the values.
|
// Restore the values.
|
||||||
RegSetValueExW(Registrykey, L"SteamClientDll", NULL, REG_SZ, (LPBYTE)OrgSteamCDir, Size1);
|
RegSetValueExW(Registrykey, L"SteamClientDll", NULL, REG_SZ, (LPBYTE)OrgSteamCDir, Size1);
|
||||||
RegSetValueExW(Registrykey, L"SteamClientDll64", NULL, REG_SZ, (LPBYTE)OrgSteamCDir64, Size2);
|
RegSetValueExW(Registrykey, L"SteamClientDll64", NULL, REG_SZ, (LPBYTE)OrgSteamCDir64, Size2);
|
||||||
|
|
||||||
// Close the HKEY Handle.
|
// Close the HKEY Handle.
|
||||||
RegCloseKey(Registrykey);
|
RegCloseKey(Registrykey);
|
||||||
}
|
} else {
|
||||||
}
|
dbg_log::write("Unable to restore the original Steam process informations in the Windows registry, error = " + std::to_string(GetLastError()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
dbg_log::close();
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user