Page MenuHomedesp's stash

rdtscemup.c
No OneTemporary

rdtscemup.c

#include "rdtscemu.h"
#include "ntinternal.h"
#include <ntifs.h>
#include <ndis.h>
//
// It is very unlikely that each CPU will have different Trap0D handlers.
//
ULONG_PTR AvmpRdtscEmulationTrap0DOriginalHandler;
//
// Set CR4_TSD flag into the CR4 register.
//
VOID
NTAPI
AvmpRdtscEmulationSetTimeStampDisableFlag(
VOID
)
{
WriteCR4(ReadCR4() | CR4_TSD);
}
//
// Unset CR4_TSD flag from the CR4 register.
//
VOID
NTAPI
AvmpRdtscEmulationUnsetTimeStampDisableFlag(
VOID
)
{
WriteCR4(ReadCR4() & ~CR4_TSD);
}
//
// Force immediate context switch immediate context switch if the current processor
// does not fall in the newly set affinity mask and does not return to the caller
// until the thread is rescheduled on a processor conforming to the new affinity mask.
//
// ref: http://www.drdobbs.com/monitoring-nt-debug-services/184416239
//
VOID
NTAPI
AvmpRdtscEmulationSwitchToProcessor(
IN UCHAR ProcessorIndex
)
{
//
// If KeSetSystemAffinityThread is called at IRQL <= APC_LEVEL and the call is successful,
// the new affinity mask takes effect immediately.
//
// ref: https://msdn.microsoft.com/en-us/library/windows/hardware/ff553267(v=vs.85).aspx (see Remarks section)
//
if (KeGetCurrentIrql() > APC_LEVEL)
{
KeLowerIrql(APC_LEVEL);
}
KeSetSystemAffinityThread(AFFINITY_MASK(ProcessorIndex));
}
//
// Replace IDT entry.
//
#if defined(_X86_)
VOID
NTAPI
AvmpRdtscEmulationHookInterruptEntry(
IN UCHAR Index,
IN ULONG_PTR NewRoutineAddress,
OUT ULONG_PTR* OldRoutineAddress
)
{
AVM_KDESCRIPTOR Idtr;
ReadIDT(&Idtr);
PAVM_KIDTENTRY Idt = (PAVM_KIDTENTRY)(Idtr.Limit | Idtr.Base << 16);
DisableInterrupts();
{
ULONG_PTR OriginalHandler = (ULONG)(Idt[Index].ExtendedOffset) << 16 | Idt[Index].Offset;
Idt[Index].Offset = (USHORT)NewRoutineAddress;
Idt[Index].ExtendedOffset = (USHORT)((ULONG_PTR)NewRoutineAddress >> 16);
*OldRoutineAddress = OriginalHandler;
}
EnableInterrupts();
}
#else
//
// WP bit needs to be disabled on newer Windows 64-bit versions,
// Presumably due to Kernel Data Protection.
// Code referenced from https://github.com/LLLZed/IDTHOOK
//
KIRQL WPOFFx64()
{
KIRQL irql = KeRaiseIrqlToDpcLevel();
UINT64 cr0 = ReadCR0();
cr0 &= ~CR0_WP;
WriteCR0(cr0);
DisableInterrupts();
return irql;
}
void WPONx64(KIRQL irql)
{
UINT64 cr0 = ReadCR0();
cr0 |= CR0_WP;
EnableInterrupts();
WriteCR0(cr0);
KeLowerIrql(irql);
}
ULONG64 SetIdtAddr(ULONG64 IdtBaseAddr, UCHAR Index, ULONG64 NewAddr)
{
PAVM_KIDTENTRY Pidt = (PAVM_KIDTENTRY)(IdtBaseAddr);
Pidt = Pidt + Index;
ULONG64 OffsetHigh, OffsetMiddle, OffsetLow, ret;
OffsetHigh = Pidt->OffsetHigh;
OffsetHigh = OffsetHigh << 32;
OffsetMiddle = Pidt->OffsetMiddle;
OffsetMiddle = OffsetMiddle << 16;
OffsetLow = Pidt->OffsetLow;
ret = OffsetHigh + OffsetMiddle + OffsetLow;
Pidt->OffsetHigh = NewAddr >> 32;
Pidt->OffsetMiddle = NewAddr << 32 >> 48;
Pidt->OffsetLow = NewAddr & 0xFFFF;
return ret;
}
//
// System might triple fault using this method if KVA Shadowing is enabled,
// Disable through registry before continuing.
//
VOID
NTAPI
AvmpRdtscEmulationHookInterruptEntry(
IN UCHAR Index,
IN ULONG_PTR NewRoutineAddress,
OUT ULONG_PTR* OldRoutineAddress
)
{
AVM_KDESCRIPTOR Idtr;
ReadIDT(&Idtr);
KIRQL IRQL = WPOFFx64();
*OldRoutineAddress = SetIdtAddr(Idtr.Base, Index, NewRoutineAddress);
WPONx64(IRQL);
}
#endif

File Metadata

Mime Type
text/x-c
Expires
Mon, Jul 7, 5:51 PM (1 d, 2 h)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
0c/f6/0509462e60b44d7b4f63e92ba23f

Event Timeline