Page MenuHomedesp's stash

No OneTemporary

diff --git a/src/avmext/rdtscemu.c b/src/avmext/rdtscemu.c
index 904a03e..7d727bd 100644
--- a/src/avmext/rdtscemu.c
+++ b/src/avmext/rdtscemu.c
@@ -1,365 +1,371 @@
#include "rdtscemu.h"
#include "ntinternal.h"
#include <ntifs.h>
#define AVM_GENERAL_PROTECTION_FAULT_INTERRUPT_VECTOR (0x0D)
AVM_RDTSC_EMULATION_LOG_TABLE_ITEM AvmRdtscEmulationLogTable[AVM_RDTSC_EMULATION_LOG_TABLE_SIZE];
ULONG AvmRdtscEmulationLogTableSizeInBytes = sizeof(AvmRdtscEmulationLogTable);
ULONG AvmRdtscEmulationLogTableItemCount = 0;
KSPIN_LOCK AvmRdtscEmulationLogTableLock;
AVM_RDTSC_EMULATION_CONFIGURATION AvmRdtscEmulationConfiguration;
VOID
NTAPI
AvmRdtscEmulationLog(
AVM_RDTSC_EMULATION_INSTRUCTION_TYPE Instruction,
PVOID Eip,
ULONG ReturnedEax,
ULONG ReturnedEdx,
ULONG ReturnedEcx
)
{
AVM_RDTSC_EMULATION_LOG_TABLE_ITEM TableItem = {
.ProcessId = (ULONG)(ULONG_PTR)PsGetCurrentProcessId(),
.ReturnedEax = ReturnedEax,
.ReturnedEdx = ReturnedEdx,
.ReturnedEcx = ReturnedEcx,
.Eip = Eip,
.Instruction = Instruction
};
AvmRdtscEmulationLogTable[AvmRdtscEmulationLogTableItemCount++ % RTL_NUMBER_OF(AvmRdtscEmulationLogTable)] = TableItem;
}
//
// Inspired by vmdetectorsys.
//
// ref: https://github.com/x9090/vmdetectorsys
//
#if defined(_X86_)
VOID
NTAPI
AvmRdtscEmulationEmulate(
PULONG Eax,
PULONG Edx
)
{
static ULONG Seed = 0x01000193;
ULONG RandomDelta;
switch (AvmRdtscEmulationConfiguration.Method)
{
case AvmRdtscEmulationIncreasingMethodType:
//
// Generate RandomDelta in the interval <DeltaFrom, DeltaTo).
//
RandomDelta = (ULONG)RtlRandomEx(&Seed);
RandomDelta %= (AvmRdtscEmulationConfiguration.DeltaTo - AvmRdtscEmulationConfiguration.DeltaFrom);
RandomDelta += AvmRdtscEmulationConfiguration.DeltaFrom;
AvmRdtscEmulationConfiguration.TscValue += RandomDelta;
//
// Fall through.
//
case AvmRdtscEmulationConstantMethodType:
*Edx = (ULONG)(AvmRdtscEmulationConfiguration.TscValue << 32);
*Eax = (ULONG)(AvmRdtscEmulationConfiguration.TscValue);
break;
default:
break;
}
}
//
// Real Trap0D handler.
//
BOOLEAN
NTAPI
AvmRdtscEmulationTrap0D(
IN PAVM_KTRAP_FRAME UserFrame
)
{
SIZE_T InstructionLength = 0;
KIRQL OldIrql;
KeAcquireSpinLock(&AvmRdtscEmulationLogTableLock, &OldIrql);
if (MmIsAddressValid((PVOID)UserFrame->Eip))
{
if (RtlEqualMemory((PVOID)UserFrame->Eip, AvmOpRdtsc, sizeof(AvmOpRdtsc)))
{
InstructionLength = sizeof(AvmOpRdtsc);
AvmRdtscEmulationEmulate(
&UserFrame->Eax,
&UserFrame->Edx);
AvmRdtscEmulationLog(
AvmRdtscType,
(PVOID)UserFrame->Eip,
UserFrame->Eax,
UserFrame->Edx,
UserFrame->Ecx);
}
else if (RtlEqualMemory((PVOID)UserFrame->Eip, AvmOpRdtscp, sizeof(AvmOpRdtscp)))
{
InstructionLength = sizeof(AvmOpRdtscp);
UserFrame->Ecx = AvmRdtscEmulationConfiguration.TscAux;
AvmRdtscEmulationEmulate(
&UserFrame->Eax,
&UserFrame->Edx);
AvmRdtscEmulationLog(
AvmRdtscpType,
(PVOID)UserFrame->Eip,
UserFrame->Eax,
UserFrame->Edx,
UserFrame->Ecx);
}
}
KeReleaseSpinLock(&AvmRdtscEmulationLogTableLock, OldIrql);
//
// Move instruction pointer behind the instruction.
//
UserFrame->Eip += InstructionLength;
//
// Return TRUE if the rdtsc(p) instruction was handled.
//
return InstructionLength != 0;
}
#else
VOID
NTAPI
AvmRdtscEmulationEmulate(
PULONGLONG Rax,
PULONGLONG Rdx
)
{
static ULONG Seed = 0x01000193;
ULONG RandomDelta;
switch (AvmRdtscEmulationConfiguration.Method)
{
case AvmRdtscEmulationIncreasingMethodType:
//
// Generate RandomDelta in the interval <DeltaFrom, DeltaTo).
//
RandomDelta = (ULONG)RtlRandomEx(&Seed);
RandomDelta %= (AvmRdtscEmulationConfiguration.DeltaTo - AvmRdtscEmulationConfiguration.DeltaFrom);
RandomDelta += AvmRdtscEmulationConfiguration.DeltaFrom;
AvmRdtscEmulationConfiguration.TscValue += RandomDelta;
//
// Fall through.
//
case AvmRdtscEmulationConstantMethodType:
*Rdx = (ULONGLONG)(ULONG)(AvmRdtscEmulationConfiguration.TscValue << 32);
*Rax = (ULONGLONG)(ULONG)(AvmRdtscEmulationConfiguration.TscValue);
break;
default:
break;
}
}
//
// Real Trap0D handler.
//
BOOLEAN
NTAPI
AvmRdtscEmulationTrap0D(
IN PAVM_KTRAP_FRAME UserFrame
)
{
SIZE_T InstructionLength = 0;
KIRQL OldIrql;
KeAcquireSpinLock(&AvmRdtscEmulationLogTableLock, &OldIrql);
if (MmIsAddressValid((PVOID)UserFrame->Rip))
{
if (RtlEqualMemory((PVOID)UserFrame->Rip, AvmOpRdtsc, sizeof(AvmOpRdtsc)))
{
InstructionLength = sizeof(AvmOpRdtsc);
AvmRdtscEmulationEmulate(
&UserFrame->Rax,
&UserFrame->Rdx);
AvmRdtscEmulationLog(
AvmRdtscType,
(PVOID)UserFrame->Rip,
(ULONG)UserFrame->Rax,
(ULONG)UserFrame->Rdx,
(ULONG)UserFrame->Rcx);
}
else if (RtlEqualMemory((PVOID)UserFrame->Rip, AvmOpRdtscp, sizeof(AvmOpRdtscp)))
{
InstructionLength = sizeof(AvmOpRdtscp);
UserFrame->Rcx = AvmRdtscEmulationConfiguration.TscAux;
AvmRdtscEmulationEmulate(
&UserFrame->Rax,
&UserFrame->Rdx);
AvmRdtscEmulationLog(
AvmRdtscpType,
(PVOID)UserFrame->Rip,
(ULONG)UserFrame->Rax,
(ULONG)UserFrame->Rdx,
(ULONG)UserFrame->Rcx);
}
}
KeReleaseSpinLock(&AvmRdtscEmulationLogTableLock, OldIrql);
//
// Move instruction pointer behind the instruction.
//
UserFrame->Rip += InstructionLength;
//
// Return TRUE if the rdtsc(p) instruction was handled.
//
return InstructionLength != 0;
}
#endif
VOID
NTAPI
AvmRdtscEmulationEnable(
VOID
)
{
//
// Early exit if the hook has been already installed.
//
if (AvmpRdtscEmulationTrap0DOriginalHandler != 0)
{
return;
}
//
// Hook IDT entry on each processor.
//
for (CCHAR i = 0; i < KeNumberProcessors; i++)
{
//
// Synchronously switch CPU.
//
AvmpRdtscEmulationSwitchToProcessor(i);
//
// Hook IDT entry on current processor.
//
AvmpRdtscEmulationHookInterruptEntry(
AVM_GENERAL_PROTECTION_FAULT_INTERRUPT_VECTOR,
(ULONG_PTR)&AvmpRdtscEmulationTrap0D,
&AvmpRdtscEmulationTrap0DOriginalHandler);
//
// Set the TSD flag.
//
AvmpRdtscEmulationSetTimeStampDisableFlag();
}
}
VOID
NTAPI
AvmRdtscEmulationDisable(
VOID
)
{
//
// Early exit if the hook was not installed.
//
if (AvmpRdtscEmulationTrap0DOriginalHandler == 0)
{
return;
}
//
// Unhook IDT entry on each processor.
//
for (CCHAR i = 0; i < KeNumberProcessors; i++)
{
//
// Synchronously switch CPU.
//
AvmpRdtscEmulationSwitchToProcessor(i);
//
// Unhook IDT entry on current processor.
//
ULONG_PTR Dummy;
AvmpRdtscEmulationHookInterruptEntry(
AVM_GENERAL_PROTECTION_FAULT_INTERRUPT_VECTOR,
AvmpRdtscEmulationTrap0DOriginalHandler,
&Dummy);
+ //
+ // Signify hook has been uninstalled.
+ //
+
+ AvmpRdtscEmulationTrap0DOriginalHandler = 0;
+
//
// Unset the TSD flag.
//
AvmpRdtscEmulationUnsetTimeStampDisableFlag();
}
}
NTSTATUS
NTAPI
AvmRdtscEmulationInitialize(
IN PDRIVER_OBJECT DriverObject
)
{
UNREFERENCED_PARAMETER(DriverObject);
RtlZeroMemory(AvmRdtscEmulationLogTable, AvmRdtscEmulationLogTableSizeInBytes);
KeInitializeSpinLock(&AvmRdtscEmulationLogTableLock);
//
// Initial RDTSC configuration.
//
AvmRdtscEmulationConfiguration.Method = AvmRdtscEmulationIncreasingMethodType;
AvmRdtscEmulationConfiguration.ProcessId = 0;
AvmRdtscEmulationConfiguration.TscValue = ReadTSC();
ReadTSCP(&AvmRdtscEmulationConfiguration.TscAux);
AvmRdtscEmulationConfiguration.DeltaFrom = 10;
AvmRdtscEmulationConfiguration.DeltaTo = 100;
AvmRdtscEmulationConfiguration.TscAux = 20;
return STATUS_SUCCESS;
}
VOID
NTAPI
AvmRdtscEmulationDestroy(
IN PDRIVER_OBJECT DriverObject
)
{
UNREFERENCED_PARAMETER(DriverObject);
AvmRdtscEmulationDisable();
}

File Metadata

Mime Type
text/x-diff
Expires
Sat, Sep 21, 7:04 PM (1 d, 18 h)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
06/83/12d6823d267c8bb9622ae446a862

Event Timeline