From d1493867fe00257fc5b8a9ae00bb143868caabb6 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Sun, 10 Nov 2024 15:34:21 +0100 Subject: [PATCH] Support relative and absolute time This fixes #23 --- src/emulator/serialization.hpp | 12 ++++++++++ .../emulation_test_utils.hpp | 1 + src/windows-emulator/syscalls.cpp | 21 +++++++++++++----- src/windows-emulator/windows_emulator.cpp | 22 +++++++++++++++---- src/windows-emulator/windows_emulator.hpp | 9 +++++++- 5 files changed, 55 insertions(+), 10 deletions(-) diff --git a/src/emulator/serialization.hpp b/src/emulator/serialization.hpp index f40625e..f4938df 100644 --- a/src/emulator/serialization.hpp +++ b/src/emulator/serialization.hpp @@ -433,6 +433,12 @@ namespace utils std::vector buffer_{}; }; + template <> + inline void buffer_deserializer::read(bool& object) + { + object = this->read() != 0; + } + template <> inline void buffer_deserializer::read(std::string& object) { @@ -445,6 +451,12 @@ namespace utils object = this->read_string(); } + template <> + inline void buffer_serializer::write(const bool& object) + { + this->write(object ? 1 : 0); + } + template <> inline void buffer_serializer::write(const std::string& object) { diff --git a/src/windows-emulator-test/emulation_test_utils.hpp b/src/windows-emulator-test/emulation_test_utils.hpp index c3b8122..f874329 100644 --- a/src/windows-emulator-test/emulation_test_utils.hpp +++ b/src/windows-emulator-test/emulation_test_utils.hpp @@ -26,6 +26,7 @@ namespace test { .application = "./test-sample.exe", .disable_logging = true, + .use_relative_time = true, }; return windows_emulator{settings}; diff --git a/src/windows-emulator/syscalls.cpp b/src/windows-emulator/syscalls.cpp index be62047..e134a67 100644 --- a/src/windows-emulator/syscalls.cpp +++ b/src/windows-emulator/syscalls.cpp @@ -22,17 +22,28 @@ namespace { performance_counter.access([&](LARGE_INTEGER& value) { - value.QuadPart = static_cast(c.proc.executed_instructions); - //QueryPerformanceCounter(&value); + if (c.win_emu.time_is_relative()) + { + value.QuadPart = static_cast(c.proc.executed_instructions); + } + else + { + value.QuadPart = std::chrono::steady_clock::now().time_since_epoch().count(); + } }); } if (performance_frequency) { - performance_frequency.access([](LARGE_INTEGER& value) + int64_t frequency{}; + c.proc.kusd.access([&](const KUSER_SHARED_DATA& kusd) + { + frequency = kusd.QpcFrequency; + }); + + performance_frequency.access([&](LARGE_INTEGER& value) { - value.QuadPart = 10000; - //QueryPerformanceFrequency(&value); + value.QuadPart = frequency; }); } diff --git a/src/windows-emulator/windows_emulator.cpp b/src/windows-emulator/windows_emulator.cpp index f23277c..00e5ccd 100644 --- a/src/windows-emulator/windows_emulator.cpp +++ b/src/windows-emulator/windows_emulator.cpp @@ -1,5 +1,6 @@ #include "std_include.hpp" #include "windows_emulator.hpp" + #include "context_frame.hpp" #include @@ -49,14 +50,14 @@ namespace emu.write_register(x64_register::msr, &value, sizeof(value)); } - emulator_object setup_kusd(x64_emulator& emu) + emulator_object setup_kusd(x64_emulator& emu, bool use_relative_time) { // TODO: Fix that. Use hooks to feed dynamic data, e.g. time values emu.allocate_memory(KUSD_ADDRESS, page_align_up(sizeof(KUSER_SHARED_DATA)), memory_permission::read); const emulator_object kusd_object{emu, KUSD_ADDRESS}; - kusd_object.access([](KUSER_SHARED_DATA& kusd) + kusd_object.access([&](KUSER_SHARED_DATA& kusd) { kusd.TickCountMultiplier = 0x0fa00000; kusd.InterruptTime.LowPart = 0x17bd9547; @@ -114,7 +115,15 @@ namespace kusd.XState.EnabledFeatures = 0x000000000000001f; kusd.XState.EnabledVolatileFeatures = 0x000000000000000f; kusd.XState.Size = 0x000003c0; - kusd.QpcFrequency = 1000; + + if (use_relative_time) + { + kusd.QpcFrequency = 1000; + } + else + { + kusd.QpcFrequency = std::chrono::steady_clock::period::den; + } constexpr std::wstring_view root_dir{L"C:\\WINDOWS"}; memcpy(&kusd.NtSystemRoot.arr[0], root_dir.data(), root_dir.size() * 2); @@ -259,7 +268,7 @@ namespace context.registry = registry_manager(settings.registry_directory); - context.kusd = setup_kusd(emu); + context.kusd = setup_kusd(emu, settings.use_relative_time); context.base_allocator = create_allocator(emu, PEB_SEGMENT_SIZE); auto& allocator = context.base_allocator; @@ -767,6 +776,7 @@ windows_emulator::windows_emulator(const emulator_settings& settings, std::unique_ptr emu) : windows_emulator(std::move(emu)) { + this->use_relative_time_ = settings.use_relative_time; this->logger.disable_output(settings.disable_logging); this->setup_process(settings); } @@ -1028,6 +1038,7 @@ void windows_emulator::start(std::chrono::nanoseconds timeout, size_t count) void windows_emulator::serialize(utils::buffer_serializer& buffer) const { + buffer.write(this->use_relative_time_); this->emu().serialize(buffer); this->process_.serialize(buffer); this->dispatcher_.serialize(buffer); @@ -1040,6 +1051,9 @@ void windows_emulator::deserialize(utils::buffer_deserializer& buffer) return emulator_thread(this->emu()); }); + + buffer.read(this->use_relative_time_); + this->emu().deserialize(buffer); this->process_.deserialize(buffer); this->dispatcher_.deserialize(buffer); diff --git a/src/windows-emulator/windows_emulator.hpp b/src/windows-emulator/windows_emulator.hpp index fb61ec2..23bce87 100644 --- a/src/windows-emulator/windows_emulator.hpp +++ b/src/windows-emulator/windows_emulator.hpp @@ -16,6 +16,7 @@ struct emulator_settings std::filesystem::path registry_directory{"./registry"}; std::vector arguments{}; bool disable_logging{false}; + bool use_relative_time{false}; }; class windows_emulator @@ -95,11 +96,17 @@ class windows_emulator void yield_thread(); void perform_thread_switch(); + bool time_is_relative() const + { + return this->use_relative_time_; + } + private: + bool use_relative_time_{false}; std::unique_ptr emu_{}; - std::vector syscall_hooks_{}; + process_context process_; syscall_dispatcher dispatcher_;