mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-18 19:23:56 +00:00
some refactoring with optional_function (#96)
- wrapped std::function into utils::optional_function - cleaned the code accordingly in windows_emulator - using the 'emulator'/'windows_emulator' dependency implies the emulator_common as well.
This commit is contained in:
54
src/common/utils/function.hpp
Normal file
54
src/common/utils/function.hpp
Normal file
@@ -0,0 +1,54 @@
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace utils
|
||||
{
|
||||
template <typename Signature>
|
||||
class optional_function;
|
||||
|
||||
template <typename Ret, typename... Args>
|
||||
class optional_function<Ret(Args...)>
|
||||
{
|
||||
private:
|
||||
std::function<Ret(Args...)> func;
|
||||
|
||||
public:
|
||||
optional_function() = default;
|
||||
|
||||
optional_function(std::function<Ret(Args...)> f)
|
||||
: func(std::move(f))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename F, typename = std::enable_if_t<std::is_invocable_r_v<Ret, F, Args...>>>
|
||||
optional_function(F&& f)
|
||||
: func(std::forward<F>(f))
|
||||
{
|
||||
}
|
||||
|
||||
optional_function& operator=(std::function<Ret(Args...)> f)
|
||||
{
|
||||
func = std::move(f);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Ret operator()(Args... args) const
|
||||
{
|
||||
if (func)
|
||||
{
|
||||
return func(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
if constexpr (!std::is_void_v<Ret>)
|
||||
{
|
||||
return Ret();
|
||||
}
|
||||
}
|
||||
|
||||
explicit operator bool() const noexcept
|
||||
{
|
||||
return static_cast<bool>(func);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -8,4 +8,5 @@ list(SORT SRC_FILES)
|
||||
|
||||
add_library(emulator ${SRC_FILES})
|
||||
|
||||
target_link_libraries(emulator PUBLIC emulator-common)
|
||||
target_include_directories(emulator INTERFACE "${CMAKE_CURRENT_LIST_DIR}")
|
||||
|
||||
@@ -16,10 +16,7 @@ target_link_libraries(windows-emulator PRIVATE
|
||||
unicorn-emulator
|
||||
)
|
||||
|
||||
target_link_libraries(windows-emulator PUBLIC
|
||||
emulator-common
|
||||
emulator
|
||||
)
|
||||
target_link_libraries(windows-emulator PUBLIC emulator)
|
||||
|
||||
target_include_directories(windows-emulator INTERFACE "${CMAKE_CURRENT_LIST_DIR}")
|
||||
|
||||
|
||||
@@ -91,8 +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.callbacks().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>");
|
||||
}
|
||||
@@ -111,9 +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.callbacks().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",
|
||||
|
||||
@@ -2681,7 +2681,7 @@ namespace
|
||||
temp_buffer.push_back('\n');
|
||||
}
|
||||
|
||||
c.win_emu.on_stdout(temp_buffer);
|
||||
c.win_emu.callbacks().stdout_callback(temp_buffer);
|
||||
c.win_emu.log.info("%.*s", static_cast<int>(temp_buffer.size()), temp_buffer.data());
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
@@ -1141,30 +1141,3 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
|
||||
#include <x64_emulator.hpp>
|
||||
|
||||
#include <utils/function.hpp>
|
||||
|
||||
#include "syscall_dispatcher.hpp"
|
||||
#include "process_context.hpp"
|
||||
#include "logger.hpp"
|
||||
@@ -11,13 +13,13 @@ 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)>
|
||||
utils::optional_function<void(std::string_view)> stdout_callback{};
|
||||
utils::optional_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)>
|
||||
utils::optional_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{};
|
||||
};
|
||||
|
||||
@@ -108,13 +110,6 @@ class windows_emulator
|
||||
this->syscall_hooks_.push_back(std::move(callback));
|
||||
}
|
||||
|
||||
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};
|
||||
bool verbose_calls{false};
|
||||
@@ -131,6 +126,11 @@ class windows_emulator
|
||||
return this->use_relative_time_;
|
||||
}
|
||||
|
||||
emulator_callbacks& callbacks()
|
||||
{
|
||||
return this->callbacks_;
|
||||
}
|
||||
|
||||
private:
|
||||
emulator_callbacks callbacks_{};
|
||||
bool use_relative_time_{false};
|
||||
|
||||
Reference in New Issue
Block a user