Move registry manager into windows emulator

This commit is contained in:
momo5502
2025-02-10 16:37:33 +01:00
parent adf632c64e
commit 7ae36a6452
9 changed files with 32 additions and 55 deletions

View File

@@ -119,8 +119,8 @@ namespace
};
const emulator_settings settings{
.registry_directory = options.registry_path,
.emulation_root = options.emulation_root,
.registry_directory = options.registry_path,
.verbose_calls = options.verbose_logging,
.disable_logging = options.silent,
.silent_until_main = options.concise_logging,

View File

@@ -42,7 +42,7 @@ namespace
struct fuzzer_executer : fuzzer::executer
{
windows_emulator emu{"./"}; // TODO: Fix root directory
windows_emulator emu{{.emulation_root = "./"}}; // TODO: Fix root directory
std::span<const std::byte> emulator_data{};
std::unordered_set<uint64_t> visited_blocks{};
const std::function<fuzzer::coverage_functor>* handler{nullptr};

View File

@@ -49,7 +49,7 @@ namespace test
utils::buffer_deserializer deserializer{serializer1.get_buffer()};
windows_emulator new_emu{get_emulator_root()};
windows_emulator new_emu{{.emulation_root = get_emulator_root()}};
new_emu.deserialize(deserializer);
utils::buffer_serializer serializer2{};
@@ -92,7 +92,7 @@ namespace test
utils::buffer_deserializer deserializer{serializer.get_buffer()};
windows_emulator new_emu{get_emulator_root()};
windows_emulator new_emu{{.emulation_root = get_emulator_root()}};
new_emu.log.disable_output(true);
new_emu.deserialize(deserializer);

View File

@@ -36,8 +36,6 @@ struct process_context
{
}
registry_manager registry{};
uint64_t executed_instructions{0};
uint64_t current_ip{0};
uint64_t previous_ip{0};
@@ -79,7 +77,6 @@ struct process_context
void serialize(utils::buffer_serializer& buffer) const
{
buffer.write(this->registry);
buffer.write(this->executed_instructions);
buffer.write(this->current_ip);
buffer.write(this->previous_ip);
@@ -118,7 +115,6 @@ struct process_context
void deserialize(utils::buffer_deserializer& buffer)
{
buffer.read(this->registry);
buffer.read(this->executed_instructions);
buffer.read(this->current_ip);
buffer.read(this->previous_ip);

View File

@@ -60,30 +60,17 @@ void registry_manager::setup()
this->add_path_mapping(machine / "system" / "CurrentControlSet", machine / "system" / "ControlSet001");
}
void registry_manager::serialize(utils::buffer_serializer& buffer) const
{
buffer.write(this->hive_path_);
}
void registry_manager::deserialize(utils::buffer_deserializer& buffer)
{
buffer.read(this->hive_path_);
this->setup();
}
utils::path_key registry_manager::normalize_path(const utils::path_key& path) const
{
const utils::path_key canonical_path = path;
for (const auto& mapping : this->path_mapping_)
{
if (is_subpath(mapping.first.get(), canonical_path.get()))
if (is_subpath(mapping.first.get(), path.get()))
{
return mapping.second.get() / canonical_path.get().lexically_relative(mapping.first.get());
return mapping.second.get() / path.get().lexically_relative(mapping.first.get());
}
}
return canonical_path.get();
return path;
}
void registry_manager::add_path_mapping(const utils::path_key& key, const utils::path_key& value)

View File

@@ -46,9 +46,6 @@ class registry_manager
registry_manager(const registry_manager&) = delete;
registry_manager& operator=(const registry_manager&) = delete;
void serialize(utils::buffer_serializer& buffer) const;
void deserialize(utils::buffer_deserializer& buffer);
std::optional<registry_key> get_key(const utils::path_key& key);
std::optional<registry_value> get_value(const registry_key& key, std::string name);

View File

@@ -84,7 +84,7 @@ namespace
c.win_emu.log.print(color::dark_gray, "--> Registry key: %s\n", u16_to_u8(key).c_str());
auto entry = c.proc.registry.get_key({key});
auto entry = c.win_emu.registry.get_key({key});
if (!entry.has_value())
{
return STATUS_OBJECT_NAME_NOT_FOUND;
@@ -187,7 +187,7 @@ namespace
const auto query_name = read_unicode_string(c.emu, value_name);
const auto value = c.proc.registry.get_value(*key, u16_to_u8(query_name));
const auto value = c.win_emu.registry.get_value(*key, u16_to_u8(query_name));
if (!value)
{
return STATUS_OBJECT_NAME_NOT_FOUND;

View File

@@ -218,10 +218,6 @@ namespace
setup_gdt(emu, memory);
// TODO: Move that out
context.registry = registry_manager(win_emu.emulation_root.empty() ? emu_settings.registry_directory
: win_emu.emulation_root / "registry");
context.kusd.setup(emu_settings.use_relative_time);
context.base_allocator = create_allocator(memory, PEB_SEGMENT_SIZE);
@@ -438,9 +434,28 @@ std::unique_ptr<x64_emulator> create_default_x64_emulator()
windows_emulator::windows_emulator(application_settings app_settings, const emulator_settings& settings,
emulator_callbacks callbacks, std::unique_ptr<x64_emulator> emu)
: windows_emulator(settings.emulation_root, std::move(emu))
: windows_emulator(settings, std::move(emu))
{
this->callbacks = std::move(callbacks);
fixup_application_settings(app_settings);
this->setup_process(app_settings, settings);
}
windows_emulator::windows_emulator(const emulator_settings& settings, std::unique_ptr<x64_emulator> emu)
: emu_(std::move(emu)),
emulation_root{settings.emulation_root.empty() ? settings.emulation_root : absolute(settings.emulation_root)},
file_sys(emulation_root.empty() ? emulation_root : emulation_root / "filesys"),
memory(*this->emu_),
registry(emulation_root.empty() ? settings.registry_directory : emulation_root / "registry"),
process(*this->emu_, memory, file_sys)
{
#ifndef OS_WINDOWS
if (this->emulation_root.empty())
{
throw std::runtime_error("Emulation root directory can not be empty!");
}
#endif
for (const auto& mapping : settings.path_mappings)
{
@@ -456,27 +471,8 @@ windows_emulator::windows_emulator(application_settings app_settings, const emul
this->silent_until_main_ = settings.silent_until_main && !settings.disable_logging;
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->modules_ = settings.modules;
this->setup_process(app_settings, settings);
}
windows_emulator::windows_emulator(const std::filesystem::path& emulation_root_directory,
std::unique_ptr<x64_emulator> emu)
: emu_(std::move(emu)),
emulation_root{emulation_root_directory.empty() ? emulation_root_directory : absolute(emulation_root_directory)},
file_sys(emulation_root.empty() ? emulation_root : emulation_root / "filesys"),
memory(*this->emu_),
process(*this->emu_, memory, file_sys)
{
#ifndef OS_WINDOWS
if (this->emulation_root.empty())
{
throw std::runtime_error("Emulation root directory can not be empty!");
}
#endif
this->setup_hooks();
}

View File

@@ -34,8 +34,8 @@ struct application_settings
struct emulator_settings
{
std::filesystem::path registry_directory{"./registry"};
std::filesystem::path emulation_root{};
std::filesystem::path registry_directory{"./registry"};
bool verbose_calls{false};
bool disable_logging{false};
@@ -65,10 +65,11 @@ class windows_emulator
logger log{};
file_system file_sys;
memory_manager memory;
registry_manager registry{};
process_context process;
syscall_dispatcher dispatcher;
windows_emulator(const std::filesystem::path& emulation_root,
windows_emulator(const emulator_settings& settings = {},
std::unique_ptr<x64_emulator> emu = create_default_x64_emulator());
windows_emulator(application_settings app_settings, const emulator_settings& settings = {},
emulator_callbacks callbacks = {},