Start steam if necessary

This commit is contained in:
momo5502 2022-05-24 20:56:15 +02:00
parent b1c6f9de4a
commit 4b2a7c8e0b
3 changed files with 120 additions and 31 deletions

View File

@ -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
@ -9,8 +10,6 @@ namespace arxan
namespace namespace
{ {
DWORD get_steam_pid() DWORD get_steam_pid()
{
static auto steam_pid = []
{ {
HKEY reg_key; HKEY reg_key;
DWORD pid{}; DWORD pid{};
@ -24,6 +23,78 @@ namespace arxan
RegCloseKey(reg_key); RegCloseKey(reg_key);
return pid; 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);

View File

@ -7,10 +7,12 @@ namespace utils::hook
{ {
namespace namespace
{ {
[[maybe_unused]] class _ void* initialize_min_hook()
{
static class min_hook_init
{ {
public: public:
_() min_hook_init()
{ {
if (MH_Initialize() != MH_OK) if (MH_Initialize() != MH_OK)
{ {
@ -18,11 +20,13 @@ namespace utils::hook
} }
} }
~_() ~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);
} }

View File

@ -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();