Revert earlier rdtsc changes, implement fixes

This commit is contained in:
CarlTSpeak
2025-10-24 10:59:28 +01:00
parent 96169a01a8
commit 064df5b6ef
6 changed files with 14 additions and 30 deletions

View File

@@ -204,17 +204,6 @@ namespace
emu.reg(x86_register::rsp, emu.reg(x86_register::rsp) + 8);
emu.reg(x86_register::rax, 1);
}
else if (function == "VirtualQuery")
{
auto& emu = c.win_emu->emu();
const auto lpAddress = emu.reg(x86_register::rcx);
const auto lpBuffer = emu.reg(x86_register::rdx);
const auto dwLength = emu.reg(x86_register::r8);
c.win_emu->log.print(color::yellow,
"VirtualQuery called: lpAddress=0x%" PRIx64 ", lpBuffer=0x%" PRIx64 ", dwLength=%" PRIu64 "\n", lpAddress,
lpBuffer, dwLength);
}
else if (function == "lstrcmp" || function == "lstrcmpi")
{
print_arg_as_string(*c.win_emu, 0);

View File

@@ -504,7 +504,7 @@ uint64_t memory_manager::find_free_allocation_base(const size_t size, const uint
start_address = align_up(region_end, ALLOCATION_GRANULARITY);
}
if (start_address + size <= MAX_ALLOCATION_ADDRESS)
if (start_address + size <= MAX_ALLOCATION_END_EXCL)
{
return start_address;
}
@@ -516,7 +516,7 @@ region_info memory_manager::get_region_info(const uint64_t address)
{
region_info result{};
result.start = MIN_ALLOCATION_ADDRESS;
result.length = static_cast<size_t>(MAX_ALLOCATION_ADDRESS - result.start);
result.length = static_cast<size_t>(MAX_ALLOCATION_END_EXCL - result.start);
result.permissions = nt_memory_permission();
result.initial_permissions = nt_memory_permission();
result.allocation_base = {};
@@ -541,7 +541,7 @@ region_info memory_manager::get_region_info(const uint64_t address)
if (lower_end <= address)
{
result.start = lower_end;
result.length = static_cast<size_t>(MAX_ALLOCATION_ADDRESS - result.start);
result.length = static_cast<size_t>(MAX_ALLOCATION_END_EXCL - result.start);
return result;
}

View File

@@ -12,6 +12,7 @@
constexpr auto ALLOCATION_GRANULARITY = 0x0000000000010000ULL;
constexpr auto MIN_ALLOCATION_ADDRESS = 0x0000000000010000ULL;
constexpr auto MAX_ALLOCATION_ADDRESS = 0x00007ffffffeffffULL;
constexpr auto MAX_ALLOCATION_END_EXCL = MAX_ALLOCATION_ADDRESS + 1ULL;
// This maps to the `basic_memory_region` struct defined in
// emulator\memory_region.hpp

View File

@@ -20,6 +20,13 @@ namespace syscalls
return STATUS_NOT_SUPPORTED;
}
if (base_address < MIN_ALLOCATION_ADDRESS || base_address >= MAX_ALLOCATION_END_EXCL)
{
if (return_length)
return_length.write(0);
return STATUS_INVALID_PARAMETER;
}
if (info_class == MemoryBasicInformation)
{
if (return_length)

View File

@@ -328,7 +328,7 @@ windows_emulator::windows_emulator(std::unique_ptr<x86_64_emulator> emu, const e
this->map_port(mapping.first, mapping.second);
}
this->setup_hooks();
this->setup_hooks();
}
windows_emulator::~windows_emulator() = default;
@@ -434,9 +434,6 @@ void windows_emulator::on_instruction_execution(const uint64_t address)
void windows_emulator::setup_hooks()
{
uint64_t tsc_base = splitmix64(0xCAFEBABEDEADBEEFull);
constexpr uint64_t tick_scale = 50;
this->emu().hook_instruction(x86_hookable_instructions::syscall, [&] {
this->dispatcher.dispatch(*this);
return instruction_hook_continuation::skip_instruction;
@@ -445,8 +442,7 @@ void windows_emulator::setup_hooks()
this->emu().hook_instruction(x86_hookable_instructions::rdtscp, [&] {
this->callbacks.on_rdtscp();
const uint64_t retired = this->executed_instructions_;
const uint64_t ticks = tsc_base + (retired * tick_scale);
const auto ticks = this->clock_->timestamp_counter();
this->emu().reg(x86_register::rax, static_cast<uint32_t>(ticks));
this->emu().reg(x86_register::rdx, static_cast<uint32_t>(ticks >> 32));
@@ -460,8 +456,7 @@ void windows_emulator::setup_hooks()
this->emu().hook_instruction(x86_hookable_instructions::rdtsc, [&] {
this->callbacks.on_rdtsc();
const uint64_t retired = this->executed_instructions_;
const uint64_t ticks = tsc_base + (retired * tick_scale);
const auto ticks = this->clock_->timestamp_counter();
this->emu().reg(x86_register::rax, static_cast<uint32_t>(ticks));
this->emu().reg(x86_register::rdx, static_cast<uint32_t>(ticks >> 32));

View File

@@ -225,11 +225,3 @@ class windows_emulator
void register_factories(utils::buffer_deserializer& buffer);
};
static inline uint64_t splitmix64(uint64_t x) noexcept
{
x += 0x9E3779B97F4A7C15ull;
x = (x ^ (x >> 30)) * 0xBF58476D1CE4E5B9ull;
x = (x ^ (x >> 27)) * 0x94D049BB133111EBull;
return x ^ (x >> 31);
}