stabilize html frame
This commit is contained in:
parent
92e456e756
commit
945d65d2e3
@ -2,39 +2,64 @@
|
|||||||
#include "html_frame.hpp"
|
#include "html_frame.hpp"
|
||||||
|
|
||||||
#include <utils/nt.hpp>
|
#include <utils/nt.hpp>
|
||||||
|
#include <utils/hook.hpp>
|
||||||
|
|
||||||
std::atomic<int> html_frame::frame_count_ = 0;
|
std::atomic<int> 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<decltype(co_internet_feature_value_internal_stub)*>(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)
|
html_frame::callback_params::callback_params(DISPPARAMS* params, VARIANT* res) : result(res)
|
||||||
{
|
{
|
||||||
for (auto i = params->cArgs; i > 0; --i)
|
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);
|
this->arguments.emplace_back(param);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
html_frame::html_frame()
|
html_frame::html_frame() : in_place_frame_(this), in_place_site_(this), ui_handler_(this), client_site_(this),
|
||||||
: in_place_frame_(this)
|
html_dispatch_(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)
|
if (frame_count_++ == 0 && OleInitialize(nullptr) != S_OK)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Unable to initialize the OLE library");
|
throw std::runtime_error("Unable to initialize the OLE library");
|
||||||
}
|
}
|
||||||
|
|
||||||
auto needs_restart = false;
|
set_browser_feature("FEATURE_BROWSER_EMULATION", 11000);
|
||||||
needs_restart |= set_browser_feature("FEATURE_BROWSER_EMULATION", 11000);
|
set_browser_feature("FEATURE_GPU_RENDERING", 1);
|
||||||
needs_restart |= set_browser_feature("FEATURE_GPU_RENDERING", 1);
|
|
||||||
|
|
||||||
if (needs_restart)
|
|
||||||
{
|
|
||||||
utils::nt::relaunch_self();
|
|
||||||
utils::nt::terminate(0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
html_frame::~html_frame()
|
html_frame::~html_frame()
|
||||||
|
@ -15,7 +15,8 @@ namespace utils::nt
|
|||||||
library library::get_by_address(void* address)
|
library library::get_by_address(void* address)
|
||||||
{
|
{
|
||||||
HMODULE handle = nullptr;
|
HMODULE handle = nullptr;
|
||||||
GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, static_cast<LPCSTR>(address), &handle);
|
GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
|
||||||
|
static_cast<LPCSTR>(address), &handle);
|
||||||
return library(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
|
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;
|
if (!this->is_valid()) return nullptr;
|
||||||
|
|
||||||
@ -166,7 +172,7 @@ namespace utils::nt
|
|||||||
auto* const target_function = other_module.get_proc<void*>(proc_name);
|
auto* const target_function = other_module.get_proc<void*>(proc_name);
|
||||||
if (!target_function) return nullptr;
|
if (!target_function) return nullptr;
|
||||||
|
|
||||||
auto* header = this->get_optional_header();
|
const auto* header = this->get_optional_header();
|
||||||
if (!header) return nullptr;
|
if (!header) return nullptr;
|
||||||
|
|
||||||
auto* import_descriptor = reinterpret_cast<PIMAGE_IMPORT_DESCRIPTOR>(this->get_ptr() + header->DataDirectory
|
auto* import_descriptor = reinterpret_cast<PIMAGE_IMPORT_DESCRIPTOR>(this->get_ptr() + header->DataDirectory
|
||||||
@ -183,16 +189,22 @@ namespace utils::nt
|
|||||||
|
|
||||||
while (original_thunk_data->u1.AddressOfData)
|
while (original_thunk_data->u1.AddressOfData)
|
||||||
{
|
{
|
||||||
const size_t ordinal_number = original_thunk_data->u1.AddressOfData & 0xFFFFFFF;
|
if (thunk_data->u1.Function == reinterpret_cast<uint64_t>(target_function))
|
||||||
|
|
||||||
if (ordinal_number > 0xFFFF) continue;
|
|
||||||
|
|
||||||
if (GetProcAddress(other_module.module_, reinterpret_cast<char*>(ordinal_number)) ==
|
|
||||||
target_function)
|
|
||||||
{
|
{
|
||||||
return reinterpret_cast<void**>(&thunk_data->u1.Function);
|
return reinterpret_cast<void**>(&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<char*>(ordinal_number));
|
||||||
|
if (reinterpret_cast<void*>(proc) == target_function)
|
||||||
|
{
|
||||||
|
return reinterpret_cast<void**>(&thunk_data->u1.Function);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
++original_thunk_data;
|
++original_thunk_data;
|
||||||
++thunk_data;
|
++thunk_data;
|
||||||
}
|
}
|
||||||
|
@ -59,6 +59,13 @@ namespace utils::nt
|
|||||||
return reinterpret_cast<T>(GetProcAddress(this->module_, process.data()));
|
return reinterpret_cast<T>(GetProcAddress(this->module_, process.data()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T get_proc(const char* name) const
|
||||||
|
{
|
||||||
|
if (!this->is_valid()) T{};
|
||||||
|
return reinterpret_cast<T>(GetProcAddress(this->module_, name));
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::function<T> get(const std::string& process) const
|
std::function<T> get(const std::string& process) const
|
||||||
{
|
{
|
||||||
@ -97,6 +104,7 @@ namespace utils::nt
|
|||||||
PIMAGE_OPTIONAL_HEADER get_optional_header() const;
|
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 std::string& proc_name) const;
|
||||||
|
void** get_iat_entry(const std::string& module_name, const char* name) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HMODULE module_;
|
HMODULE module_;
|
||||||
|
Loading…
Reference in New Issue
Block a user