Page Menu
Home
desp's stash
Search
Configure Global Search
Log In
Files
F225241
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
8 KB
Subscribers
None
View Options
diff --git a/src/avmext/ntinternal.h b/src/avmext/ntinternal.h
index 89267bd..ad311b5 100644
--- a/src/avmext/ntinternal.h
+++ b/src/avmext/ntinternal.h
@@ -1,227 +1,222 @@
#pragma once
#include <ntifs.h>
#pragma warning (disable : 4201)
#pragma warning (disable : 4204)
#pragma warning (disable : 4214)
//
// Inspired by WRK.
//
#define CR4_TSD 0x00000004 // Time stamp disable
+#define CR0_WP 0x10000 // Write Protection enable
+
#define ReadTSC() __rdtsc()
#define ReadTSCP(data) __rdtscp(data)
+#define ReadCR0() __readcr0()
+#define WriteCR0(data) __writecr0(data)
+
#define ReadCR4() __readcr4()
#define WriteCR4(data) __writecr4(data)
#define ReadIDT(data) __sidt(data)
#define WriteIDT(data) __lidt(data)
#define EnableInterrupts() _enable() // sti instruction
#define DisableInterrupts() _disable() // cli instruction
//
// IDT descriptor.
//
struct _AVM_KDESCRIPTOR32
{
USHORT Pad;
USHORT Limit;
ULONG Base;
};
-struct _AVM_KDESCRIPTOR64
-{
- union
- {
- struct
- {
- USHORT Pad[3];
- USHORT Limit;
- };
-
- ULONG_PTR LowPart;
- };
- union
- {
- ULONG_PTR Base;
- ULONG_PTR HighPart;
- };
-};
-
//
// Entry of Interrupt Descriptor Table (IDTENTRY)
//
struct _AVM_KIDTENTRY32
{
USHORT Offset;
USHORT Selector;
USHORT Access;
USHORT ExtendedOffset;
};
+#pragma pack(1)
+struct _AVM_KDESCRIPTOR64
+{
+ USHORT limit;
+ ULONG64 Base;
+};
+
struct _AVM_KIDTENTRY64
{
union
{
struct
{
USHORT OffsetLow;
USHORT Selector;
USHORT IstIndex : 3;
USHORT Reserved0 : 5;
USHORT Type : 5;
USHORT Dpl : 2;
USHORT Present : 1;
USHORT OffsetMiddle;
ULONG OffsetHigh;
ULONG Reserved1;
};
ULONG64 Alignment;
};
};
+#pragma pack()
+
//
// Trap frame
//
struct _AVM_KTRAP_FRAME32
{
//
// Segment registers
//
ULONG SegGs;
ULONG SegEs;
ULONG SegDs;
//
// Volatile registers
//
ULONG Edx;
ULONG Ecx;
ULONG Eax;
//
// FS is TIB/PCR pointer, is here to make save sequence easy
//
ULONG SegFs;
//
// Non-volatile registers
//
ULONG Edi;
ULONG Esi;
ULONG Ebx;
ULONG Ebp;
//
// Control registers
//
ULONG ErrCode;
ULONG Eip;
ULONG SegCs;
ULONG EFlags;
ULONG HardwareEsp; // WARNING - segSS:esp are only here for stacks
ULONG HardwareSegSs; // that involve a ring transition.
};
struct _AVM_KTRAP_FRAME64
{
//
// Volatile registers.
//
// N.B. These registers are only saved on exceptions and interrupts. They
// are not saved for system calls.
//
ULONG64 Rax;
ULONG64 Rcx;
ULONG64 Rdx;
ULONG64 R8;
ULONG64 R9;
ULONG64 R10;
ULONG64 R11;
//
// Saved nonvolatile registers RBX, RDI and RSI. These registers are only
// saved in system service trap frames.
//
ULONG64 Rbx;
ULONG64 Rdi;
ULONG64 Rsi;
//
// Saved nonvolatile register RBP. This register is used as a frame
// pointer during trap processing and is saved in all trap frames.
//
ULONG64 Rbp;
//
// Information pushed by hardware.
//
// N.B. The error code is not always pushed by hardware. For those cases
// where it is not pushed by hardware a dummy error code is allocated
// on the stack.
//
union
{
ULONG64 ErrorCode;
ULONG64 ExceptionFrame;
};
ULONG64 Rip;
USHORT SegCs;
USHORT Fill1[3];
ULONG EFlags;
ULONG Fill2;
ULONG64 Rsp;
USHORT SegSs;
USHORT Fill3[1];
};
#if defined(_X86_)
typedef struct _AVM_KDESCRIPTOR32 AVM_KDESCRIPTOR, *PAVM_KDESCRIPTOR;
typedef struct _AVM_KIDTENTRY32 AVM_KIDTENTRY, *PAVM_KIDTENTRY;
typedef struct _AVM_KTRAP_FRAME32 AVM_KTRAP_FRAME, *PAVM_KTRAP_FRAME;
#elif defined(_AMD64_)
typedef struct _AVM_KDESCRIPTOR64 AVM_KDESCRIPTOR, *PAVM_KDESCRIPTOR;
typedef struct _AVM_KIDTENTRY64 AVM_KIDTENTRY, *PAVM_KIDTENTRY;
typedef struct _AVM_KTRAP_FRAME64 AVM_KTRAP_FRAME, *PAVM_KTRAP_FRAME;
#else
# error "Unknown architecture"
#endif
//
// Initialize & destroy routines.
//
NTSTATUS
NTAPI
AvmNtInternalInitialize(
IN PDRIVER_OBJECT DriverObject
);
VOID
NTAPI
AvmNtInternalDestroy(
IN PDRIVER_OBJECT DriverObject
);
diff --git a/src/avmext/rdtscemup.c b/src/avmext/rdtscemup.c
index 0e59eb5..0c52e9a 100644
--- a/src/avmext/rdtscemup.c
+++ b/src/avmext/rdtscemup.c
@@ -1,125 +1,164 @@
#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);
- PAVM_KIDTENTRY Idt = (PAVM_KIDTENTRY)(Idtr.LowPart >> 16 | Idtr.HighPart << 48);
- PAVM_KIDTENTRY IdtAt = &Idt[Index];
-
- DisableInterrupts();
- {
- ULONG_PTR OriginalHandler = (ULONG_PTR)Idt[Index].OffsetLow |
- (ULONG_PTR)Idt[Index].OffsetMiddle << 16 |
- (ULONG_PTR)Idt[Index].OffsetHigh << 32;
+ KIRQL IRQL = WPOFFx64();
- IdtAt->OffsetLow = (USHORT)(NewRoutineAddress);
- IdtAt->OffsetMiddle = (USHORT)(NewRoutineAddress >> 16);
- IdtAt->OffsetHigh = (ULONG) (NewRoutineAddress >> 32);
+ *OldRoutineAddress = SetIdtAddr(Idtr.Base, Index, NewRoutineAddress);
- *OldRoutineAddress = OriginalHandler;
- }
- EnableInterrupts();
+ WPONx64(IRQL);
}
#endif
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Fri, Mar 14, 10:17 PM (12 h, 2 m)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
37/03/061874dce1ae5a34b9f1e280a381
Attached To
rAVM avmext
Event Timeline
Log In to Comment