2022-05-21 06:04:08 -04:00
|
|
|
#include <std_include.hpp>
|
|
|
|
|
|
|
|
#include "loader/component_loader.hpp"
|
|
|
|
|
|
|
|
#include <utils/finally.hpp>
|
|
|
|
#include <utils/hook.hpp>
|
|
|
|
#include <utils/nt.hpp>
|
|
|
|
|
|
|
|
namespace
|
|
|
|
{
|
2022-05-23 11:57:45 -04:00
|
|
|
DECLSPEC_NORETURN void WINAPI exit_hook(const int code)
|
|
|
|
{
|
|
|
|
component_loader::pre_destroy();
|
|
|
|
exit(code);
|
|
|
|
}
|
2022-05-21 06:04:08 -04:00
|
|
|
|
2022-05-23 11:57:45 -04:00
|
|
|
VOID WINAPI initialize_critical_section(const LPCRITICAL_SECTION critical_section)
|
|
|
|
{
|
|
|
|
component_loader::post_unpack();
|
|
|
|
InitializeCriticalSection(critical_section);
|
|
|
|
}
|
2022-05-21 06:04:08 -04:00
|
|
|
|
2022-05-23 11:57:45 -04:00
|
|
|
void patch_imports()
|
2022-05-21 06:04:08 -04:00
|
|
|
{
|
2022-05-23 11:57:45 -04:00
|
|
|
const utils::nt::library game{};
|
|
|
|
const auto self = utils::nt::library::get_by_address(patch_imports);
|
|
|
|
|
|
|
|
auto patch_steam_import = [&](const std::string& func)
|
2022-05-21 06:04:08 -04:00
|
|
|
{
|
2022-05-23 11:57:45 -04:00
|
|
|
const auto game_entry = game.get_iat_entry("steam_api64.dll", func);
|
|
|
|
if (!game_entry)
|
2022-05-21 06:04:08 -04:00
|
|
|
{
|
2022-05-23 11:57:45 -04:00
|
|
|
throw std::runtime_error("Import '" + func + "' not found!");
|
2022-05-21 06:04:08 -04:00
|
|
|
}
|
|
|
|
|
2022-05-23 11:57:45 -04:00
|
|
|
const auto self_proc = self.get_proc<void*>(func);
|
|
|
|
if (!self_proc)
|
2022-05-21 06:04:08 -04:00
|
|
|
{
|
2022-05-23 11:57:45 -04:00
|
|
|
throw std::runtime_error(func + " export not found");
|
2022-05-21 06:04:08 -04:00
|
|
|
}
|
2022-05-23 11:57:45 -04:00
|
|
|
utils::hook::set(game_entry, self_proc);
|
|
|
|
};
|
|
|
|
|
|
|
|
patch_steam_import("SteamAPI_RegisterCallback");
|
|
|
|
patch_steam_import("SteamAPI_RegisterCallResult");
|
|
|
|
patch_steam_import("SteamGameServer_Shutdown");
|
|
|
|
patch_steam_import("SteamGameServer_RunCallbacks");
|
|
|
|
patch_steam_import("SteamGameServer_GetHSteamPipe");
|
|
|
|
patch_steam_import("SteamGameServer_GetHSteamUser");
|
|
|
|
patch_steam_import("SteamInternal_GameServer_Init");
|
|
|
|
patch_steam_import("SteamAPI_UnregisterCallResult");
|
|
|
|
patch_steam_import("SteamAPI_UnregisterCallback");
|
|
|
|
patch_steam_import("SteamAPI_RunCallbacks");
|
|
|
|
//patch_steam_import("SteamAPI_Shutdown");
|
|
|
|
patch_steam_import("SteamInternal_CreateInterface");
|
|
|
|
patch_steam_import("SteamAPI_GetHSteamUser");
|
|
|
|
patch_steam_import("SteamAPI_GetHSteamPipe");
|
|
|
|
patch_steam_import("SteamAPI_Init");
|
|
|
|
patch_steam_import("SteamAPI_RestartAppIfNecessary");
|
|
|
|
|
|
|
|
utils::hook::set(game.get_iat_entry("kernel32.dll", "InitializeCriticalSection"), initialize_critical_section);
|
|
|
|
utils::hook::set(game.get_iat_entry("kernel32.dll", "ExitProcess"), exit_hook);
|
|
|
|
}
|
2022-05-21 06:04:08 -04:00
|
|
|
|
2022-05-23 11:57:45 -04:00
|
|
|
void enable_dpi_awareness()
|
|
|
|
{
|
|
|
|
const utils::nt::library user32{"user32.dll"};
|
|
|
|
const auto set_dpi = user32
|
|
|
|
? user32.get_proc<BOOL(WINAPI*)(DPI_AWARENESS_CONTEXT)>(
|
|
|
|
"SetProcessDpiAwarenessContext")
|
|
|
|
: nullptr;
|
|
|
|
if (set_dpi)
|
2022-05-21 06:04:08 -04:00
|
|
|
{
|
2022-05-23 11:57:45 -04:00
|
|
|
set_dpi(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
|
2022-05-21 06:04:08 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-23 11:57:45 -04:00
|
|
|
bool run()
|
|
|
|
{
|
2022-05-27 13:08:39 -04:00
|
|
|
srand(uint32_t(time(nullptr)) ^ ~(GetTickCount() * GetCurrentProcessId()));
|
2022-05-23 11:57:45 -04:00
|
|
|
|
|
|
|
{
|
|
|
|
auto premature_shutdown = true;
|
|
|
|
const auto _ = utils::finally([&premature_shutdown]()
|
|
|
|
{
|
|
|
|
if (premature_shutdown)
|
|
|
|
{
|
|
|
|
component_loader::pre_destroy();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
enable_dpi_awareness();
|
|
|
|
patch_imports();
|
|
|
|
|
|
|
|
if (!component_loader::post_load())
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
premature_shutdown = false;
|
|
|
|
}
|
|
|
|
catch (std::exception& e)
|
|
|
|
{
|
|
|
|
MessageBoxA(nullptr, e.what(), "ERROR", MB_ICONERROR);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2022-05-28 13:13:44 -04:00
|
|
|
|
|
|
|
class patch
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
patch() = default;
|
|
|
|
patch(void* source, void* target)
|
|
|
|
: source_(source)
|
|
|
|
{
|
|
|
|
memcpy(this->data_, source, sizeof(this->data_));
|
|
|
|
utils::hook::jump(this->source_, target, true, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
~patch()
|
|
|
|
{
|
|
|
|
if (source_)
|
|
|
|
{
|
|
|
|
utils::hook::copy(this->source_, this->data_, sizeof(this->data_));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
patch(patch&& obj) noexcept
|
|
|
|
: patch()
|
|
|
|
{
|
|
|
|
this->operator=(std::move(obj));
|
|
|
|
}
|
|
|
|
|
|
|
|
patch& operator=(patch&& obj) noexcept
|
|
|
|
{
|
|
|
|
if (this != &obj)
|
|
|
|
{
|
|
|
|
this->~patch();
|
|
|
|
|
|
|
|
this->source_ = obj.source_;
|
|
|
|
memcpy(this->data_, obj.data_, sizeof(this->data_));
|
|
|
|
|
|
|
|
obj.source_ = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
void* source_{ nullptr };
|
|
|
|
uint8_t data_[15]{};
|
|
|
|
};
|
|
|
|
|
|
|
|
std::vector<patch> initialization_hooks{};
|
|
|
|
|
|
|
|
uint8_t* get_entry_point()
|
|
|
|
{
|
|
|
|
const utils::nt::library game{};
|
|
|
|
return game.get_ptr() + game.get_optional_header()->AddressOfEntryPoint;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<uint8_t*> get_tls_callbacks()
|
|
|
|
{
|
|
|
|
const utils::nt::library game{};
|
|
|
|
const auto& entry = game.get_optional_header()->DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS];
|
|
|
|
if(!entry.VirtualAddress || !entry.Size)
|
|
|
|
{
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
|
|
|
const auto* tls_dir = reinterpret_cast<IMAGE_TLS_DIRECTORY*>(game.get_ptr() + entry.VirtualAddress);
|
|
|
|
auto* callback = reinterpret_cast<uint8_t**>(tls_dir->AddressOfCallBacks);
|
|
|
|
|
|
|
|
std::vector<uint8_t*> addresses{};
|
|
|
|
while(callback && *callback)
|
|
|
|
{
|
|
|
|
addresses.emplace_back(*callback);
|
|
|
|
++callback;
|
|
|
|
}
|
|
|
|
|
|
|
|
return addresses;
|
|
|
|
}
|
|
|
|
|
|
|
|
int patch_main()
|
|
|
|
{
|
|
|
|
initialization_hooks.clear();
|
|
|
|
|
|
|
|
if(!run())
|
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return reinterpret_cast<int(*)()>(get_entry_point())();
|
|
|
|
}
|
|
|
|
|
|
|
|
void nullsub()
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void patch_entry_point()
|
|
|
|
{
|
|
|
|
initialization_hooks.emplace_back(get_entry_point(), patch_main);
|
|
|
|
|
|
|
|
for(auto* tls_callback : get_tls_callbacks()) {
|
|
|
|
initialization_hooks.emplace_back(tls_callback, nullsub);
|
|
|
|
}
|
|
|
|
}
|
2022-05-21 06:04:08 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
BOOL WINAPI DllMain(HINSTANCE, const DWORD reason, LPVOID)
|
|
|
|
{
|
2022-05-23 11:57:45 -04:00
|
|
|
if (reason == DLL_PROCESS_ATTACH)
|
|
|
|
{
|
2022-05-28 13:13:44 -04:00
|
|
|
patch_entry_point();
|
2022-05-23 11:57:45 -04:00
|
|
|
}
|
|
|
|
return TRUE;
|
2022-05-21 06:04:08 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" __declspec(dllexport)
|
2022-05-23 11:57:45 -04:00
|
|
|
HRESULT D3D11CreateDevice(void* adapter, const uint64_t driver_type,
|
|
|
|
const HMODULE software, const UINT flags,
|
|
|
|
const void* p_feature_levels, const UINT feature_levels,
|
|
|
|
const UINT sdk_version, void** device, void* feature_level,
|
|
|
|
void** immediate_context)
|
2022-05-21 06:04:08 -04:00
|
|
|
{
|
2022-05-23 11:57:45 -04:00
|
|
|
static auto func = []
|
|
|
|
{
|
|
|
|
char dir[MAX_PATH]{0};
|
|
|
|
GetSystemDirectoryA(dir, sizeof(dir));
|
2022-05-21 06:04:08 -04:00
|
|
|
|
2022-05-23 11:57:45 -04:00
|
|
|
const auto d3d11 = utils::nt::library::load(dir + "/d3d11.dll"s);
|
|
|
|
return d3d11.get_proc<decltype(&D3D11CreateDevice)>("D3D11CreateDevice");
|
|
|
|
}();
|
2022-05-21 06:04:08 -04:00
|
|
|
|
2022-05-23 11:57:45 -04:00
|
|
|
return func(adapter, driver_type, software, flags, p_feature_levels, feature_levels, sdk_version, device,
|
|
|
|
feature_level, immediate_context);
|
2022-05-21 06:04:08 -04:00
|
|
|
}
|