added more callbacks

This commit is contained in:
Elias Bachaalany
2025-02-10 11:25:04 -08:00
parent 760bb9318f
commit 1d7f841ee4
10 changed files with 35 additions and 16 deletions

View File

@@ -136,7 +136,7 @@ namespace
if (options.silent)
{
win_emu.buffer_stdout = false;
win_emu.callbacks.stdout_callback = [](const std::string_view data) {
win_emu.callbacks().stdout_callback = [](const std::string_view data) {
(void)fwrite(data.data(), 1, data.size(), stdout);
};
}

View File

@@ -27,19 +27,13 @@ namespace utils
{
}
optional_function& operator=(std::function<Ret(Args...)> f)
template <typename F, typename = std::enable_if_t<std::is_invocable_r_v<Ret, F, Args...>>>
optional_function& operator=(F&& f)
{
func = std::move(f);
func = std::forward<F>(f);
return *this;
}
template <typename T>
requires(!std::is_same_v<std::remove_cvref_t<T>, std::function<Ret(Args...)>>)
optional_function& operator=(T&& t)
{
return this->operator=(std::function<Ret(Args...)>(std::forward<T>(t)));
}
Ret operator()(Args... args) const
{
if (func)

View File

@@ -95,6 +95,7 @@ mapped_module* module_manager::map_local_module(const std::filesystem::path& fil
const auto image_base = mod.image_base;
const auto entry = this->modules_.try_emplace(image_base, std::move(mod));
this->on_module_load(entry.first->second);
return &entry.first->second;
}
catch (const std::exception& e)
@@ -146,6 +147,7 @@ bool module_manager::unmap(const uint64_t address, const logger& logger)
logger.log("Unmapping %s (0x%" PRIx64 ")\n", mod->second.path.generic_string().c_str(), mod->second.image_base);
this->on_module_unload(mod->second);
unmap_module(*this->memory_, mod->second);
this->modules_.erase(mod);

View File

@@ -3,6 +3,7 @@
#include "mapped_module.hpp"
#include "../file_system.hpp"
#include <utils/function.hpp>
class logger;
@@ -10,6 +11,9 @@ class module_manager
{
public:
using module_map = std::map<uint64_t, mapped_module>;
utils::optional_function<void(mapped_module& mod)> on_module_load{};
utils::optional_function<void(mapped_module& mod)> on_module_unload{};
module_manager(memory_manager& memory, file_system& file_sys);
void map_main_modules(const windows_path& executable_path, const windows_path& ntdll_path,

View File

@@ -201,5 +201,7 @@ handle process_context::create_thread(memory_manager& memory, const uint64_t sta
const uint64_t stack_size)
{
emulator_thread t{memory, *this, start_address, argument, stack_size, ++this->spawned_thread_count};
return this->threads.store(std::move(t));
auto h = this->threads.store(std::move(t));
on_create_thread(h, *this->threads.get(h));
return h;
}

View File

@@ -44,6 +44,8 @@ struct process_context
const emulator_settings& emu_settings, const mapped_module& executable, const mapped_module& ntdll,
const apiset::container& apiset_container);
utils::optional_function<void(handle h, emulator_thread& thr)> on_create_thread{};
handle create_thread(memory_manager& memory, const uint64_t start_address, const uint64_t argument,
const uint64_t stack_size);

View File

@@ -91,7 +91,7 @@ void syscall_dispatcher::dispatch(windows_emulator& win_emu)
const auto* mod = win_emu.mod_manager.find_by_address(address);
if (mod != win_emu.mod_manager.ntdll && mod != win_emu.mod_manager.win32u)
{
win_emu.callbacks.inline_syscall(syscall_id, address, mod ? mod->name.c_str() : "<N/A>",
win_emu.callbacks().inline_syscall(syscall_id, address, mod ? mod->name.c_str() : "<N/A>",
entry->second.name);
win_emu.log.print(color::blue, "Executing inline syscall: %s (0x%X) at 0x%" PRIx64 " (%s)\n",
@@ -116,7 +116,7 @@ void syscall_dispatcher::dispatch(windows_emulator& win_emu)
{
const auto* previous_mod = win_emu.mod_manager.find_by_address(context.previous_ip);
win_emu.callbacks.outofline_syscall(syscall_id, address, mod ? mod->name.c_str() : "<N/A>",
win_emu.callbacks().outofline_syscall(syscall_id, address, mod ? mod->name.c_str() : "<N/A>",
entry->second.name, context.previous_ip,
previous_mod ? previous_mod->name.c_str() : "<N/A>");

View File

@@ -2878,7 +2878,7 @@ namespace
io_status_block.write(block);
}
c.win_emu.callbacks.stdout_callback(temp_buffer);
c.win_emu.callbacks().stdout_callback(temp_buffer);
if (!temp_buffer.ends_with("\n"))
{
@@ -3613,6 +3613,7 @@ namespace
}
thread->exit_status = exit_status;
c.win_emu.callbacks().thread_terminated(thread_handle, *thread);
if (thread == c.proc.active_thread)
{
c.win_emu.yield_thread();

View File

@@ -172,7 +172,7 @@ windows_emulator::windows_emulator(application_settings app_settings, const emul
emulator_callbacks callbacks, std::unique_ptr<x64_emulator> emu)
: windows_emulator(settings, std::move(emu))
{
this->callbacks = std::move(callbacks);
this->callbacks_ = std::move(callbacks);
fixup_application_settings(app_settings);
this->setup_process(app_settings, settings);
@@ -220,6 +220,10 @@ void windows_emulator::setup_process(const application_settings& app_settings, c
const auto& emu = this->emu();
auto& context = this->process;
mod_manager.on_module_load = [this](mapped_module& mod) { this->callbacks().module_loaded(mod); };
mod_manager.on_module_unload = [this](mapped_module& mod) { this->callbacks().module_unloaded(mod); };
context.on_create_thread = [this](handle h, emulator_thread& thr) { this->callbacks().thread_created(h, thr); };
this->mod_manager.map_main_modules(app_settings.application, R"(C:\Windows\System32\ntdll.dll)",
R"(C:\Windows\System32\win32u.dll)", this->log);

View File

@@ -23,6 +23,10 @@ struct emulator_callbacks
std::string_view syscall_name, x64_emulator::pointer_type prev_address,
std::string_view prev_mod_name)>
outofline_syscall{};
utils::optional_function<void(mapped_module& mod)> module_loaded{};
utils::optional_function<void(mapped_module& mod)> module_unloaded{};
utils::optional_function<void(handle h, emulator_thread& thr)> thread_created{};
utils::optional_function<void(handle h, emulator_thread& thr)> thread_terminated{};
};
struct application_settings
@@ -53,7 +57,6 @@ class windows_emulator
public:
std::filesystem::path emulation_root{};
emulator_callbacks callbacks{};
logger log{};
file_system file_sys;
memory_manager memory;
@@ -161,11 +164,18 @@ class windows_emulator
return this->use_relative_time_;
}
emulator_callbacks& callbacks()
{
return this->callbacks_;
}
private:
bool switch_thread_{false};
bool use_relative_time_{false};
bool silent_until_main_{false};
emulator_callbacks callbacks_{};
std::vector<instruction_hook_callback> syscall_hooks_{};
std::unordered_map<uint16_t, uint16_t> port_mappings_{};