From 32fcbf3ded7cd3c14b6659b94108b6130aa3582b Mon Sep 17 00:00:00 2001 From: momo5502 Date: Tue, 3 Jun 2025 20:29:58 +0200 Subject: [PATCH] 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... --- src/windows-emulator/event_manager.cpp | 2 + src/windows-emulator/event_manager.hpp | 98 +++++++++++++++++++++ src/windows-emulator/generic_logger.hpp | 28 ++++++ src/windows-emulator/logger.cpp | 7 +- src/windows-emulator/logger.hpp | 26 +----- src/windows-emulator/syscall_dispatcher.cpp | 10 ++- 6 files changed, 144 insertions(+), 27 deletions(-) create mode 100644 src/windows-emulator/event_manager.cpp create mode 100644 src/windows-emulator/event_manager.hpp create mode 100644 src/windows-emulator/generic_logger.hpp diff --git a/src/windows-emulator/event_manager.cpp b/src/windows-emulator/event_manager.cpp new file mode 100644 index 00000000..e20376ce --- /dev/null +++ b/src/windows-emulator/event_manager.cpp @@ -0,0 +1,2 @@ +#include "std_include.hpp" +#include "event_manager.hpp" diff --git a/src/windows-emulator/event_manager.hpp b/src/windows-emulator/event_manager.hpp new file mode 100644 index 00000000..26a2c98b --- /dev/null +++ b/src/windows-emulator/event_manager.hpp @@ -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 +struct typed_event : event +{ + using event::event; + + event_type get_type() const override + { + return Type; + } +}; + +template +class rich_event : typed_event +{ + 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 +{ + 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_{}; +}; diff --git a/src/windows-emulator/generic_logger.hpp b/src/windows-emulator/generic_logger.hpp new file mode 100644 index 00000000..54c48a50 --- /dev/null +++ b/src/windows-emulator/generic_logger.hpp @@ -0,0 +1,28 @@ +#pragma once +#include + +#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; +}; diff --git a/src/windows-emulator/logger.cpp b/src/windows-emulator/logger.cpp index 292bdfb6..3ad989cb 100644 --- a/src/windows-emulator/logger.cpp +++ b/src/windows-emulator/logger.cpp @@ -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); diff --git a/src/windows-emulator/logger.hpp b/src/windows-emulator/logger.hpp index aafcbb9c..f91be95e 100644 --- a/src/windows-emulator/logger.hpp +++ b/src/windows-emulator/logger.hpp @@ -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); diff --git a/src/windows-emulator/syscall_dispatcher.cpp b/src/windows-emulator/syscall_dispatcher.cpp index 164da74b..9495f630 100644 --- a/src/windows-emulator/syscall_dispatcher.cpp +++ b/src/windows-emulator/syscall_dispatcher.cpp @@ -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 ntdll_data, - const exported_symbols& win32u_exports, std::span win32u_data) +void syscall_dispatcher::setup(const exported_symbols& ntdll_exports, const std::span ntdll_data, + const exported_symbols& win32u_exports, const std::span 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 ntdll_data, - const exported_symbols& win32u_exports, std::span win32u_data) +syscall_dispatcher::syscall_dispatcher(const exported_symbols& ntdll_exports, + const std::span ntdll_data, + const exported_symbols& win32u_exports, + const std::span win32u_data) { this->setup(ntdll_exports, ntdll_data, win32u_exports, win32u_data); }