mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-11 16:46:16 +00:00
added more callbacks
This commit is contained in:
@@ -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);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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>");
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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_{};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user