Support relative and absolute time

This fixes #23
This commit is contained in:
momo5502
2024-11-10 15:34:21 +01:00
parent 6f8f840b57
commit d1493867fe
5 changed files with 56 additions and 11 deletions

View File

@@ -433,6 +433,12 @@ namespace utils
std::vector<std::byte> buffer_{};
};
template <>
inline void buffer_deserializer::read<bool>(bool& object)
{
object = this->read<uint8_t>() != 0;
}
template <>
inline void buffer_deserializer::read<std::string>(std::string& object)
{
@@ -445,6 +451,12 @@ namespace utils
object = this->read_string<wchar_t>();
}
template <>
inline void buffer_serializer::write<bool>(const bool& object)
{
this->write<uint8_t>(object ? 1 : 0);
}
template <>
inline void buffer_serializer::write<std::string>(const std::string& object)
{

View File

@@ -26,6 +26,7 @@ namespace test
{
.application = "./test-sample.exe",
.disable_logging = true,
.use_relative_time = true,
};
return windows_emulator{settings};

View File

@@ -22,17 +22,28 @@ namespace
{
performance_counter.access([&](LARGE_INTEGER& value)
{
value.QuadPart = static_cast<LONGLONG>(c.proc.executed_instructions);
//QueryPerformanceCounter(&value);
if (c.win_emu.time_is_relative())
{
value.QuadPart = static_cast<LONGLONG>(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)
{
value.QuadPart = 10000;
//QueryPerformanceFrequency(&value);
frequency = kusd.QpcFrequency;
});
performance_frequency.access([&](LARGE_INTEGER& value)
{
value.QuadPart = frequency;
});
}

View File

@@ -1,5 +1,6 @@
#include "std_include.hpp"
#include "windows_emulator.hpp"
#include "context_frame.hpp"
#include <unicorn_x64_emulator.hpp>
@@ -49,14 +50,14 @@ namespace
emu.write_register(x64_register::msr, &value, sizeof(value));
}
emulator_object<KUSER_SHARED_DATA> setup_kusd(x64_emulator& emu)
emulator_object<KUSER_SHARED_DATA> 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<KUSER_SHARED_DATA> 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<x64_emulator> 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);

View File

@@ -16,6 +16,7 @@ struct emulator_settings
std::filesystem::path registry_directory{"./registry"};
std::vector<std::wstring> arguments{};
bool disable_logging{false};
bool use_relative_time{false};
};
class windows_emulator
@@ -95,11 +96,17 @@ public:
void yield_thread();
void perform_thread_switch();
private:
std::unique_ptr<x64_emulator> emu_{};
bool time_is_relative() const
{
return this->use_relative_time_;
}
private:
bool use_relative_time_{false};
std::unique_ptr<x64_emulator> emu_{};
std::vector<instruction_hook_callback> syscall_hooks_{};
process_context process_;
syscall_dispatcher dispatcher_;