Skip to content

Commit

Permalink
Dynamically update KUSD system time
Browse files Browse the repository at this point in the history
  • Loading branch information
momo5502 committed Nov 23, 2024
1 parent 2e2b4ff commit 422e8e5
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 4 deletions.
14 changes: 14 additions & 0 deletions src/emulator/serialization_helper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,20 @@ inline void deserialize(utils::buffer_deserializer& buffer, std::chrono::steady_
tp = time_point{duration{count}};
}

inline void serialize(utils::buffer_serializer& buffer, const std::chrono::system_clock::time_point& tp)
{
buffer.write(tp.time_since_epoch().count());
}

inline void deserialize(utils::buffer_deserializer& buffer, std::chrono::system_clock::time_point& tp)
{
using time_point = std::chrono::system_clock::time_point;
using duration = time_point::duration;

const auto count = buffer.read<duration::rep>();
tp = time_point{duration{count}};
}

inline void serialize(utils::buffer_serializer& buffer, const std::filesystem::path& path)
{
buffer.write_string<wchar_t>(path.wstring());
Expand Down
35 changes: 34 additions & 1 deletion src/windows-emulator/kusd_mmio.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "kusd_mmio.hpp"
#include "syscall_utils.hpp"
#include "windows_emulator.hpp"

#include <address_utils.hpp>
Expand Down Expand Up @@ -87,6 +88,20 @@ namespace
}
}

inline void serialize(utils::buffer_serializer& buffer, const KSYSTEM_TIME& time)
{
buffer.write(time.LowPart);
buffer.write(time.High1Time);
buffer.write(time.High2Time);
}

inline void deserialize(utils::buffer_deserializer& buffer, KSYSTEM_TIME& time)
{
buffer.read(time.LowPart);
buffer.read(time.High1Time);
buffer.read(time.High2Time);
}

inline void serialize(utils::buffer_serializer& buffer, const KUSER_SHARED_DATA& kusd)
{
static_assert(KUSD_SIZE == sizeof(kusd));
Expand All @@ -103,6 +118,7 @@ kusd_mmio::kusd_mmio(windows_emulator& win_emu, const bool use_relative_time, co
, win_emu_(&win_emu)
{
setup_kusd(this->kusd_, use_relative_time);
this->start_time_ = convert_from_ksystem_time(this->kusd_.SystemTime);

if (perform_registration)
{
Expand Down Expand Up @@ -137,12 +153,14 @@ void kusd_mmio::serialize(utils::buffer_serializer& buffer) const
{
buffer.write(this->use_relative_time_);
buffer.write(this->kusd_);
buffer.write(this->start_time_);
}

void kusd_mmio::deserialize(utils::buffer_deserializer& buffer)
{
buffer.read(this->use_relative_time_);
buffer.read(this->kusd_);
buffer.read(this->start_time_);

this->register_mmio();
}
Expand Down Expand Up @@ -185,7 +203,22 @@ void kusd_mmio::write(const uint64_t /*addr*/, const size_t /*size*/, const uint

void kusd_mmio::update()
{
// TODO
auto time = this->start_time_;

if (this->use_relative_time_)
{
const auto passed_time = this->win_emu_->process().executed_instructions;
const auto clock_frequency = this->kusd_.QpcFrequency;

using duration = std::chrono::system_clock::duration;
time += duration(passed_time * duration::period::den / clock_frequency);
}
else
{
time = std::chrono::system_clock::now();
}

convert_to_ksystem_time(&this->kusd_.SystemTime, time);
}

void kusd_mmio::register_mmio()
Expand Down
1 change: 1 addition & 0 deletions src/windows-emulator/kusd_mmio.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class kusd_mmio
bool use_relative_time_{};
windows_emulator* win_emu_{};
KUSER_SHARED_DATA kusd_{};
std::chrono::system_clock::time_point start_time_{};

uint64_t read(uint64_t addr, size_t size);
void write(uint64_t addr, size_t size, uint64_t data);
Expand Down
42 changes: 39 additions & 3 deletions src/windows-emulator/syscall_utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,11 +175,12 @@ void write_attribute(emulator& emu, const PS_ATTRIBUTE& attribute, const T& valu
}
}

constexpr auto HUNDRED_NANOSECONDS_IN_ONE_SECOND = 10000000LL;
constexpr auto EPOCH_DIFFERENCE_1601_TO_1970_SECONDS = 11644473600LL;
constexpr auto WINDOWS_EPOCH_DIFFERENCE = EPOCH_DIFFERENCE_1601_TO_1970_SECONDS * HUNDRED_NANOSECONDS_IN_ONE_SECOND;

inline std::chrono::steady_clock::time_point convert_delay_interval_to_time_point(const LARGE_INTEGER delay_interval)
{
constexpr auto HUNDRED_NANOSECONDS_IN_ONE_SECOND = 10000000LL;
constexpr auto EPOCH_DIFFERENCE_1601_TO_1970_SECONDS = 11644473600LL;

if (delay_interval.QuadPart <= 0)
{
const auto relative_time = -delay_interval.QuadPart;
Expand Down Expand Up @@ -207,3 +208,38 @@ inline std::chrono::steady_clock::time_point convert_delay_interval_to_time_poin

return std::chrono::steady_clock::now() + duration_until_target;
}

inline KSYSTEM_TIME convert_to_ksystem_time(const std::chrono::system_clock::time_point& tp)
{
const auto duration = tp.time_since_epoch();
const auto ns_duration = std::chrono::duration_cast<std::chrono::nanoseconds>(duration);

const auto total_ticks = ns_duration.count() / 100 + WINDOWS_EPOCH_DIFFERENCE;

KSYSTEM_TIME time{};
time.LowPart = static_cast<uint32_t>(total_ticks);
time.High1Time = static_cast<int32_t>(total_ticks >> 32);
time.High2Time = time.High1Time;

return time;
}

inline void convert_to_ksystem_time(volatile KSYSTEM_TIME* dest, const std::chrono::system_clock::time_point& tp)
{
const auto time = convert_to_ksystem_time(tp);
memcpy(const_cast<KSYSTEM_TIME*>(dest), &time, sizeof(*dest));
}

inline std::chrono::system_clock::time_point convert_from_ksystem_time(const KSYSTEM_TIME& time)
{
auto totalTicks = (static_cast<int64_t>(time.High1Time) << 32) | time.LowPart;
totalTicks -= WINDOWS_EPOCH_DIFFERENCE;

const auto duration = std::chrono::system_clock::duration(totalTicks * 100);
return std::chrono::system_clock::time_point(duration);
}

inline std::chrono::system_clock::time_point convert_from_ksystem_time(const volatile KSYSTEM_TIME& time)
{
return convert_from_ksystem_time(*const_cast<const KSYSTEM_TIME*>(&time));
}

0 comments on commit 422e8e5

Please sign in to comment.