Start steam if necessary
This commit is contained in:
parent
b1c6f9de4a
commit
4b2a7c8e0b
@ -2,6 +2,7 @@
|
|||||||
#include "loader/component_loader.hpp"
|
#include "loader/component_loader.hpp"
|
||||||
#include "scheduler.hpp"
|
#include "scheduler.hpp"
|
||||||
|
|
||||||
|
#include "steam/steam.hpp"
|
||||||
#include <utils/hook.hpp>
|
#include <utils/hook.hpp>
|
||||||
|
|
||||||
namespace arxan
|
namespace arxan
|
||||||
@ -10,20 +11,90 @@ namespace arxan
|
|||||||
{
|
{
|
||||||
DWORD get_steam_pid()
|
DWORD get_steam_pid()
|
||||||
{
|
{
|
||||||
static auto steam_pid = []
|
HKEY reg_key;
|
||||||
{
|
DWORD pid{};
|
||||||
HKEY reg_key;
|
|
||||||
DWORD pid{};
|
|
||||||
|
|
||||||
if (RegOpenKeyExA(HKEY_CURRENT_USER, "Software\\Valve\\Steam\\ActiveProcess", 0, KEY_QUERY_VALUE,
|
|
||||||
®_key) != ERROR_SUCCESS)
|
|
||||||
return pid;
|
|
||||||
|
|
||||||
DWORD length = sizeof(pid);
|
|
||||||
RegQueryValueExA(reg_key, "pid", nullptr, nullptr, reinterpret_cast<BYTE*>(&pid), &length);
|
|
||||||
RegCloseKey(reg_key);
|
|
||||||
|
|
||||||
|
if (RegOpenKeyExA(HKEY_CURRENT_USER, "Software\\Valve\\Steam\\ActiveProcess", 0, KEY_QUERY_VALUE,
|
||||||
|
®_key) != ERROR_SUCCESS)
|
||||||
return pid;
|
return pid;
|
||||||
|
|
||||||
|
DWORD length = sizeof(pid);
|
||||||
|
RegQueryValueExA(reg_key, "pid", nullptr, nullptr, reinterpret_cast<BYTE*>(&pid), &length);
|
||||||
|
RegCloseKey(reg_key);
|
||||||
|
|
||||||
|
return pid;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_valid_pid(const DWORD pid)
|
||||||
|
{
|
||||||
|
const auto handle = OpenProcess(SYNCHRONIZE, FALSE, pid);
|
||||||
|
if (!handle)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseHandle(handle);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void start_steam()
|
||||||
|
{
|
||||||
|
STARTUPINFOA startup_info;
|
||||||
|
PROCESS_INFORMATION process_info;
|
||||||
|
|
||||||
|
ZeroMemory(&startup_info, sizeof(startup_info));
|
||||||
|
ZeroMemory(&process_info, sizeof(process_info));
|
||||||
|
startup_info.cb = sizeof(startup_info);
|
||||||
|
|
||||||
|
const auto steam_folder = steam::SteamAPI_GetSteamInstallPath();
|
||||||
|
const auto steam_path = steam_folder + "\\steam.exe"s;
|
||||||
|
char cmd_line[] = "steam.exe -silent";
|
||||||
|
|
||||||
|
if (CreateProcessA(steam_path.data(), &cmd_line[0], nullptr, nullptr, false, NULL, nullptr, steam_folder,
|
||||||
|
&startup_info, &process_info))
|
||||||
|
{
|
||||||
|
CloseHandle(process_info.hThread);
|
||||||
|
CloseHandle(
|
||||||
|
process_info.hProcess);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void start_steam_if_wanted()
|
||||||
|
{
|
||||||
|
if (MessageBoxA(nullptr, "Steam must be running. Do you want to start it now?", "Information",
|
||||||
|
MB_ICONINFORMATION | MB_YESNO) != IDYES)
|
||||||
|
{
|
||||||
|
TerminateProcess(GetCurrentProcess(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
start_steam();
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD setup_and_get_steam_pid()
|
||||||
|
{
|
||||||
|
static DWORD steam_pid = []
|
||||||
|
{
|
||||||
|
auto pid = get_steam_pid();
|
||||||
|
if (is_valid_pid(pid))
|
||||||
|
{
|
||||||
|
return pid;
|
||||||
|
}
|
||||||
|
|
||||||
|
start_steam_if_wanted();
|
||||||
|
|
||||||
|
std::this_thread::sleep_for(3s);
|
||||||
|
|
||||||
|
for (int i = 0; i < 10; ++i)
|
||||||
|
{
|
||||||
|
std::this_thread::sleep_for(1s);
|
||||||
|
pid = get_steam_pid();
|
||||||
|
if (is_valid_pid(pid))
|
||||||
|
{
|
||||||
|
return pid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return get_steam_pid();
|
||||||
}();
|
}();
|
||||||
|
|
||||||
return steam_pid;
|
return steam_pid;
|
||||||
@ -162,6 +233,10 @@ namespace arxan
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define ProcessDebugPort 7
|
||||||
|
#define ProcessDebugObjectHandle 30 // WinXP source says 31?
|
||||||
|
#define ProcessDebugFlags 31 // WinXP source says 32?
|
||||||
|
|
||||||
NTSTATUS WINAPI nt_query_information_process_stub(HANDLE handle, const PROCESSINFOCLASS info_class,
|
NTSTATUS WINAPI nt_query_information_process_stub(HANDLE handle, const PROCESSINFOCLASS info_class,
|
||||||
const PVOID info,
|
const PVOID info,
|
||||||
const ULONG info_length, const PULONG ret_length)
|
const ULONG info_length, const PULONG ret_length)
|
||||||
@ -175,23 +250,24 @@ namespace arxan
|
|||||||
{
|
{
|
||||||
if (info_class == ProcessBasicInformation)
|
if (info_class == ProcessBasicInformation)
|
||||||
{
|
{
|
||||||
static_cast<PPROCESS_BASIC_INFORMATION>(info)->Reserved3 = PVOID(DWORD64(get_steam_pid()));
|
static_cast<PPROCESS_BASIC_INFORMATION>(info)->Reserved3 =
|
||||||
|
PVOID(DWORD64(setup_and_get_steam_pid()));
|
||||||
}
|
}
|
||||||
else if (info_class == 30) // ProcessDebugObjectHandle
|
else if (info_class == ProcessDebugObjectHandle)
|
||||||
{
|
{
|
||||||
*static_cast<HANDLE*>(info) = nullptr;
|
*static_cast<HANDLE*>(info) = nullptr;
|
||||||
|
|
||||||
return 0xC0000353;
|
return 0xC0000353;
|
||||||
}
|
}
|
||||||
else if (info_class == ProcessImageFileName || info_class == 43)
|
else if (info_class == ProcessImageFileName || info_class == 43 /* ? */)
|
||||||
{
|
{
|
||||||
remove_evil_keywords_from_string(*static_cast<UNICODE_STRING*>(info));
|
remove_evil_keywords_from_string(*static_cast<UNICODE_STRING*>(info));
|
||||||
}
|
}
|
||||||
else if (info_class == 7) // ProcessDebugPort
|
else if (info_class == ProcessDebugPort)
|
||||||
{
|
{
|
||||||
*static_cast<HANDLE*>(info) = nullptr;
|
*static_cast<HANDLE*>(info) = nullptr;
|
||||||
}
|
}
|
||||||
else if (info_class == 31)
|
else if (info_class == ProcessDebugFlags)
|
||||||
{
|
{
|
||||||
*static_cast<ULONG*>(info) = 1;
|
*static_cast<ULONG*>(info) = 1;
|
||||||
}
|
}
|
||||||
@ -259,7 +335,7 @@ namespace arxan
|
|||||||
|
|
||||||
const utils::nt::library ntdll("ntdll.dll");
|
const utils::nt::library ntdll("ntdll.dll");
|
||||||
|
|
||||||
for (int i = 0; i < ARRAYSIZE(functions); ++i)
|
for (auto i = 0u; i < ARRAYSIZE(functions); ++i)
|
||||||
{
|
{
|
||||||
const auto func = ntdll.get_proc<void*>(functions[i]);
|
const auto func = ntdll.get_proc<void*>(functions[i]);
|
||||||
if (!loaded)
|
if (!loaded)
|
||||||
@ -281,6 +357,8 @@ namespace arxan
|
|||||||
public:
|
public:
|
||||||
void post_load() override
|
void post_load() override
|
||||||
{
|
{
|
||||||
|
setup_and_get_steam_pid();
|
||||||
|
|
||||||
hide_being_debugged();
|
hide_being_debugged();
|
||||||
scheduler::loop(hide_being_debugged, scheduler::pipeline::async);
|
scheduler::loop(hide_being_debugged, scheduler::pipeline::async);
|
||||||
|
|
||||||
|
@ -7,22 +7,26 @@ namespace utils::hook
|
|||||||
{
|
{
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
[[maybe_unused]] class _
|
void* initialize_min_hook()
|
||||||
{
|
{
|
||||||
public:
|
static class min_hook_init
|
||||||
_()
|
|
||||||
{
|
{
|
||||||
if (MH_Initialize() != MH_OK)
|
public:
|
||||||
|
min_hook_init()
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Failed to initialize MinHook");
|
if (MH_Initialize() != MH_OK)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Failed to initialize MinHook");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
~_()
|
~min_hook_init()
|
||||||
{
|
{
|
||||||
MH_Uninitialize();
|
MH_Uninitialize();
|
||||||
}
|
}
|
||||||
} __;
|
} min_hook_init;
|
||||||
|
return &min_hook_init;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void assembler::pushad64()
|
void assembler::pushad64()
|
||||||
@ -95,11 +99,18 @@ namespace utils::hook
|
|||||||
return Assembler::jmp(size_t(target));
|
return Assembler::jmp(size_t(target));
|
||||||
}
|
}
|
||||||
|
|
||||||
detour::detour(const size_t place, void* target) : detour(reinterpret_cast<void*>(place), target)
|
detour::detour()
|
||||||
|
{
|
||||||
|
(void)initialize_min_hook();
|
||||||
|
}
|
||||||
|
|
||||||
|
detour::detour(const size_t place, void* target)
|
||||||
|
: detour(reinterpret_cast<void*>(place), target)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
detour::detour(void* place, void* target)
|
detour::detour(void* place, void* target)
|
||||||
|
: detour()
|
||||||
{
|
{
|
||||||
this->create(place, target);
|
this->create(place, target);
|
||||||
}
|
}
|
||||||
|
@ -85,7 +85,7 @@ namespace utils::hook
|
|||||||
class detour
|
class detour
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
detour() = default;
|
detour();
|
||||||
detour(void* place, void* target);
|
detour(void* place, void* target);
|
||||||
detour(size_t place, void* target);
|
detour(size_t place, void* target);
|
||||||
~detour();
|
~detour();
|
||||||
|
Loading…
Reference in New Issue
Block a user