diff --git a/src/client/launcher/html/html_frame.cpp b/src/client/launcher/html/html_frame.cpp
index d844ffec..277fd4da 100644
--- a/src/client/launcher/html/html_frame.cpp
+++ b/src/client/launcher/html/html_frame.cpp
@@ -2,39 +2,64 @@
#include "html_frame.hpp"
#include
+#include
std::atomic html_frame::frame_count_ = 0;
+namespace
+{
+ void* original_func{};
+ GUID browser_emulation_guid{ 0xac969931, 0x3566, 0x4b50, {0xae, 0x48, 0x71, 0xb9, 0x6a, 0x75, 0xc8, 0x79} };
+
+ int WINAPI co_internet_feature_value_internal_stub(const GUID* guid, uint32_t* result)
+ {
+ const auto res = static_cast(original_func)(guid, result);
+
+ if (IsEqualGUID(*guid, browser_emulation_guid))
+ {
+ *result = 11000;
+ return 0;
+ }
+
+ return res;
+ }
+
+ void setup_ie_hook()
+ {
+ static const auto _ = []
+ {
+ const auto urlmon = utils::nt::library::load("urlmon.dll"s);
+ const auto target = urlmon.get_iat_entry("iertutil.dll", MAKEINTRESOURCEA(700));
+
+ original_func = *target;
+ utils::hook::set(target, co_internet_feature_value_internal_stub);
+
+ return 0;
+ }();
+ (void)_;
+ }
+}
+
html_frame::callback_params::callback_params(DISPPARAMS* params, VARIANT* res) : result(res)
{
for (auto i = params->cArgs; i > 0; --i)
{
- auto* param = ¶ms->rgvarg[i - 1];
+ auto param = ¶ms->rgvarg[i - 1];
this->arguments.emplace_back(param);
}
}
-html_frame::html_frame()
- : in_place_frame_(this)
- , in_place_site_(this)
- , ui_handler_(this)
- , client_site_(this)
- , html_dispatch_(this)
+html_frame::html_frame() : in_place_frame_(this), in_place_site_(this), ui_handler_(this), client_site_(this),
+html_dispatch_(this)
{
+ setup_ie_hook();
if (frame_count_++ == 0 && OleInitialize(nullptr) != S_OK)
{
throw std::runtime_error("Unable to initialize the OLE library");
}
- auto needs_restart = false;
- needs_restart |= set_browser_feature("FEATURE_BROWSER_EMULATION", 11000);
- needs_restart |= set_browser_feature("FEATURE_GPU_RENDERING", 1);
-
- if (needs_restart)
- {
- utils::nt::relaunch_self();
- utils::nt::terminate(0);
- }
+ set_browser_feature("FEATURE_BROWSER_EMULATION", 11000);
+ set_browser_feature("FEATURE_GPU_RENDERING", 1);
}
html_frame::~html_frame()
diff --git a/src/common/utils/nt.cpp b/src/common/utils/nt.cpp
index 4cead0fa..12ae6109 100644
--- a/src/common/utils/nt.cpp
+++ b/src/common/utils/nt.cpp
@@ -15,7 +15,8 @@ namespace utils::nt
library library::get_by_address(void* address)
{
HMODULE handle = nullptr;
- GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, static_cast(address), &handle);
+ GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
+ static_cast(address), &handle);
return library(handle);
}
@@ -157,6 +158,11 @@ namespace utils::nt
}
void** library::get_iat_entry(const std::string& module_name, const std::string& proc_name) const
+ {
+ return this->get_iat_entry(module_name, proc_name.data());
+ }
+
+ void** library::get_iat_entry(const std::string& module_name, const char* proc_name) const
{
if (!this->is_valid()) return nullptr;
@@ -166,7 +172,7 @@ namespace utils::nt
auto* const target_function = other_module.get_proc(proc_name);
if (!target_function) return nullptr;
- auto* header = this->get_optional_header();
+ const auto* header = this->get_optional_header();
if (!header) return nullptr;
auto* import_descriptor = reinterpret_cast(this->get_ptr() + header->DataDirectory
@@ -183,16 +189,22 @@ namespace utils::nt
while (original_thunk_data->u1.AddressOfData)
{
- const size_t ordinal_number = original_thunk_data->u1.AddressOfData & 0xFFFFFFF;
-
- if (ordinal_number > 0xFFFF) continue;
-
- if (GetProcAddress(other_module.module_, reinterpret_cast(ordinal_number)) ==
- target_function)
+ if (thunk_data->u1.Function == reinterpret_cast(target_function))
{
return reinterpret_cast(&thunk_data->u1.Function);
}
+ const size_t ordinal_number = original_thunk_data->u1.AddressOfData & 0xFFFFFFF;
+
+ if (ordinal_number <= 0xFFFF)
+ {
+ auto* proc = GetProcAddress(other_module.module_, reinterpret_cast(ordinal_number));
+ if (reinterpret_cast(proc) == target_function)
+ {
+ return reinterpret_cast(&thunk_data->u1.Function);
+ }
+ }
+
++original_thunk_data;
++thunk_data;
}
diff --git a/src/common/utils/nt.hpp b/src/common/utils/nt.hpp
index c4f58afe..df48c6c5 100644
--- a/src/common/utils/nt.hpp
+++ b/src/common/utils/nt.hpp
@@ -59,6 +59,13 @@ namespace utils::nt
return reinterpret_cast(GetProcAddress(this->module_, process.data()));
}
+ template
+ T get_proc(const char* name) const
+ {
+ if (!this->is_valid()) T{};
+ return reinterpret_cast(GetProcAddress(this->module_, name));
+ }
+
template
std::function get(const std::string& process) const
{
@@ -97,6 +104,7 @@ namespace utils::nt
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;
private:
HMODULE module_;