From ebd2dbc29e9b06797db1f36d3a7d29d43a31d35c Mon Sep 17 00:00:00 2001 From: momo5502 Date: Mon, 28 Oct 2024 19:05:24 +0100 Subject: [PATCH] Initialize emulator using settings struct --- src/analyzer/main.cpp | 6 ++-- src/fuzzer/main.cpp | 6 ++-- src/windows-emulator-test/emulation_test.cpp | 12 +++---- .../emulation_test_utils.hpp | 14 ++++++++ .../serialization_test.cpp | 12 +++---- src/windows-emulator/windows_emulator.cpp | 36 ++++++++++++------- src/windows-emulator/windows_emulator.hpp | 12 +++++-- 7 files changed, 64 insertions(+), 34 deletions(-) diff --git a/src/analyzer/main.cpp b/src/analyzer/main.cpp index 87fc37eb..d6a60574 100644 --- a/src/analyzer/main.cpp +++ b/src/analyzer/main.cpp @@ -62,10 +62,12 @@ namespace void run(const std::string_view application) { - windows_emulator win_emu{ - application, {} + const emulator_settings settings{ + .application = application, }; + windows_emulator win_emu{settings}; + (void)&watch_system_objects; //watch_system_objects(win_emu); win_emu.buffer_stdout = true; diff --git a/src/fuzzer/main.cpp b/src/fuzzer/main.cpp index 785796da..de088639 100644 --- a/src/fuzzer/main.cpp +++ b/src/fuzzer/main.cpp @@ -144,10 +144,12 @@ namespace void run(const std::string_view application) { - windows_emulator win_emu{ - application, {} + const emulator_settings settings{ + .application = application, }; + windows_emulator win_emu{settings}; + forward_emulator(win_emu); run_fuzzer(win_emu); } diff --git a/src/windows-emulator-test/emulation_test.cpp b/src/windows-emulator-test/emulation_test.cpp index 708e617e..bddf56e3 100644 --- a/src/windows-emulator-test/emulation_test.cpp +++ b/src/windows-emulator-test/emulation_test.cpp @@ -4,8 +4,7 @@ namespace test { TEST(EmulationTest, BasicEmulationWorks) { - windows_emulator emu{"./test-sample.exe"}; - emu.logger.disable_output(true); + auto emu = create_sample_emulator(); emu.start(); ASSERT_TERMINATED_SUCCESSFULLY(emu); @@ -15,8 +14,7 @@ namespace test { constexpr auto count = 200000; - windows_emulator emu{"./test-sample.exe"}; - emu.logger.disable_output(true); + auto emu = create_sample_emulator(); emu.start({}, count); ASSERT_EQ(emu.process().executed_instructions, count); @@ -24,16 +22,14 @@ namespace test TEST(EmulationTest, CountedEmulationIsAccurate) { - windows_emulator emu{"./test-sample.exe"}; - emu.logger.disable_output(true); + auto emu = create_sample_emulator(); emu.start(); ASSERT_TERMINATED_SUCCESSFULLY(emu); const auto executedInstructions = emu.process().executed_instructions; - windows_emulator new_emu{"./test-sample.exe"}; - new_emu.logger.disable_output(true); + auto new_emu = create_sample_emulator(); constexpr auto offset = 1; const auto instructionsToExecute = executedInstructions - offset; diff --git a/src/windows-emulator-test/emulation_test_utils.hpp b/src/windows-emulator-test/emulation_test_utils.hpp index dc9d64ba..c3b8122c 100644 --- a/src/windows-emulator-test/emulation_test_utils.hpp +++ b/src/windows-emulator-test/emulation_test_utils.hpp @@ -17,3 +17,17 @@ #define ASSERT_TERMINATED_SUCCESSFULLY(win_emu) \ ASSERT_TERMINATED_WITH_STATUS(win_emu, STATUS_SUCCESS) + +namespace test +{ + inline windows_emulator create_sample_emulator() + { + const emulator_settings settings + { + .application = "./test-sample.exe", + .disable_logging = true, + }; + + return windows_emulator{settings}; + } +} diff --git a/src/windows-emulator-test/serialization_test.cpp b/src/windows-emulator-test/serialization_test.cpp index dfc42580..e8305cda 100644 --- a/src/windows-emulator-test/serialization_test.cpp +++ b/src/windows-emulator-test/serialization_test.cpp @@ -4,8 +4,7 @@ namespace test { TEST(SerializationTest, SerializedDataIsReproducible) { - windows_emulator emu1{"./test-sample.exe"}; - emu1.logger.disable_output(true); + auto emu1 = create_sample_emulator(); emu1.start(); ASSERT_TERMINATED_SUCCESSFULLY(emu1); @@ -29,8 +28,7 @@ namespace test TEST(SerializationTest, EmulationIsReproducible) { - windows_emulator emu1{"./test-sample.exe"}; - emu1.logger.disable_output(true); + auto emu1 = create_sample_emulator(); emu1.start(); ASSERT_TERMINATED_SUCCESSFULLY(emu1); @@ -38,8 +36,7 @@ namespace test utils::buffer_serializer serializer1{}; emu1.serialize(serializer1); - windows_emulator emu2{"./test-sample.exe"}; - emu2.logger.disable_output(true); + auto emu2 = create_sample_emulator(); emu2.start(); ASSERT_TERMINATED_SUCCESSFULLY(emu2); @@ -52,8 +49,7 @@ namespace test TEST(SerializationTest, DeserializedEmulatorBehavesLikeSource) { - windows_emulator emu{"./test-sample.exe"}; - emu.logger.disable_output(true); + auto emu = create_sample_emulator(); emu.start({}, 100); utils::buffer_serializer serializer{}; diff --git a/src/windows-emulator/windows_emulator.cpp b/src/windows-emulator/windows_emulator.cpp index bd30130d..621ea073 100644 --- a/src/windows-emulator/windows_emulator.cpp +++ b/src/windows-emulator/windows_emulator.cpp @@ -246,8 +246,12 @@ namespace emu.reg(x64_register::ss, 0x2B); } - void setup_context(process_context& context, x64_emulator& emu, const std::filesystem::path& file, - const std::vector& arguments) + std::filesystem::path canonicalize_path(const std::filesystem::path& path) + { + return canonical(absolute(path).parent_path()).make_preferred(); + } + + void setup_context(process_context& context, x64_emulator& emu, const emulator_settings& settings) { setup_gdt(emu); @@ -289,19 +293,27 @@ namespace allocator.copy_string(L"COMPUTERNAME=momo"); allocator.copy_string(L""); - std::wstring command_line = L"\"" + file.wstring() + L"\""; + std::wstring command_line = L"\"" + settings.application.wstring() + L"\""; - for (const auto& arg : arguments) + for (const auto& arg : settings.arguments) { command_line.push_back(L' '); command_line.append(arg); } - const auto current_folder = canonical(absolute(file).parent_path()).make_preferred().wstring() + L"\\"; + std::wstring current_folder{}; + if (!settings.working_directory.empty()) + { + current_folder = canonicalize_path(settings.working_directory).wstring() + L"\\"; + } + else + { + current_folder = canonicalize_path(settings.application).parent_path().wstring() + L"\\"; + } allocator.make_unicode_string(proc_params.CommandLine, command_line); allocator.make_unicode_string(proc_params.CurrentDirectory.DosPath, current_folder); - allocator.make_unicode_string(proc_params.ImagePathName, file.wstring()); + allocator.make_unicode_string(proc_params.ImagePathName, canonicalize_path(settings.application).wstring()); const auto total_length = allocator.get_next_address() - context.process_params.value(); @@ -724,11 +736,12 @@ std::unique_ptr create_default_x64_emulator() return unicorn::create_x64_emulator(); } -windows_emulator::windows_emulator(const std::filesystem::path& application, const std::vector& arguments, +windows_emulator::windows_emulator(const emulator_settings& settings, std::unique_ptr emu) : windows_emulator(std::move(emu)) { - this->setup_process(application, arguments); + this->logger.disable_output(settings.disable_logging); + this->setup_process(settings); } windows_emulator::windows_emulator(std::unique_ptr emu) @@ -738,17 +751,16 @@ windows_emulator::windows_emulator(std::unique_ptr emu) this->setup_hooks(); } -void windows_emulator::setup_process(const std::filesystem::path& application, - const std::vector& arguments) +void windows_emulator::setup_process(const emulator_settings& settings) { auto& emu = this->emu(); auto& context = this->process(); context.module_manager = module_manager(emu); // TODO: Cleanup module manager - setup_context(context, emu, application, arguments); + setup_context(context, emu, settings); - context.executable = context.module_manager.map_module(application, this->logger); + context.executable = context.module_manager.map_module(settings.application, this->logger); context.peb.access([&](PEB& peb) { diff --git a/src/windows-emulator/windows_emulator.hpp b/src/windows-emulator/windows_emulator.hpp index 6651d2c0..7ae773ec 100644 --- a/src/windows-emulator/windows_emulator.hpp +++ b/src/windows-emulator/windows_emulator.hpp @@ -9,11 +9,19 @@ std::unique_ptr create_default_x64_emulator(); +struct emulator_settings +{ + std::filesystem::path application; + std::filesystem::path working_directory; + std::vector arguments; + bool disable_logging{false}; +}; + class windows_emulator { public: windows_emulator(std::unique_ptr emu = create_default_x64_emulator()); - windows_emulator(const std::filesystem::path& application, const std::vector& arguments = {}, + windows_emulator(const emulator_settings& settings, std::unique_ptr emu = create_default_x64_emulator()); windows_emulator(windows_emulator&&) = delete; @@ -97,5 +105,5 @@ private: //std::optional process_snapshot_{}; void setup_hooks(); - void setup_process(const std::filesystem::path& application, const std::vector& arguments); + void setup_process(const emulator_settings& settings); };