Prepare event manager

The event manager forms the basis for semantic logging.
The emulator transmits events and the manager can handle them.
This means to either print information to stdout, do nothing, etc...
This commit is contained in:
momo5502
2025-06-03 20:29:58 +02:00
parent dcee2982ce
commit 32fcbf3ded
6 changed files with 144 additions and 27 deletions

View File

@@ -0,0 +1,2 @@
#include "std_include.hpp"
#include "event_manager.hpp"

View File

@@ -0,0 +1,98 @@
#pragma once
#include "logger.hpp"
struct mapped_module;
struct windows_emulator;
enum class event_type
{
syscall,
function_call,
};
struct event : utils::object
{
event() = default;
event(event&&) = delete;
event& operator=(event&&) = delete;
event(const event&) = delete;
event& operator=(const event&) = delete;
virtual event_type get_type() const = 0;
virtual void print(const generic_logger& log) const
{
(void)log;
}
};
template <event_type Type>
struct typed_event : event
{
using event::event;
event_type get_type() const override
{
return Type;
}
};
template <event_type Type, typename Data>
class rich_event : typed_event<Type>
{
public:
rich_event(windows_emulator& win_emu, Data data)
: win_emu(&win_emu),
data(std::move(data))
{
}
const Data& get_data() const
{
return this->data;
}
protected:
windows_emulator* win_emu{};
Data data{};
};
struct syscall_data
{
uint32_t id{};
std::string_view name{};
};
struct syscall_event : rich_event<event_type::syscall, syscall_data>
{
struct extended_info
{
uint64_t address{};
mapped_module* origin{};
};
extended_info get_extended_info() const;
};
struct event_manager : utils::object
{
virtual void handle(const event& e);
};
class printing_event_manager : public event_manager
{
public:
printing_event_manager(generic_logger& log)
: logger_(&log)
{
}
void handle(const event& e) override
{
e.print(*this->logger_);
}
private:
generic_logger* logger_{};
};

View File

@@ -0,0 +1,28 @@
#pragma once
#include <utils/object.hpp>
#if defined(__clang__) || defined(__GNUC__)
#define FORMAT_ATTRIBUTE(fmt_pos, var_pos) __attribute__((format(printf, fmt_pos, var_pos)))
#else
#define FORMAT_ATTRIBUTE(fmt_pos, var_pos)
#endif
enum class color
{
black,
red,
green,
yellow,
blue,
cyan,
pink,
white,
gray,
dark_gray,
};
struct generic_logger : utils::object
{
virtual void print(color c, std::string_view message) = 0;
virtual void print(color c, const char* message, ...) FORMAT_ATTRIBUTE(3, 4) = 0;
};

View File

@@ -116,8 +116,13 @@ void logger::print_message(const color c, const std::string_view message, const
print_colored(message, get_color_type(c));
}
void logger::print(const color c, const std::string_view message)
{
this->print_message(c, message);
}
// NOLINTNEXTLINE(cert-dcl50-cpp)
void logger::print(const color c, const char* message, ...) const
void logger::print(const color c, const char* message, ...)
{
format_to_string(message, data);
this->print_message(c, data);

View File

@@ -1,29 +1,11 @@
#pragma once
#include "generic_logger.hpp"
#ifdef OS_WINDOWS
#define FORMAT_ATTRIBUTE(fmt_pos, var_pos)
#else
#define FORMAT_ATTRIBUTE(fmt_pos, var_pos) __attribute__((format(printf, fmt_pos, var_pos)))
#endif
enum class color
{
black,
red,
green,
yellow,
blue,
cyan,
pink,
white,
gray,
dark_gray,
};
class logger
class logger : public generic_logger
{
public:
void print(color c, const char* message, ...) const FORMAT_ATTRIBUTE(3, 4);
void print(color c, std::string_view message) override;
void print(color c, const char* message, ...) override FORMAT_ATTRIBUTE(3, 4);
void info(const char* message, ...) const FORMAT_ATTRIBUTE(2, 3);
void warn(const char* message, ...) const FORMAT_ATTRIBUTE(2, 3);
void error(const char* message, ...) const FORMAT_ATTRIBUTE(2, 3);

View File

@@ -24,8 +24,8 @@ void syscall_dispatcher::deserialize(utils::buffer_deserializer& buffer)
this->add_handlers();
}
void syscall_dispatcher::setup(const exported_symbols& ntdll_exports, std::span<const std::byte> ntdll_data,
const exported_symbols& win32u_exports, std::span<const std::byte> win32u_data)
void syscall_dispatcher::setup(const exported_symbols& ntdll_exports, const std::span<const std::byte> ntdll_data,
const exported_symbols& win32u_exports, const std::span<const std::byte> win32u_data)
{
this->handlers_ = {};
@@ -150,8 +150,10 @@ void syscall_dispatcher::dispatch(windows_emulator& win_emu)
}
}
syscall_dispatcher::syscall_dispatcher(const exported_symbols& ntdll_exports, std::span<const std::byte> ntdll_data,
const exported_symbols& win32u_exports, std::span<const std::byte> win32u_data)
syscall_dispatcher::syscall_dispatcher(const exported_symbols& ntdll_exports,
const std::span<const std::byte> ntdll_data,
const exported_symbols& win32u_exports,
const std::span<const std::byte> win32u_data)
{
this->setup(ntdll_exports, ntdll_data, win32u_exports, win32u_data);
}