Event manager progress

This commit is contained in:
momo5502
2025-06-04 18:52:59 +02:00
parent 32fcbf3ded
commit 25295707ec
4 changed files with 110 additions and 70 deletions

View File

@@ -1,2 +1,45 @@
#include "std_include.hpp"
#include "event_manager.hpp"
#include "windows_emulator.hpp"
void syscall_event::print(generic_logger& log) const
{
auto& win = *this->win_emu;
auto& emu = win.emu();
const auto address = emu.read_instruction_pointer();
const auto* mod = win.mod_manager.find_by_address(address);
if (mod != win.mod_manager.ntdll && mod != win.mod_manager.win32u)
{
log.print(color::blue, "Executing inline syscall: %.*s (0x%X) at 0x%" PRIx64 " (%s)\n",
static_cast<int>(this->data.name.size()), this->data.name.data(), this->data.id, address,
mod ? mod->name.c_str() : "<N/A>");
}
else
{
if (mod->is_within(win_emu->process.previous_ip))
{
const auto rsp = emu.read_stack_pointer();
uint64_t return_address{};
emu.try_read_memory(rsp, &return_address, sizeof(return_address));
const auto* caller_mod_name = win.mod_manager.find_name(return_address);
log.print(color::dark_gray, "Executing syscall: %.*s (0x%X) at 0x%" PRIx64 " via 0x%" PRIx64 " (%s)\n",
static_cast<int>(this->data.name.size()), this->data.name.data(), this->data.id, address,
return_address, caller_mod_name);
}
else
{
const auto* previous_mod = win.mod_manager.find_by_address(win.process.previous_ip);
log.print(color::blue,
"Crafted out-of-line syscall: %.*s (0x%X) at 0x%" PRIx64 " (%s) via 0x%" PRIx64 " (%s)\n",
static_cast<int>(this->data.name.size()), this->data.name.data(), this->data.id, address,
mod ? mod->name.c_str() : "<N/A>", win.process.previous_ip,
previous_mod ? previous_mod->name.c_str() : "<N/A>");
}
}
}

View File

@@ -2,82 +2,98 @@
#include "logger.hpp"
struct mapped_module;
struct windows_emulator;
class windows_emulator;
enum class event_type
enum class emulation_event_type
{
syscall,
function_call,
};
struct event : utils::object
struct emulation_event : utils::object
{
event() = default;
emulation_event() = default;
event(event&&) = delete;
event& operator=(event&&) = delete;
event(const event&) = delete;
event& operator=(const event&) = delete;
emulation_event(emulation_event&&) = delete;
emulation_event& operator=(emulation_event&&) = delete;
emulation_event(const emulation_event&) = delete;
emulation_event& operator=(const emulation_event&) = delete;
virtual event_type get_type() const = 0;
virtual emulation_event_type get_type() const = 0;
virtual void print(const generic_logger& log) const
virtual void print(generic_logger& log) const
{
(void)log;
}
};
template <event_type Type>
struct typed_event : event
template <emulation_event_type Type>
struct typed_event : emulation_event
{
using event::event;
using emulation_event::emulation_event;
event_type get_type() const override
emulation_event_type get_type() const override
{
return Type;
}
};
template <event_type Type, typename Data>
class rich_event : typed_event<Type>
struct empty_data
{
};
template <emulation_event_type Type, typename Input = empty_data, typename Output = empty_data>
class rich_event : public typed_event<Type>
{
public:
rich_event(windows_emulator& win_emu, Data data)
rich_event(windows_emulator& win_emu, Input input = {}, Output output = {})
: win_emu(&win_emu),
data(std::move(data))
in(std::move(input))
{
}
const Data& get_data() const
const Input& get_input() const
{
return this->data;
return this->in;
}
Output& get_output()
{
return this->out;
}
const Output& get_output() const
{
return this->out;
}
protected:
windows_emulator* win_emu{};
Data data{};
Input in{};
Output out{};
};
struct syscall_data
struct syscall_input
{
uint32_t id{};
std::string_view name{};
};
struct syscall_event : rich_event<event_type::syscall, syscall_data>
struct syscall_output
{
struct extended_info
{
uint64_t address{};
mapped_module* origin{};
};
bool skip{false};
};
extended_info get_extended_info() const;
struct syscall_event : rich_event<emulation_event_type::syscall, syscall_input, syscall_output>
{
using rich_event::rich_event;
void print(generic_logger& log) const override;
};
struct event_manager : utils::object
{
virtual void handle(const event& e);
virtual void handle(emulation_event& e);
};
class printing_event_manager : public event_manager
@@ -88,7 +104,7 @@ class printing_event_manager : public event_manager
{
}
void handle(const event& e) override
void handle(emulation_event& e) override
{
e.print(*this->logger_);
}

