mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-18 11:13:57 +00:00
exposing high level callbacks to win_emu
This commit is contained in:
@@ -20,10 +20,10 @@
|
||||
|
||||
namespace test
|
||||
{
|
||||
inline windows_emulator create_sample_emulator(emulator_settings settings)
|
||||
inline windows_emulator create_sample_emulator(emulator_settings settings, emulator_callbacks callbacks = {})
|
||||
{
|
||||
settings.application = "./test-sample.exe";
|
||||
return windows_emulator{std::move(settings)};
|
||||
return windows_emulator{std::move(settings), std::move(callbacks)};
|
||||
}
|
||||
|
||||
inline windows_emulator create_sample_emulator()
|
||||
|
||||
@@ -6,14 +6,17 @@ namespace test
|
||||
{
|
||||
std::string output_buffer{};
|
||||
|
||||
emulator_callbacks callbacks{
|
||||
.stdout_callback = [&output_buffer](const std::string_view data) { output_buffer.append(data); },
|
||||
};
|
||||
|
||||
const emulator_settings settings{
|
||||
.arguments = {u"-time"},
|
||||
.stdout_callback = [&output_buffer](const std::string_view data) { output_buffer.append(data); },
|
||||
.disable_logging = true,
|
||||
.use_relative_time = false,
|
||||
};
|
||||
|
||||
auto emu = create_sample_emulator(settings);
|
||||
auto emu = create_sample_emulator(settings, callbacks);
|
||||
emu.start();
|
||||
|
||||
constexpr auto prefix = "Time: "sv;
|
||||
|
||||
@@ -91,6 +91,8 @@ void syscall_dispatcher::dispatch(windows_emulator& win_emu)
|
||||
const auto* mod = context.mod_manager.find_by_address(address);
|
||||
if (mod != context.ntdll && mod != context.win32u)
|
||||
{
|
||||
win_emu.on_inline_syscall(syscall_id, address, mod ? mod->name.c_str() : "<N/A>",
|
||||
entry->second.name.c_str());
|
||||
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>");
|
||||
}
|
||||
@@ -109,6 +111,9 @@ void syscall_dispatcher::dispatch(windows_emulator& win_emu)
|
||||
else
|
||||
{
|
||||
const auto* previous_mod = context.mod_manager.find_by_address(context.previous_ip);
|
||||
win_emu.on_outofline_syscall(syscall_id, address, mod ? mod->name.c_str() : "<N/A>",
|
||||
entry->second.name.c_str(), context.previous_ip,
|
||||
previous_mod ? previous_mod->name.c_str() : "<N/A>");
|
||||
win_emu.log.print(color::blue,
|
||||
"Crafted out-of-line syscall: %s (0x%X) at 0x%" PRIx64 " (%s) via 0x%" PRIx64
|
||||
" (%s)\n",
|
||||
|
||||
@@ -742,13 +742,14 @@ std::unique_ptr<x64_emulator> create_default_x64_emulator()
|
||||
return unicorn::create_x64_emulator();
|
||||
}
|
||||
|
||||
windows_emulator::windows_emulator(emulator_settings settings, std::unique_ptr<x64_emulator> emu)
|
||||
windows_emulator::windows_emulator(emulator_settings settings, emulator_callbacks callbacks,
|
||||
std::unique_ptr<x64_emulator> emu)
|
||||
: windows_emulator(std::move(emu))
|
||||
{
|
||||
this->silent_until_main_ = settings.silent_until_main && !settings.disable_logging;
|
||||
this->stdout_callback_ = std::move(settings.stdout_callback);
|
||||
this->use_relative_time_ = settings.use_relative_time;
|
||||
this->log.disable_output(settings.disable_logging || this->silent_until_main_);
|
||||
this->callbacks_ = std::move(callbacks);
|
||||
this->setup_process(settings);
|
||||
}
|
||||
|
||||
@@ -1054,3 +1055,30 @@ void windows_emulator::restore_snapshot()
|
||||
this->process_.deserialize(deserializer);
|
||||
// this->process_ = *this->process_snapshot_;
|
||||
}
|
||||
|
||||
void windows_emulator::on_stdout(const std::string_view data) const
|
||||
{
|
||||
if (this->callbacks_.stdout_callback)
|
||||
{
|
||||
this->callbacks_.stdout_callback(data);
|
||||
}
|
||||
}
|
||||
|
||||
void windows_emulator::on_inline_syscall(uint32_t syscall_id, const x64_emulator::pointer_type address,
|
||||
const std::string_view mod_name, const std::string_view name)
|
||||
{
|
||||
if (this->callbacks_.inline_syscall)
|
||||
{
|
||||
this->callbacks_.inline_syscall(syscall_id, address, mod_name, name);
|
||||
}
|
||||
}
|
||||
|
||||
void windows_emulator::on_outofline_syscall(uint32_t syscall_id, x64_emulator::pointer_type address,
|
||||
std::string_view mod_name, std::string_view syscall_name,
|
||||
x64_emulator::pointer_type prev_address, std::string_view prev_mod_name)
|
||||
{
|
||||
if (this->callbacks_.outofline_syscall)
|
||||
{
|
||||
this->callbacks_.outofline_syscall(syscall_id, address, mod_name, syscall_name, prev_address, prev_mod_name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,17 @@
|
||||
|
||||
std::unique_ptr<x64_emulator> create_default_x64_emulator();
|
||||
|
||||
struct emulator_callbacks
|
||||
{
|
||||
std::function<void(std::string_view)> stdout_callback{};
|
||||
std::function<void(uint32_t syscall_id, x64_emulator::pointer_type address, std::string_view mod_name,
|
||||
std::string_view syscall_name)>
|
||||
inline_syscall{};
|
||||
std::function<void(uint32_t syscall_id, x64_emulator::pointer_type address, std::string_view mod_name,
|
||||
std::string_view syscall_name, x64_emulator::pointer_type prev_address, std::string_view prev_mod_name)>
|
||||
outofline_syscall{};
|
||||
};
|
||||
|
||||
// TODO: Split up into application and emulator settings
|
||||
struct emulator_settings
|
||||
{
|
||||
@@ -16,7 +27,6 @@ struct emulator_settings
|
||||
std::filesystem::path working_directory{};
|
||||
std::filesystem::path registry_directory{"./registry"};
|
||||
std::vector<std::u16string> arguments{};
|
||||
std::function<void(std::string_view)> stdout_callback{};
|
||||
bool disable_logging{false};
|
||||
bool silent_until_main{false};
|
||||
bool use_relative_time{false};
|
||||
@@ -26,7 +36,8 @@ class windows_emulator
|
||||
{
|
||||
public:
|
||||
windows_emulator(std::unique_ptr<x64_emulator> emu = create_default_x64_emulator());
|
||||
windows_emulator(emulator_settings settings, std::unique_ptr<x64_emulator> emu = create_default_x64_emulator());
|
||||
windows_emulator(emulator_settings settings, emulator_callbacks callbacks = {},
|
||||
std::unique_ptr<x64_emulator> emu = create_default_x64_emulator());
|
||||
|
||||
windows_emulator(windows_emulator&&) = delete;
|
||||
windows_emulator(const windows_emulator&) = delete;
|
||||
@@ -88,13 +99,12 @@ class windows_emulator
|
||||
this->syscall_hooks_.push_back(std::move(callback));
|
||||
}
|
||||
|
||||
void on_stdout(const std::string_view data) const
|
||||
{
|
||||
if (this->stdout_callback_)
|
||||
{
|
||||
this->stdout_callback_(data);
|
||||
}
|
||||
}
|
||||
void on_stdout(const std::string_view data) const;
|
||||
void on_inline_syscall(uint32_t syscall_id, const x64_emulator::pointer_type address,
|
||||
const std::string_view mod_name, const std::string_view name);
|
||||
void on_outofline_syscall(uint32_t syscall_id, x64_emulator::pointer_type address, std::string_view mod_name,
|
||||
std::string_view syscall_name, x64_emulator::pointer_type prev_address,
|
||||
std::string_view prev_mod_name);
|
||||
|
||||
logger log{};
|
||||
bool verbose{false};
|
||||
@@ -112,6 +122,7 @@ class windows_emulator
|
||||
}
|
||||
|
||||
private:
|
||||
emulator_callbacks callbacks_{};
|
||||
bool use_relative_time_{false};
|
||||
bool silent_until_main_{false};
|
||||
std::unique_ptr<x64_emulator> emu_{};
|
||||
|
||||
Reference in New Issue
Block a user