mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-18 11:13:57 +00:00
feat: spoof rdtsc timings (#185)
Previously, RDTSC in the VM always returned a constant value of 4, which broke any timing-based operations, or caused detections in heuristics of malware and ANTI-VM tools. This patch introduces a spoofed rdtsc_fake counter that tracks and adjusts timing deltas to simulate realistic TSC increments. Can be extended to simulate rdtsc timings based on CPU clock speed.
This commit is contained in:
@@ -3,6 +3,12 @@
|
||||
#include <chrono>
|
||||
|
||||
#include "../platform/platform.hpp"
|
||||
#if defined(_MSC_VER)
|
||||
#include <intrin.h>
|
||||
#pragma intrinsic(__rdtsc)
|
||||
#elif defined(__x86_64__) || defined(__i386__) || defined(__amd64__)
|
||||
#include <x86intrin.h>
|
||||
#endif
|
||||
|
||||
constexpr auto HUNDRED_NANOSECONDS_IN_ONE_SECOND = 10000000LL;
|
||||
constexpr auto EPOCH_DIFFERENCE_1601_TO_1970_SECONDS = 11644473600LL;
|
||||
@@ -29,6 +35,19 @@ namespace utils
|
||||
{
|
||||
return std::chrono::steady_clock::now();
|
||||
}
|
||||
|
||||
// Returns the current timestamp counter value. RDTSC on x86/x64, or just time since epoch for ARM
|
||||
/// TODO: find better solution for ARM and Figure out better CPU base frequency heuristics
|
||||
virtual uint64_t timestamp_counter()
|
||||
{
|
||||
#if defined(_M_X64) || defined(_M_AMD64) || defined(_M_IX86) || defined(__x86_64__) || defined(__i386__) || \
|
||||
defined(__amd64__)
|
||||
return __rdtsc(); // any x86 system will have this instrinsic
|
||||
#else
|
||||
const auto count = std::chrono::high_resolution_clock::now().time_since_epoch().count();
|
||||
return static_cast<uint64_t>((count * 38LL) / 10LL);
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
class tick_clock : public clock
|
||||
|
||||
@@ -448,9 +448,9 @@ void windows_emulator::setup_hooks()
|
||||
});
|
||||
|
||||
this->emu().hook_instruction(x64_hookable_instructions::rdtsc, [&] {
|
||||
const auto instructions = this->executed_instructions_;
|
||||
this->emu().reg(x64_register::rax, instructions & 0xFFFFFFFF);
|
||||
this->emu().reg(x64_register::rdx, (instructions >> 32) & 0xFFFFFFFF);
|
||||
const auto ticks = this->clock_->timestamp_counter();
|
||||
this->emu().reg(x64_register::rax, ticks & 0xFFFFFFFF);
|
||||
this->emu().reg(x64_register::rdx, (ticks >> 32) & 0xFFFFFFFF);
|
||||
return instruction_hook_continuation::skip_instruction;
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user