View File

@@ -87,9 +87,14 @@ void syscall_dispatcher::dispatch(windows_emulator& win_emu)
return;
}
const std::string_view mod_name = mod ? mod->name : std::string_view{};
const auto res = win_emu.callbacks.on_syscall(syscall_id, address, mod_name, entry->second.name);
if (res == instruction_hook_continuation::skip_instruction)
syscall_event e(c.win_emu, {
.id = syscall_id,
.name = entry->second.name,
});
c.win_emu.manager().handle(e);
if (e.get_output().skip)
{
return;
}
@@ -102,38 +107,6 @@ void syscall_dispatcher::dispatch(windows_emulator& win_emu)
return;
}
if (mod != win_emu.mod_manager.ntdll && mod != win_emu.mod_manager.win32u)
{
win_emu.log.print(color::blue, "Executing inline syscall: %s (0x%X) at 0x%" PRIx64 " (%s)\n",
entry->second.name.c_str(), syscall_id, address, mod ? mod->name.c_str() : "<N/A>");
}
else
{
if (mod->is_within(context.previous_ip))
{
const auto rsp = c.emu.read_stack_pointer();
uint64_t return_address{};
c.emu.try_read_memory(rsp, &return_address, sizeof(return_address));
const auto* caller_mod_name = win_emu.mod_manager.find_name(return_address);
win_emu.log.print(color::dark_gray,
"Executing syscall: %s (0x%X) at 0x%" PRIx64 " via 0x%" PRIx64 " (%s)\n",
entry->second.name.c_str(), syscall_id, address, return_address, caller_mod_name);
}
else
{
const auto* previous_mod = win_emu.mod_manager.find_by_address(context.previous_ip);
win_emu.log.print(color::blue,
"Crafted out-of-line syscall: %s (0x%X) at 0x%" PRIx64 " (%s) via 0x%" PRIx64
" (%s)\n",
entry->second.name.c_str(), syscall_id, address, mod ? mod->name.c_str() : "<N/A>",
context.previous_ip, previous_mod ? previous_mod->name.c_str() : "<N/A>");
}
}
entry->second.handler(c);
}
catch (std::exception& e)

View File

@@ -5,6 +5,7 @@
#include <utils/function.hpp>
#include "event_manager.hpp"
#include "syscall_dispatcher.hpp"
#include "process_context.hpp"
#include "logger.hpp"
@@ -15,10 +16,6 @@
struct emulator_callbacks : module_manager::callbacks, process_context::callbacks
{
utils::optional_function<instruction_hook_continuation(uint32_t syscall_id, x86_64_emulator::pointer_type address,
std::string_view mod_name, std::string_view syscall_name)>
on_syscall{};
utils::optional_function<void(std::string_view)> on_stdout{};
};
@@ -58,6 +55,7 @@ class windows_emulator
std::unique_ptr<x86_64_emulator> emu_{};
std::unique_ptr<utils::clock> clock_{};
std::unique_ptr<network::socket_factory> socket_factory_{};
std::unique_ptr<event_manager> event_manager_{};
public:
std::filesystem::path emulation_root{};
@@ -93,6 +91,16 @@ class windows_emulator
return *this->emu_;
}
event_manager& manager()
{
return *this->event_manager_;
}
event_manager& manager() const
{
return *this->event_manager_;
}
utils::clock& clock()
{
return *this->clock_;