some boiii launcher stuff
This commit is contained in:
parent
945d65d2e3
commit
c1e2a29ee2
@ -21,10 +21,10 @@ namespace redirect
|
||||
ZeroMemory(&process_info, sizeof(process_info));
|
||||
startup_info.cb = sizeof(startup_info);
|
||||
|
||||
auto* arguments = const_cast<char*>(utils::string::va("%s%s%s", self.get_path().data(),
|
||||
auto* arguments = const_cast<char*>(utils::string::va("%s%s%s", self.get_path().generic_string().data(),
|
||||
(singleplayer ? " -singleplayer" : " -multiplayer"),
|
||||
(mode.empty() ? "" : (" +"s + mode).data())));
|
||||
CreateProcessA(self.get_path().data(), arguments, nullptr, nullptr, false, NULL, nullptr, nullptr,
|
||||
CreateProcessA(self.get_path().generic_string().data(), arguments, nullptr, nullptr, false, NULL, nullptr, nullptr,
|
||||
&startup_info, &process_info);
|
||||
|
||||
if (process_info.hThread && process_info.hThread != INVALID_HANDLE_VALUE)
|
||||
|
@ -1,8 +1,8 @@
|
||||
#include <std_include.hpp>
|
||||
#include "html_frame.hpp"
|
||||
|
||||
#include <utils/nt.hpp>
|
||||
#include <utils/hook.hpp>
|
||||
#include "utils/nt.hpp"
|
||||
#include "utils/io.hpp"
|
||||
#include "utils/hook.hpp"
|
||||
|
||||
std::atomic<int> html_frame::frame_count_ = 0;
|
||||
|
||||
@ -24,7 +24,57 @@ namespace
|
||||
return res;
|
||||
}
|
||||
|
||||
void setup_ie_hook()
|
||||
void patch_cached_browser_emulator(const utils::nt::library& urlmon)
|
||||
{
|
||||
std::string data{};
|
||||
if (!utils::io::read_file(urlmon.get_path().generic_string(), &data))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const utils::nt::library file_lib(reinterpret_cast<HMODULE>(data.data()));
|
||||
|
||||
auto translate_file_offset_to_rva = [&](const size_t file_offset) -> size_t
|
||||
{
|
||||
const auto sections = file_lib.get_section_headers();
|
||||
for (const auto* section : sections)
|
||||
{
|
||||
if (section->PointerToRawData <= file_offset && section->PointerToRawData + section->SizeOfRawData > file_offset)
|
||||
{
|
||||
const auto section_va = file_offset - section->PointerToRawData;
|
||||
return section_va + section->VirtualAddress;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
const auto guid_pos = data.find(std::string(reinterpret_cast<const char*>(&browser_emulation_guid), sizeof(browser_emulation_guid)));
|
||||
if (guid_pos == std::string::npos)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto guid_rva = translate_file_offset_to_rva(guid_pos);
|
||||
const auto guid_va = reinterpret_cast<GUID*>(urlmon.get_ptr() + guid_rva);
|
||||
|
||||
if (!IsEqualGUID(*guid_va, browser_emulation_guid))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const size_t unrelocated_guid_va = file_lib.get_optional_header()->ImageBase + guid_rva;
|
||||
const auto guid_ptr_pos = data.find(std::string(reinterpret_cast<const char*>(&unrelocated_guid_va), sizeof(unrelocated_guid_va)));
|
||||
if (guid_ptr_pos == std::string::npos)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto guid_ptr_rva = translate_file_offset_to_rva(guid_ptr_pos);
|
||||
*reinterpret_cast<GUID**>(urlmon.get_ptr() + guid_ptr_rva) = guid_va;
|
||||
}
|
||||
|
||||
void setup_ie_hooks()
|
||||
{
|
||||
static const auto _ = []
|
||||
{
|
||||
@ -34,6 +84,8 @@ namespace
|
||||
original_func = *target;
|
||||
utils::hook::set(target, co_internet_feature_value_internal_stub);
|
||||
|
||||
patch_cached_browser_emulator(urlmon);
|
||||
|
||||
return 0;
|
||||
}();
|
||||
(void)_;
|
||||
@ -52,7 +104,7 @@ html_frame::callback_params::callback_params(DISPPARAMS* params, VARIANT* res) :
|
||||
html_frame::html_frame() : in_place_frame_(this), in_place_site_(this), ui_handler_(this), client_site_(this),
|
||||
html_dispatch_(this)
|
||||
{
|
||||
setup_ie_hook();
|
||||
setup_ie_hooks();
|
||||
if (frame_count_++ == 0 && OleInitialize(nullptr) != S_OK)
|
||||
{
|
||||
throw std::runtime_error("Unable to initialize the OLE library");
|
||||
|
@ -50,7 +50,7 @@ void window::close()
|
||||
{
|
||||
if (!this->handle_) return;
|
||||
|
||||
SendMessageA(this->handle_, WM_KILL_WINDOW, NULL, NULL);
|
||||
DestroyWindow(this->handle_);
|
||||
this->handle_ = nullptr;
|
||||
}
|
||||
|
||||
|
@ -164,12 +164,41 @@ void remove_crash_file()
|
||||
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")
|
||||
? user32.get_proc<BOOL(WINAPI*)(DPI_AWARENESS_CONTEXT)>(
|
||||
"SetProcessDpiAwarenessContext")
|
||||
: nullptr;
|
||||
if (set_dpi)
|
||||
{
|
||||
set_dpi(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const utils::nt::library shcore{"shcore.dll"};
|
||||
const auto set_dpi = shcore
|
||||
? shcore.get_proc<HRESULT(WINAPI*)(PROCESS_DPI_AWARENESS)>(
|
||||
"SetProcessDpiAwareness")
|
||||
: nullptr;
|
||||
if (set_dpi)
|
||||
{
|
||||
set_dpi(PROCESS_PER_MONITOR_DPI_AWARE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const auto set_dpi = user32
|
||||
? user32.get_proc<BOOL(WINAPI*)()>(
|
||||
"SetProcessDPIAware")
|
||||
: nullptr;
|
||||
if (set_dpi)
|
||||
{
|
||||
set_dpi();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,6 +48,7 @@
|
||||
#include <atlbase.h>
|
||||
#include <iphlpapi.h>
|
||||
#include <wincrypt.h>
|
||||
#include <shellscalingapi.h>
|
||||
|
||||
// min and max is required by gdi, therefore NOMINMAX won't work
|
||||
#ifdef max
|
||||
|
@ -118,29 +118,29 @@ namespace utils::nt
|
||||
{
|
||||
if (!this->is_valid()) return "";
|
||||
|
||||
auto path = this->get_path();
|
||||
const auto pos = path.find_last_of("/\\");
|
||||
if (pos == std::string::npos) return path;
|
||||
const auto path = this->get_path();
|
||||
const auto pos = path.generic_string().find_last_of("/\\");
|
||||
if (pos == std::string::npos) return path.generic_string();
|
||||
|
||||
return path.substr(pos + 1);
|
||||
return path.generic_string().substr(pos + 1);
|
||||
}
|
||||
|
||||
std::string library::get_path() const
|
||||
std::filesystem::path library::get_path() const
|
||||
{
|
||||
if (!this->is_valid()) return "";
|
||||
if (!this->is_valid()) return {};
|
||||
|
||||
char name[MAX_PATH] = {0};
|
||||
GetModuleFileNameA(this->module_, name, sizeof name);
|
||||
wchar_t name[MAX_PATH] = { 0 };
|
||||
GetModuleFileNameW(this->module_, name, MAX_PATH);
|
||||
|
||||
return name;
|
||||
return { name };
|
||||
}
|
||||
|
||||
std::string library::get_folder() const
|
||||
{
|
||||
if (!this->is_valid()) return "";
|
||||
|
||||
const auto path = std::filesystem::path(this->get_path());
|
||||
return path.parent_path().generic_string();
|
||||
std::filesystem::path library::get_folder() const
|
||||
{
|
||||
if (!this->is_valid()) return {};
|
||||
|
||||
return this->get_path().parent_path().generic_string();
|
||||
}
|
||||
|
||||
void library::free()
|
||||
@ -157,7 +157,7 @@ namespace utils::nt
|
||||
return this->module_;
|
||||
}
|
||||
|
||||
void** library::get_iat_entry(const std::string& module_name, const std::string& proc_name) const
|
||||
void** library::get_iat_entry(const std::string& module_name, std::string proc_name) const
|
||||
{
|
||||
return this->get_iat_entry(module_name, proc_name.data());
|
||||
}
|
||||
@ -220,15 +220,13 @@ namespace utils::nt
|
||||
|
||||
bool is_wine()
|
||||
{
|
||||
static std::optional<bool> is_wine = {};
|
||||
|
||||
if (!is_wine.has_value())
|
||||
static const auto has_wine_export = []() -> bool
|
||||
{
|
||||
const utils::nt::library ntdll("ntdll.dll");
|
||||
is_wine = ntdll.get_proc<void*>("wine_get_version") != nullptr;
|
||||
}
|
||||
const library ntdll("ntdll.dll");
|
||||
return ntdll.get_proc<void*>("wine_get_version");
|
||||
}();
|
||||
|
||||
return is_wine.value();
|
||||
return has_wine_export;
|
||||
}
|
||||
|
||||
void raise_hard_exception()
|
||||
@ -277,7 +275,7 @@ namespace utils::nt
|
||||
}
|
||||
}
|
||||
|
||||
CreateProcessA(self.get_path().data(), command_line.data(), nullptr, nullptr, false, NULL, nullptr, current_dir,
|
||||
CreateProcessA(self.get_path().generic_string().data(), command_line.data(), nullptr, nullptr, false, NULL, nullptr, current_dir,
|
||||
&startup_info, &process_info);
|
||||
|
||||
if (process_info.hThread && process_info.hThread != INVALID_HANDLE_VALUE) CloseHandle(process_info.hThread);
|
||||
@ -287,5 +285,6 @@ namespace utils::nt
|
||||
void terminate(const uint32_t code)
|
||||
{
|
||||
TerminateProcess(GetCurrentProcess(), code);
|
||||
_Exit(code);
|
||||
}
|
||||
}
|
||||
|
@ -40,30 +40,29 @@ namespace utils::nt
|
||||
operator HMODULE() const;
|
||||
|
||||
void unprotect() const;
|
||||
void* get_entry_point() const;
|
||||
size_t get_relative_entry_point() const;
|
||||
[[nodiscard]] void* get_entry_point() const;
|
||||
[[nodiscard]] size_t get_relative_entry_point() const;
|
||||
|
||||
bool is_valid() const;
|
||||
std::string get_name() const;
|
||||
std::string get_path() const;
|
||||
std::string get_folder() const;
|
||||
std::uint8_t* get_ptr() const;
|
||||
[[nodiscard]] bool is_valid() const;
|
||||
[[nodiscard]] std::string get_name() const;
|
||||
[[nodiscard]] std::filesystem::path get_path() const;
|
||||
[[nodiscard]] std::filesystem::path get_folder() const;
|
||||
[[nodiscard]] std::uint8_t* get_ptr() const;
|
||||
void free();
|
||||
|
||||
HMODULE get_handle() const;
|
||||
[[nodiscard]] HMODULE get_handle() const;
|
||||
|
||||
template <typename T>
|
||||
T get_proc(const std::string& process) const
|
||||
[[nodiscard]] T get_proc(const char* process) const
|
||||
{
|
||||
if (!this->is_valid()) T{};
|
||||
return reinterpret_cast<T>(GetProcAddress(this->module_, process.data()));
|
||||
return reinterpret_cast<T>(GetProcAddress(this->module_, process));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T get_proc(const char* name) const
|
||||
[[nodiscard]] T get_proc(const std::string& process) const
|
||||
{
|
||||
if (!this->is_valid()) T{};
|
||||
return reinterpret_cast<T>(GetProcAddress(this->module_, name));
|
||||
return get_proc<T>(process.data());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -97,14 +96,14 @@ namespace utils::nt
|
||||
return T();
|
||||
}
|
||||
|
||||
std::vector<PIMAGE_SECTION_HEADER> get_section_headers() const;
|
||||
[[nodiscard]] std::vector<PIMAGE_SECTION_HEADER> get_section_headers() const;
|
||||
|
||||
PIMAGE_NT_HEADERS get_nt_headers() const;
|
||||
PIMAGE_DOS_HEADER get_dos_header() const;
|
||||
PIMAGE_OPTIONAL_HEADER get_optional_header() const;
|
||||
[[nodiscard]] PIMAGE_NT_HEADERS get_nt_headers() const;
|
||||
[[nodiscard]] PIMAGE_DOS_HEADER get_dos_header() const;
|
||||
[[nodiscard]] PIMAGE_OPTIONAL_HEADER get_optional_header() const;
|
||||
|
||||
void** get_iat_entry(const std::string& module_name, const std::string& proc_name) const;
|
||||
void** get_iat_entry(const std::string& module_name, const char* name) const;
|
||||
[[nodiscard]] void** get_iat_entry(const std::string& module_name, std::string proc_name) const;
|
||||
[[nodiscard]] void** get_iat_entry(const std::string& module_name, const char* proc_name) const;
|
||||
|
||||
private:
|
||||
HMODULE module_;
|
||||
|
Loading…
Reference in New Issue
Block a user