Page Menu
Home
desp's stash
Search
Configure Global Search
Log In
Files
F202122
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
70 KB
Subscribers
None
View Options
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..21d5e0e
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,11 @@
+#
+# Compiled binaries.
+#
+bin/**
+
+#
+# Visual Studio files.
+#
+.vs/**
+*.VC.db
+*.VC.opendb
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000..7066fd9
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2016 Petr Benes
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/avmext.sln b/avmext.sln
new file mode 100644
index 0000000..6c32869
--- /dev/null
+++ b/avmext.sln
@@ -0,0 +1,42 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.25123.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "avmext", "src\avmext\avmext.vcxproj", "{545C7532-D980-4FAD-B93F-6D23B241BC41}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "avmextctrl", "src\avmextctrl\avmextctrl.vcxproj", "{E14D2DC8-99BE-44EC-815C-8A0A2A4EE259}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {545C7532-D980-4FAD-B93F-6D23B241BC41}.Debug|x64.ActiveCfg = Debug|x64
+ {545C7532-D980-4FAD-B93F-6D23B241BC41}.Debug|x64.Build.0 = Debug|x64
+ {545C7532-D980-4FAD-B93F-6D23B241BC41}.Debug|x64.Deploy.0 = Debug|x64
+ {545C7532-D980-4FAD-B93F-6D23B241BC41}.Debug|x86.ActiveCfg = Debug|Win32
+ {545C7532-D980-4FAD-B93F-6D23B241BC41}.Debug|x86.Build.0 = Debug|Win32
+ {545C7532-D980-4FAD-B93F-6D23B241BC41}.Debug|x86.Deploy.0 = Debug|Win32
+ {545C7532-D980-4FAD-B93F-6D23B241BC41}.Release|x64.ActiveCfg = Release|x64
+ {545C7532-D980-4FAD-B93F-6D23B241BC41}.Release|x64.Build.0 = Release|x64
+ {545C7532-D980-4FAD-B93F-6D23B241BC41}.Release|x64.Deploy.0 = Release|x64
+ {545C7532-D980-4FAD-B93F-6D23B241BC41}.Release|x86.ActiveCfg = Release|Win32
+ {545C7532-D980-4FAD-B93F-6D23B241BC41}.Release|x86.Build.0 = Release|Win32
+ {545C7532-D980-4FAD-B93F-6D23B241BC41}.Release|x86.Deploy.0 = Release|Win32
+ {E14D2DC8-99BE-44EC-815C-8A0A2A4EE259}.Debug|x64.ActiveCfg = Debug|x64
+ {E14D2DC8-99BE-44EC-815C-8A0A2A4EE259}.Debug|x64.Build.0 = Debug|x64
+ {E14D2DC8-99BE-44EC-815C-8A0A2A4EE259}.Debug|x86.ActiveCfg = Debug|Win32
+ {E14D2DC8-99BE-44EC-815C-8A0A2A4EE259}.Debug|x86.Build.0 = Debug|Win32
+ {E14D2DC8-99BE-44EC-815C-8A0A2A4EE259}.Release|x64.ActiveCfg = Release|x64
+ {E14D2DC8-99BE-44EC-815C-8A0A2A4EE259}.Release|x64.Build.0 = Release|x64
+ {E14D2DC8-99BE-44EC-815C-8A0A2A4EE259}.Release|x86.ActiveCfg = Release|Win32
+ {E14D2DC8-99BE-44EC-815C-8A0A2A4EE259}.Release|x86.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/src/avmext/amd64/common.inc b/src/avmext/amd64/common.inc
new file mode 100644
index 0000000..266de66
--- /dev/null
+++ b/src/avmext/amd64/common.inc
@@ -0,0 +1,93 @@
+;
+; Constants for system irql and IDT vector conversion.
+;
+
+RPL_MASK equ 00003H
+
+;
+; Gdt Descriptor Offset Definitions.
+;
+
+KGDT64_R3_DATA equ 00028H
+KGDT64_R3_CMTEB equ 00050H
+
+;
+; Define constants for system IRQL and IDT vector conversion.
+;
+
+MODE_MASK equ 00001H
+
+;
+; Define TRAP_FRAME64 field offsets.
+;
+TrErrorCode equ 00058H
+TrRip equ 00060H
+TrSegCs equ 00068H
+TrEFlags equ 00070H
+TrRsp equ 00078H
+TrSegSs equ 00080H
+
+;
+; Define special macros to align trap entry points on cache line boundaries.
+;
+; N.B. This will only work if all functions in this module are declared with
+; these macros.
+;
+
+TRAP_ENTRY macro
+
+ local KernelMode
+
+ push rbp
+ push rsi
+ push rdi
+ push rbx
+
+ push r11
+ push r10
+ push r9
+ push r8
+ push rdx
+ push rcx
+ push rax
+
+ test byte ptr TrSegCs[rsp], MODE_MASK
+ jz KernelMode
+
+ swapgs
+
+KernelMode:
+
+ mov rbp, rsp
+
+ endm
+
+;
+; TRAP_END macro.
+;
+
+TRAP_END macro
+
+ local KernelMode
+
+ test byte ptr TrSegCs[rsp], MODE_MASK
+ jz KernelMode
+
+ swapgs
+
+KernelMode:
+
+ pop rax
+ pop rcx
+ pop rdx
+ pop r8
+ pop r9
+ pop r10
+ pop r11
+
+ pop rbx
+ pop rdi
+ pop rsi
+ pop rbp
+
+ endm
diff --git a/src/avmext/amd64/trap.asm b/src/avmext/amd64/trap.asm
new file mode 100644
index 0000000..4a9c693
--- /dev/null
+++ b/src/avmext/amd64/trap.asm
@@ -0,0 +1,55 @@
+include common.inc
+
+;
+; Extern functions.
+;
+
+EXTRN AvmRdtscEmulationTrap0D:PROC
+EXTRN AvmpRdtscEmulationTrap0DOriginalHandler:QWORD
+
+; ;
+; ------------------------------------------------------------------- ;
+; CODE SECTION ;
+; ------------------------------------------------------------------- ;
+; ;
+
+.CODE
+
+ AvmpRdtscEmulationTrap0D PROC PUBLIC
+ TRAP_ENTRY
+;
+; Call our new trap function.
+;
+
+ mov rcx, rsp ; set first parameter
+
+ sub rsp, 32 ; shadow space
+ call AvmRdtscEmulationTrap0D
+ add rsp, 32 ; shadow space
+
+;
+; If our trap did not handle the fault,
+; pass it to the original trap handler.
+;
+
+ cmp rax, 0
+ jz OldHandler
+
+;
+; Fault has been handled,
+; return from the interrupt handler.
+;
+
+ TRAP_END
+
+ add rsp, 8
+ iretq
+
+OldHandler:
+
+ TRAP_END
+ jmp qword ptr [AvmpRdtscEmulationTrap0DOriginalHandler]
+
+ AvmpRdtscEmulationTrap0D ENDP
+
+END
diff --git a/src/avmext/avmext.vcxproj b/src/avmext/avmext.vcxproj
new file mode 100644
index 0000000..c22c435
--- /dev/null
+++ b/src/avmext/avmext.vcxproj
@@ -0,0 +1,140 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{545C7532-D980-4FAD-B93F-6D23B241BC41}</ProjectGuid>
+ <TemplateGuid>{dd38f7fc-d7bd-488b-9242-7d8754cde80d}</TemplateGuid>
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion>
+ <Configuration>Debug</Configuration>
+ <Platform Condition="'$(Platform)' == ''">Win32</Platform>
+ <RootNamespace>avmext</RootNamespace>
+ <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <TargetVersion>Windows7</TargetVersion>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>Driver</ConfigurationType>
+ <DriverType>WDM</DriverType>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <TargetVersion>Windows7</TargetVersion>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>Driver</ConfigurationType>
+ <DriverType>WDM</DriverType>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <TargetVersion>Windows7</TargetVersion>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>Driver</ConfigurationType>
+ <DriverType>WDM</DriverType>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <TargetVersion>Windows7</TargetVersion>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>Driver</ConfigurationType>
+ <DriverType>WDM</DriverType>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
+ <EnableInf2cat>false</EnableInf2cat>
+ <OutDir>$(SolutionDir)bin\$(PlatformShortName)\$(Configuration)\</OutDir>
+ <IntDir>$(SolutionDir)bin\obj\$(PlatformShortName)\$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
+ <Inf2CatUseLocalTime>true</Inf2CatUseLocalTime>
+ <OutDir>$(SolutionDir)bin\$(PlatformShortName)\$(Configuration)\</OutDir>
+ <IntDir>$(SolutionDir)bin\obj\$(PlatformShortName)\$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
+ <Inf2CatUseLocalTime>true</Inf2CatUseLocalTime>
+ <OutDir>$(SolutionDir)bin\$(PlatformShortName)\$(Configuration)\</OutDir>
+ <IntDir>$(SolutionDir)bin\obj\$(PlatformShortName)\$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
+ <Inf2CatUseLocalTime>true</Inf2CatUseLocalTime>
+ <OutDir>$(SolutionDir)bin\$(PlatformShortName)\$(Configuration)\</OutDir>
+ <IntDir>$(SolutionDir)bin\obj\$(PlatformShortName)\$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Link>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <FilesToPackage Include="$(TargetPath)" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="dispatch.c" />
+ <ClCompile Include="entry.c" />
+ <ClCompile Include="ntinternal.c" />
+ <ClCompile Include="rdtscemup.c" />
+ <ClCompile Include="rdtscemu.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="ntinternal.h" />
+ <ClInclude Include="dispatch.h" />
+ <ClInclude Include="entry.h" />
+ <ClInclude Include="rdtscemu.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <MASM Include="amd64\trap.asm">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ </MASM>
+ <MASM Include="i386\trap.asm">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+ </MASM>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="amd64\common.inc" />
+ <None Include="i386\common.inc" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/src/avmext/avmext.vcxproj.filters b/src/avmext/avmext.vcxproj.filters
new file mode 100644
index 0000000..fd9d858
--- /dev/null
+++ b/src/avmext/avmext.vcxproj.filters
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+ </Filter>
+ <Filter Include="Source Files\i386">
+ <UniqueIdentifier>{8407f6c8-7d87-4280-9cd2-1d4e0b1b6a1a}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\amd64">
+ <UniqueIdentifier>{954fbf72-c47e-4069-9ade-92bc2bd58cdc}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="dispatch.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="entry.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="ntinternal.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="rdtscemup.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="rdtscemu.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="dispatch.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="entry.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="rdtscemu.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="ntinternal.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <MASM Include="i386\trap.asm">
+ <Filter>Source Files\i386</Filter>
+ </MASM>
+ <MASM Include="amd64\trap.asm">
+ <Filter>Source Files\amd64</Filter>
+ </MASM>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="i386\common.inc">
+ <Filter>Source Files\i386</Filter>
+ </None>
+ <None Include="amd64\common.inc">
+ <Filter>Source Files\amd64</Filter>
+ </None>
+ </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/src/avmext/avmext.vcxproj.user b/src/avmext/avmext.vcxproj.user
new file mode 100644
index 0000000..abe8dd8
--- /dev/null
+++ b/src/avmext/avmext.vcxproj.user
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup />
+</Project>
\ No newline at end of file
diff --git a/src/avmext/dispatch.c b/src/avmext/dispatch.c
new file mode 100644
index 0000000..d2c2286
--- /dev/null
+++ b/src/avmext/dispatch.c
@@ -0,0 +1,270 @@
+#include "dispatch.h"
+#include "entry.h"
+#include "rdtscemu.h"
+
+NTSTATUS
+NTAPI
+AvmDispatch_Create(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp
+ )
+{
+ UNREFERENCED_PARAMETER(DeviceObject);
+ UNREFERENCED_PARAMETER(Irp);
+
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+AvmDispatch_Close(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp
+ )
+{
+ UNREFERENCED_PARAMETER(DeviceObject);
+ UNREFERENCED_PARAMETER(Irp);
+
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+AvmDispatch_Read(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp
+ )
+{
+ UNREFERENCED_PARAMETER(DeviceObject);
+ UNREFERENCED_PARAMETER(Irp);
+
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+AvmDispatch_Write(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp
+ )
+{
+ UNREFERENCED_PARAMETER(DeviceObject);
+ UNREFERENCED_PARAMETER(Irp);
+
+// NTSTATUS Status = STATUS_SUCCESS;
+// PIO_STACK_LOCATION IoStackIrp = NULL;
+// PCHAR WriteDataBuffer;
+//
+// IoStackIrp = IoGetCurrentIrpStackLocation(Irp);
+//
+// if (IoStackIrp)
+// {
+// WriteDataBuffer = (PCHAR)Irp->AssociatedIrp.SystemBuffer;
+//
+// if (WriteDataBuffer)
+// {
+//
+// }
+// }
+
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+AvmDispatch_IoControl(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp
+ )
+{
+ UNREFERENCED_PARAMETER(DeviceObject);
+
+ NTSTATUS Status = STATUS_SUCCESS;
+ PIO_STACK_LOCATION IoCurrentStack;
+ ULONG InputBufferLength;
+ ULONG OutputBufferLength;
+
+ IoCurrentStack = IoGetCurrentIrpStackLocation(Irp);
+
+ InputBufferLength = IoCurrentStack->Parameters.DeviceIoControl.InputBufferLength;
+ OutputBufferLength = IoCurrentStack->Parameters.DeviceIoControl.OutputBufferLength;
+
+ Irp->IoStatus.Information = 0;
+ Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
+
+ // if (Irp->MdlAddress)
+ // {
+ // KdPrint(("User address: 0x%08x\n", MmGetMdlVirtualAddress(Irp->MdlAddress)));
+ // pBuf = (PCHAR)MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
+ // }
+
+ KIRQL OldIrql;
+
+ KeAcquireSpinLock(&AvmRdtscEmulationLogTableLock, &OldIrql);
+ switch (IoCurrentStack->Parameters.DeviceIoControl.IoControlCode)
+ {
+ case IOCTL_AVM_RDTSC_EMULATION_ENABLE:
+ AvmRdtscEmulationEnable();
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ break;
+
+ case IOCTL_AVM_RDTSC_EMULATION_DISABLE:
+ AvmRdtscEmulationDisable();
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ break;
+
+ case IOCTL_AVM_RDTSC_EMULATION_GET_LOG_TABLE_SIZE_IN_BYTES:
+ if (OutputBufferLength >= sizeof(AvmRdtscEmulationLogTableSizeInBytes))
+ {
+ RtlCopyMemory(
+ Irp->AssociatedIrp.SystemBuffer,
+ &AvmRdtscEmulationLogTableSizeInBytes,
+ sizeof(AvmRdtscEmulationLogTableSizeInBytes));
+
+ Irp->IoStatus.Information = sizeof(AvmRdtscEmulationLogTableSizeInBytes);
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ }
+ else
+ {
+ Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
+ }
+ break;
+
+ case IOCTL_AVM_RDTSC_EMULATION_GET_LOG_TABLE_ITEM_COUNT:
+ if (OutputBufferLength >= sizeof(AvmRdtscEmulationLogTableItemCount))
+ {
+ RtlCopyMemory(
+ Irp->AssociatedIrp.SystemBuffer,
+ &AvmRdtscEmulationLogTableItemCount,
+ sizeof(AvmRdtscEmulationLogTableItemCount));
+
+ Irp->IoStatus.Information = sizeof(AvmRdtscEmulationLogTableItemCount);
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ }
+ else
+ {
+ Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
+ }
+ break;
+
+ case IOCTL_AVM_RDTSC_EMULATION_GET_LOG_TABLE_CONTENT:
+ if (OutputBufferLength >= sizeof(AvmRdtscEmulationLogTable))
+ {
+ RtlCopyMemory(
+ Irp->AssociatedIrp.SystemBuffer,
+ AvmRdtscEmulationLogTable,
+ sizeof(AvmRdtscEmulationLogTable));
+
+ Irp->IoStatus.Information = sizeof(AvmRdtscEmulationLogTable);
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ }
+ else
+ {
+ Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
+ }
+ break;
+
+ case IOCTL_AVM_RDTSC_EMULATION_CLEAR_LOG_TABLE:
+ RtlZeroMemory(
+ AvmRdtscEmulationLogTable,
+ sizeof(AvmRdtscEmulationLogTable));
+
+ AvmRdtscEmulationLogTableItemCount = 0;
+
+ Irp->IoStatus.Information = 0;
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ break;
+
+ case IOCTL_AVM_RDTSC_EMULATION_GET_CONFIGURATION:
+ if (OutputBufferLength >= sizeof(AvmRdtscEmulationConfiguration))
+ {
+ RtlCopyMemory(
+ Irp->AssociatedIrp.SystemBuffer,
+ &AvmRdtscEmulationConfiguration,
+ sizeof(AvmRdtscEmulationConfiguration));
+
+ Irp->IoStatus.Information = sizeof(AvmRdtscEmulationConfiguration);
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ }
+ else
+ {
+ Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
+ }
+ break;
+
+ case IOCTL_AVM_RDTSC_EMULATION_SET_CONFIGURATION:
+ if (InputBufferLength >= sizeof(AvmRdtscEmulationConfiguration))
+ {
+ RtlCopyMemory(
+ &AvmRdtscEmulationConfiguration,
+ Irp->AssociatedIrp.SystemBuffer,
+ sizeof(AvmRdtscEmulationConfiguration));
+
+ Irp->IoStatus.Information = 0;
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ }
+ else
+ {
+ Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
+ }
+ break;
+ }
+ KeReleaseSpinLock(&AvmRdtscEmulationLogTableLock, OldIrql);
+
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return Status;
+}
+
+NTSTATUS
+NTAPI
+AvmDispatchInitialize(
+ IN PDRIVER_OBJECT DriverObject
+ )
+{
+ NTSTATUS Status;
+
+ UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(AVM_DEVICE_NAME);
+ PDEVICE_OBJECT DeviceObject;
+ Status = IoCreateDevice(
+ DriverObject,
+ 0,
+ &DeviceName,
+ FILE_DEVICE_UNKNOWN,
+ FILE_DEVICE_SECURE_OPEN,
+ FALSE,
+ &DeviceObject);
+
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ DriverObject->MajorFunction[IRP_MJ_CREATE] = &AvmDispatch_Create;
+ DriverObject->MajorFunction[IRP_MJ_CLOSE] = &AvmDispatch_Close;
+ DriverObject->MajorFunction[IRP_MJ_READ] = &AvmDispatch_Read;
+ DriverObject->MajorFunction[IRP_MJ_WRITE] = &AvmDispatch_Write;
+ DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = &AvmDispatch_IoControl;
+ DriverObject->DriverUnload = &AvmDestroy;
+
+ DeviceObject->Flags |= DO_BUFFERED_IO;
+ DeviceObject->Flags &= (~DO_DEVICE_INITIALIZING);
+
+ UNICODE_STRING SymbolicName = RTL_CONSTANT_STRING(AVM_SYMBOLIC_NAME);
+ Status = IoCreateSymbolicLink(
+ &SymbolicName,
+ &DeviceName);
+
+ return Status;
+}
+
+VOID
+NTAPI
+AvmDispatchDestroy(
+ IN PDRIVER_OBJECT DriverObject
+ )
+{
+ UNICODE_STRING SymbolicName = RTL_CONSTANT_STRING(AVM_SYMBOLIC_NAME);
+
+ IoDeleteSymbolicLink(&SymbolicName);
+ IoDeleteDevice(DriverObject->DeviceObject);
+}
diff --git a/src/avmext/dispatch.h b/src/avmext/dispatch.h
new file mode 100644
index 0000000..e6d1ada
--- /dev/null
+++ b/src/avmext/dispatch.h
@@ -0,0 +1,78 @@
+#pragma once
+#include <ntifs.h>
+
+#define IOCTL_AVM_RDTSC_EMULATION_ENABLE \
+ CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define IOCTL_AVM_RDTSC_EMULATION_DISABLE \
+ CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define IOCTL_AVM_RDTSC_EMULATION_GET_LOG_TABLE_SIZE_IN_BYTES \
+ CTL_CODE(FILE_DEVICE_UNKNOWN, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define IOCTL_AVM_RDTSC_EMULATION_GET_LOG_TABLE_ITEM_COUNT \
+ CTL_CODE(FILE_DEVICE_UNKNOWN, 0x803, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define IOCTL_AVM_RDTSC_EMULATION_GET_LOG_TABLE_CONTENT \
+ CTL_CODE(FILE_DEVICE_UNKNOWN, 0x804, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define IOCTL_AVM_RDTSC_EMULATION_CLEAR_LOG_TABLE \
+ CTL_CODE(FILE_DEVICE_UNKNOWN, 0x805, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define IOCTL_AVM_RDTSC_EMULATION_GET_CONFIGURATION \
+ CTL_CODE(FILE_DEVICE_UNKNOWN, 0x806, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define IOCTL_AVM_RDTSC_EMULATION_SET_CONFIGURATION \
+ CTL_CODE(FILE_DEVICE_UNKNOWN, 0x807, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+
+NTSTATUS
+NTAPI
+AvmDispatch_Create(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp
+ );
+
+NTSTATUS
+NTAPI
+AvmDispatch_Close(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp
+ );
+
+NTSTATUS
+NTAPI
+AvmDispatch_Read(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp
+ );
+
+NTSTATUS
+NTAPI
+AvmDispatch_Write(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp
+ );
+
+NTSTATUS
+NTAPI
+AvmDispatch_IoControl(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp
+ );
+
+//
+// Initialize & destroy routines.
+//
+
+NTSTATUS
+NTAPI
+AvmDispatchInitialize(
+ IN PDRIVER_OBJECT DriverObject
+ );
+
+VOID
+NTAPI
+AvmDispatchDestroy(
+ IN PDRIVER_OBJECT DriverObject
+ );
diff --git a/src/avmext/entry.c b/src/avmext/entry.c
new file mode 100644
index 0000000..3dc070d
--- /dev/null
+++ b/src/avmext/entry.c
@@ -0,0 +1,61 @@
+#include "entry.h"
+#include "dispatch.h"
+#include "ntinternal.h"
+#include "rdtscemu.h"
+
+#include <ntifs.h>
+
+NTSTATUS
+NTAPI
+AvmInitialize(
+ IN PDRIVER_OBJECT DriverObject
+ )
+{
+ NTSTATUS Status;
+
+ Status = AvmNtInternalInitialize(DriverObject);
+
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ Status = AvmDispatchInitialize(DriverObject);
+
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ Status = AvmRdtscEmulationInitialize(DriverObject);
+
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ return Status;
+}
+
+VOID
+NTAPI
+AvmDestroy(
+ IN PDRIVER_OBJECT DriverObject
+ )
+{
+ AvmRdtscEmulationDestroy(DriverObject);
+ AvmDispatchDestroy(DriverObject);
+ AvmNtInternalDestroy(DriverObject);
+}
+
+NTSTATUS
+NTAPI
+DriverEntry(
+ IN PDRIVER_OBJECT DriverObject,
+ IN PUNICODE_STRING AvmgistryPath
+ )
+{
+ UNREFERENCED_PARAMETER(AvmgistryPath);
+
+ return AvmInitialize(DriverObject);
+}
\ No newline at end of file
diff --git a/src/avmext/entry.h b/src/avmext/entry.h
new file mode 100644
index 0000000..1cd16f7
--- /dev/null
+++ b/src/avmext/entry.h
@@ -0,0 +1,33 @@
+#pragma once
+#include <ntifs.h>
+
+#define AVM_DEVICE_NAME L"\\Device\\AvmExt"
+#define AVM_SYMBOLIC_NAME L"\\??\\AvmExt"
+
+//
+// Initialize & destroy routines.
+//
+
+NTSTATUS
+NTAPI
+AvmInitialize(
+ IN PDRIVER_OBJECT DriverObject
+ );
+
+VOID
+NTAPI
+AvmDestroy(
+ IN PDRIVER_OBJECT DriverObject
+ );
+
+//
+// Driver entry-point.
+//
+
+NTSTATUS
+NTAPI
+DriverEntry(
+ IN PDRIVER_OBJECT DriverObject,
+ IN PUNICODE_STRING AvmgistryPath
+ );
+
diff --git a/src/avmext/i386/common.inc b/src/avmext/i386/common.inc
new file mode 100644
index 0000000..2ab6155
--- /dev/null
+++ b/src/avmext/i386/common.inc
@@ -0,0 +1,71 @@
+;
+; Constants for system irql and IDT vector conversion.
+;
+
+RPL_MASK equ 00003H
+
+;
+; Gdt Descriptor Offset Definitions.
+;
+
+KGDT_R3_DATA equ 00020H
+KGDT_R0_PCR equ 00030H
+
+;++
+;
+; ENTER_TRAP
+;
+; Macro Description:
+;
+; Build the TRAP_FRAME structure and set registers needed by a trap.
+;
+;--
+
+TRAP_ENTRY macro
+
+ push ebp
+ push ebx
+ push esi
+ push edi
+
+ push fs
+
+ push eax
+ push ecx
+ push edx
+
+ push ds
+ push es
+ push gs
+
+;
+; Set up segment registers.
+;
+
+ mov ax, KGDT_R3_DATA or RPL_MASK
+ mov ds, ax
+ mov es, ax
+
+ mov ax, KGDT_R0_PCR
+ mov fs, ax
+
+ endm
+
+TRAP_END macro
+
+ pop gs
+ pop es
+ pop ds
+
+ pop edx
+ pop ecx
+ pop eax
+
+ pop fs
+
+ pop edi
+ pop esi
+ pop ebx
+ pop ebp
+
+ endm
diff --git a/src/avmext/i386/trap.asm b/src/avmext/i386/trap.asm
new file mode 100644
index 0000000..ab4ca04
--- /dev/null
+++ b/src/avmext/i386/trap.asm
@@ -0,0 +1,55 @@
+.386
+.MODEL FLAT
+include common.inc
+
+;
+; Extern functions.
+;
+
+EXTRN _AvmRdtscEmulationTrap0D@4:PROC
+EXTRN _AvmpRdtscEmulationTrap0DOriginalHandler:DWORD
+
+; ;
+; ------------------------------------------------------------------- ;
+; CODE SECTION ;
+; ------------------------------------------------------------------- ;
+; ;
+
+.CODE
+
+ _AvmpRdtscEmulationTrap0D PROC PUBLIC
+ TRAP_ENTRY
+
+;
+; Call our new trap function.
+;
+
+ push esp
+ call _AvmRdtscEmulationTrap0D@4
+
+;
+; If our trap did not handle the fault,
+; pass it to the original trap handler.
+;
+
+ cmp eax, 0
+ jz OldHandler
+
+;
+; Fault has been handled,
+; return from the interrupt handler.
+;
+
+ TRAP_END
+
+ add esp, 4
+ iretd
+
+OldHandler:
+
+ TRAP_END
+ jmp dword ptr [_AvmpRdtscEmulationTrap0DOriginalHandler]
+
+ _AvmpRdtscEmulationTrap0D ENDP
+
+END
diff --git a/src/avmext/ntinternal.c b/src/avmext/ntinternal.c
new file mode 100644
index 0000000..f25a07d
--- /dev/null
+++ b/src/avmext/ntinternal.c
@@ -0,0 +1,21 @@
+#include "ntinternal.h"
+
+NTSTATUS
+NTAPI
+AvmNtInternalInitialize(
+ IN PDRIVER_OBJECT DriverObject
+ )
+{
+ UNREFERENCED_PARAMETER(DriverObject);
+
+ return STATUS_SUCCESS;
+}
+
+VOID
+NTAPI
+AvmNtInternalDestroy(
+ IN PDRIVER_OBJECT DriverObject
+ )
+{
+ UNREFERENCED_PARAMETER(DriverObject);
+}
diff --git a/src/avmext/ntinternal.h b/src/avmext/ntinternal.h
new file mode 100644
index 0000000..89267bd
--- /dev/null
+++ b/src/avmext/ntinternal.h
@@ -0,0 +1,227 @@
+#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 ReadTSC() __rdtsc()
+#define ReadTSCP(data) __rdtscp(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;
+};
+
+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;
+ };
+};
+
+//
+// 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/rdtscemu.c b/src/avmext/rdtscemu.c
new file mode 100644
index 0000000..904a03e
--- /dev/null
+++ b/src/avmext/rdtscemu.c
@@ -0,0 +1,365 @@
+#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);
+
+ //
+ // 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();
+}
+
diff --git a/src/avmext/rdtscemu.h b/src/avmext/rdtscemu.h
new file mode 100644
index 0000000..b083df8
--- /dev/null
+++ b/src/avmext/rdtscemu.h
@@ -0,0 +1,140 @@
+#pragma once
+#include "ntinternal.h"
+
+#include <ntifs.h>
+
+typedef enum _AVM_RDTSC_EMULATION_METHOD_TYPE
+{
+ AvmRdtscEmulationConstantMethodType,
+ AvmRdtscEmulationIncreasingMethodType,
+} AVM_RDTSC_EMULATION_METHOD_TYPE;
+
+typedef enum _AVM_RDTSC_EMULATION_INSTRUCTION_TYPE
+{
+ AvmRdtscType,
+ AvmRdtscpType,
+} AVM_RDTSC_EMULATION_INSTRUCTION_TYPE;
+
+typedef struct _AVM_RDTSC_EMULATION_LOG_TABLE_ITEM
+{
+ ULONG ProcessId;
+ ULONG ReturnedEax;
+ ULONG ReturnedEdx;
+ ULONG ReturnedEcx;
+ PVOID Eip;
+ AVM_RDTSC_EMULATION_INSTRUCTION_TYPE Instruction;
+} AVM_RDTSC_EMULATION_LOG_TABLE_ITEM, *PAVM_RDTSC_EMULATION_LOG_TABLE_ITEM;
+
+typedef struct _AVM_RDTSC_EMULATION_CONFIGURATION
+{
+ AVM_RDTSC_EMULATION_METHOD_TYPE Method;
+ ULONG ProcessId;
+
+ ULONGLONG TscValue;
+ ULONG TscAux;
+
+ ULONG DeltaFrom;
+ ULONG DeltaTo;
+} AVM_RDTSC_EMULATION_CONFIGURATION, *PAVM_RDTSC_EMULATION_CONFIGURATION;
+
+//
+// RDTSC table.
+//
+#define AVM_RDTSC_EMULATION_LOG_TABLE_SIZE (2048)
+
+extern AVM_RDTSC_EMULATION_LOG_TABLE_ITEM AvmRdtscEmulationLogTable[AVM_RDTSC_EMULATION_LOG_TABLE_SIZE];
+extern ULONG AvmRdtscEmulationLogTableSizeInBytes;
+extern ULONG AvmRdtscEmulationLogTableItemCount;
+extern KSPIN_LOCK AvmRdtscEmulationLogTableLock;
+
+extern AVM_RDTSC_EMULATION_CONFIGURATION AvmRdtscEmulationConfiguration;
+
+//
+// Binary representation of 'rdtsc' instruction.
+//
+static const UCHAR AvmOpRdtsc[] = { 0x0F, 0x31 };
+
+//
+// Binary representation of 'rdtscp' instruction.
+//
+static const UCHAR AvmOpRdtscp[] = { 0x0F, 0x01, 0xF9 };
+
+//
+// Private functions.
+//
+
+//
+// New Trap0D handler.
+//
+
+extern ULONG_PTR AvmpRdtscEmulationTrap0DOriginalHandler;
+
+extern
+void __cdecl
+AvmpRdtscEmulationTrap0D(
+ VOID
+ );
+
+BOOLEAN
+NTAPI
+AvmRdtscEmulationTrap0D(
+ IN PAVM_KTRAP_FRAME UserFrame
+ );
+
+VOID
+NTAPI
+AvmpRdtscEmulationSetTimeStampDisableFlag(
+ VOID
+ );
+
+VOID
+NTAPI
+AvmpRdtscEmulationUnsetTimeStampDisableFlag(
+ VOID
+ );
+
+VOID
+NTAPI
+AvmpRdtscEmulationSwitchToProcessor(
+ IN UCHAR ProcessorIndex
+ );
+
+VOID
+NTAPI
+AvmpRdtscEmulationHookInterruptEntry(
+ IN UCHAR Index,
+ IN ULONG_PTR NewRoutineAddress,
+ OUT ULONG_PTR* OldRoutineAddress
+ );
+
+//
+// Public functions.
+//
+
+VOID
+NTAPI
+AvmRdtscEmulationEnable(
+ VOID
+ );
+
+VOID
+NTAPI
+AvmRdtscEmulationDisable(
+ VOID
+ );
+
+//
+// Initialize & destroy routines.
+//
+
+NTSTATUS
+NTAPI
+AvmRdtscEmulationInitialize(
+ IN PDRIVER_OBJECT DriverObject
+ );
+
+VOID
+NTAPI
+AvmRdtscEmulationDestroy(
+ IN PDRIVER_OBJECT DriverObject
+ );
diff --git a/src/avmext/rdtscemup.c b/src/avmext/rdtscemup.c
new file mode 100644
index 0000000..0e59eb5
--- /dev/null
+++ b/src/avmext/rdtscemup.c
@@ -0,0 +1,125 @@
+#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
+
+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;
+
+ IdtAt->OffsetLow = (USHORT)(NewRoutineAddress);
+ IdtAt->OffsetMiddle = (USHORT)(NewRoutineAddress >> 16);
+ IdtAt->OffsetHigh = (ULONG) (NewRoutineAddress >> 32);
+
+ *OldRoutineAddress = OriginalHandler;
+ }
+ EnableInterrupts();
+}
+
+#endif
diff --git a/src/avmextctrl/avmextctrl.c b/src/avmextctrl/avmextctrl.c
new file mode 100644
index 0000000..d7e6242
--- /dev/null
+++ b/src/avmextctrl/avmextctrl.c
@@ -0,0 +1,400 @@
+#include "avmextctrl.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+HANDLE AvmDeviceHandle = INVALID_HANDLE_VALUE;
+
+VOID
+AvmRdtscTest(
+ VOID
+ )
+{
+ ULONG64 tsc1;
+ ULONG64 tsc2;
+ ULONG tsc_aux1, tsc_aux2;
+ ULONG diff;
+
+ tsc1 = __rdtsc();
+ tsc2 = __rdtsc();
+ diff = (ULONG)(tsc2 - tsc1);
+ printf("\t rdtsc diff: %u\n", diff);
+
+ tsc1 = __rdtscp(&tsc_aux1);
+ tsc2 = __rdtscp(&tsc_aux2);
+ diff = (ULONG)(tsc2 - tsc1);
+ printf("\t rdtscp diff: %u\n", diff);
+ printf("\t tsc_aux1: %u\n", tsc_aux1);
+ printf("\t tsc_aux2: %u\n", tsc_aux2);
+}
+
+BOOL
+AvmInitialize(
+ VOID
+ )
+{
+ AvmDeviceHandle = CreateFile(
+ TEXT("\\\\.\\AvmExt"),
+ GENERIC_WRITE | GENERIC_READ,
+ 0,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ return AvmDeviceHandle != INVALID_HANDLE_VALUE;
+}
+
+VOID
+AvmDestroy(
+ VOID
+ )
+{
+ if (AvmDeviceHandle != INVALID_HANDLE_VALUE)
+ {
+ CloseHandle(AvmDeviceHandle);
+ }
+}
+
+BOOL
+AvmGetConfiguration(
+ PAVM_RDTSC_EMULATION_CONFIGURATION Configuration
+ )
+{
+ DWORD BytesReturned;
+
+ DeviceIoControl(
+ AvmDeviceHandle,
+ IOCTL_AVM_RDTSC_EMULATION_GET_CONFIGURATION,
+ NULL,
+ 0,
+ Configuration,
+ sizeof(*Configuration),
+ &BytesReturned,
+ NULL);
+
+ return TRUE;
+}
+
+BOOL
+AvmSetConfiguration(
+ PAVM_RDTSC_EMULATION_CONFIGURATION Configuration
+ )
+{
+ DWORD BytesReturned;
+
+ DeviceIoControl(
+ AvmDeviceHandle,
+ IOCTL_AVM_RDTSC_EMULATION_SET_CONFIGURATION,
+ Configuration,
+ sizeof(*Configuration),
+ NULL,
+ 0,
+ &BytesReturned,
+ NULL);
+
+ return TRUE;
+}
+
+BOOL
+AvmEmulationEnable(
+ VOID
+ )
+{
+ DWORD BytesReturned;
+
+ DeviceIoControl(
+ AvmDeviceHandle,
+ IOCTL_AVM_RDTSC_EMULATION_ENABLE,
+ NULL,
+ 0,
+ NULL,
+ 0,
+ &BytesReturned,
+ NULL);
+
+ return TRUE;
+}
+
+BOOL
+AvmEmulationDisable(
+ VOID
+ )
+{
+ DWORD BytesReturned;
+
+ DeviceIoControl(
+ AvmDeviceHandle,
+ IOCTL_AVM_RDTSC_EMULATION_DISABLE,
+ NULL,
+ 0,
+ NULL,
+ 0,
+ &BytesReturned,
+ NULL);
+
+ return TRUE;
+}
+
+BOOL
+AvmGetLogTable(
+ PULONG LogTableSizeInBytes,
+ PULONG LogTableItemCount,
+ PAVM_RDTSC_EMULATION_LOG_TABLE_ITEM LogTable
+ )
+{
+ DWORD BytesReturned;
+
+ DeviceIoControl(
+ AvmDeviceHandle,
+ IOCTL_AVM_RDTSC_EMULATION_GET_LOG_TABLE_SIZE_IN_BYTES,
+ NULL,
+ 0,
+ LogTableSizeInBytes,
+ sizeof(*LogTableSizeInBytes),
+ &BytesReturned,
+ NULL);
+
+ DeviceIoControl(
+ AvmDeviceHandle,
+ IOCTL_AVM_RDTSC_EMULATION_GET_LOG_TABLE_ITEM_COUNT,
+ NULL,
+ 0,
+ LogTableItemCount,
+ sizeof(*LogTableItemCount),
+ &BytesReturned,
+ NULL);
+
+ if (LogTable != NULL)
+ {
+ DeviceIoControl(
+ AvmDeviceHandle,
+ IOCTL_AVM_RDTSC_EMULATION_GET_LOG_TABLE_CONTENT,
+ NULL,
+ 0,
+ LogTable,
+ *LogTableSizeInBytes,
+ &BytesReturned,
+ NULL);
+ }
+
+ return TRUE;
+}
+
+BOOL
+AvmClearLogTable(
+ VOID
+ )
+{
+ DWORD BytesReturned;
+
+ DeviceIoControl(
+ AvmDeviceHandle,
+ IOCTL_AVM_RDTSC_EMULATION_CLEAR_LOG_TABLE,
+ NULL,
+ 0,
+ NULL,
+ 0,
+ &BytesReturned,
+ NULL);
+
+ return TRUE;
+}
+
+VOID
+AvmPrintHelp(
+ VOID
+ )
+{
+ printf("Usage:\n");
+ printf(" avmextctrl.exe [--enable] [--disable] [--test] [--clear-table]\n");
+ printf(" [--print-table] [--print-config] [--tsc-value N] [--tsc-aux N]\n");
+ printf(" [--method M] [--delta-from N] [--delta-to N]\n");
+ printf("\n");
+ printf(" --enable Enable RDTSC hooking\n");
+ printf(" --disable Disable RDTSC hooking\n");
+ printf(" --test Perform RDTSC hooking\n");
+ printf(" --clear-table Clear RDTSC log table\n");
+ printf(" --print-table Print current RDTSC log table\n");
+ printf(" --method M Set RDTSC hooking method [constant|increasing]\n");
+ printf(" --tsc-value N Set initial TSC value\n");
+ printf(" --tsc-aux N Set TSC_AUX value (returned by RDTSCP)\n");
+ printf(" --delta-from N Set minimal delta between two RDTSC calls\n");
+ printf(" --delta-to N Set maximal delta between two RDTSC calls\n");
+ printf(" --print-config Print final cofig\n");
+ printf("\n");
+}
+
+int
+main(
+ int Argc,
+ char** Argv
+ )
+{
+ if (Argc == 1)
+ {
+ AvmPrintHelp();
+ exit(0);
+ }
+
+ if (!AvmInitialize())
+ {
+ printf("Cannot initialize AVM!\n");
+ exit(-1);
+ }
+
+ int CurrentArgc = 0;
+ BOOL DoEnable = FALSE;
+ BOOL DoDisable = FALSE;
+ BOOL DoTest = FALSE;
+ BOOL DoClearTable = FALSE;
+ BOOL DoPrintTable = FALSE;
+ BOOL DoPrintConfig = FALSE;
+ AVM_RDTSC_EMULATION_CONFIGURATION Configuration = { 0 };
+
+ AvmGetConfiguration(&Configuration);
+
+ while (++CurrentArgc < Argc)
+ {
+ if (strcmp(Argv[CurrentArgc], "--enable") == 0)
+ {
+ DoEnable = TRUE;
+ }
+ else if (strcmp(Argv[CurrentArgc], "--disable") == 0)
+ {
+ DoDisable = TRUE;
+ }
+ else if (strcmp(Argv[CurrentArgc], "--test") == 0)
+ {
+ DoTest = TRUE;
+ }
+ else if (strcmp(Argv[CurrentArgc], "--clear-table") == 0)
+ {
+ DoClearTable = TRUE;
+ }
+ else if (strcmp(Argv[CurrentArgc], "--print-table") == 0)
+ {
+ DoPrintTable = TRUE;
+ }
+ else if (strcmp(Argv[CurrentArgc], "--print-config") == 0)
+ {
+ DoPrintConfig = TRUE;
+ }
+ else if (strcmp(Argv[CurrentArgc], "--method") == 0)
+ {
+ const char* Method = Argv[++CurrentArgc];
+
+ if (strcmp(Method, "constant") == 0)
+ {
+ Configuration.Method = AvmRdtscEmulationConstantMethodType;
+ }
+ else if (strcmp(Method, "increasing") == 0)
+ {
+ Configuration.Method = AvmRdtscEmulationIncreasingMethodType;
+ }
+ else
+ {
+ printf("Ivalid method type!\n");
+ exit(-1);
+ }
+ }
+ else if (strcmp(Argv[CurrentArgc], "--tsc-value") == 0)
+ {
+ const char* TscValue = Argv[++CurrentArgc];
+
+ Configuration.TscValue = atoll(TscValue);
+ }
+ else if (strcmp(Argv[CurrentArgc], "--tsc-aux") == 0)
+ {
+ const char* TscAux = Argv[++CurrentArgc];
+
+ Configuration.TscAux = atol(TscAux);
+ }
+ else if (strcmp(Argv[CurrentArgc], "--delta-from") == 0)
+ {
+ const char* DeltaFrom = Argv[++CurrentArgc];
+
+ Configuration.DeltaFrom = atoi(DeltaFrom);
+ }
+ else if (strcmp(Argv[CurrentArgc], "--delta-to") == 0)
+ {
+ const char* DeltaTo = Argv[++CurrentArgc];
+
+ Configuration.DeltaTo = atoi(DeltaTo);
+ }
+ else
+ {
+ printf("Invalid argument '%s'!\n", Argv[CurrentArgc]);
+ exit(-1);
+ }
+ }
+
+ AvmSetConfiguration(&Configuration);
+
+ if (DoEnable)
+ {
+ printf("[+] Enabling...\n");
+ AvmEmulationEnable();
+ }
+
+ if (DoClearTable)
+ {
+ printf("[+] Clearing LogTable...\n");
+ AvmClearLogTable();
+ }
+
+ if (DoTest)
+ {
+ printf("[+] Performing test...\n");
+ AvmRdtscTest();
+ }
+
+ if (DoDisable)
+ {
+ printf("[+] Disabling...\n");
+ AvmEmulationDisable();
+ }
+
+ if (DoPrintConfig)
+ {
+ printf("[+] Current configuration:\n");
+ printf("\t Method: %s\n", Configuration.Method == AvmRdtscEmulationConstantMethodType ? "constant" : "increasing");
+ printf("\t TscValue: %" PRIu64 "\n", Configuration.TscValue);
+ printf("\t TscAux: %u\n", Configuration.TscAux);
+ printf("\t DeltaFrom: %u\n", Configuration.DeltaFrom);
+ printf("\t DeltaTo: %u\n", Configuration.DeltaTo);
+ printf("\n");
+ }
+
+ if (DoPrintTable)
+ {
+ printf("[+] Current LogTable:\n");
+
+ ULONG LogTableSizeInBytes;
+ ULONG LogTableItemCount;
+ AvmGetLogTable(&LogTableSizeInBytes, &LogTableItemCount, NULL);
+
+ PAVM_RDTSC_EMULATION_LOG_TABLE_ITEM LogTable = (PAVM_RDTSC_EMULATION_LOG_TABLE_ITEM)calloc(LogTableSizeInBytes, 1);
+ AvmGetLogTable(&LogTableSizeInBytes, &LogTableItemCount, LogTable);
+
+ printf("\t LogTableSizeInBytes: %u\n", LogTableSizeInBytes);
+ printf("\t LogTableItemCount: %u\n", LogTableItemCount);
+ printf("\n");
+
+ for (ULONG i = 0; i < LogTableItemCount; i++)
+ {
+ printf("\t LogTable[%u].ProcessId: %u\n", i, LogTable[i].ProcessId);
+ printf("\t LogTable[%u].Instruction: %s\n", i, LogTable[i].Instruction == AvmRdtscType ? "AvmRdtscType" : "AvmRdtscpType");
+ printf("\t LogTable[%u].Eip: %p\n", i, LogTable[i].Eip);
+ printf("\n");
+ }
+
+ free(LogTable);
+ }
+
+ AvmDestroy();
+
+ return 0;
+}
diff --git a/src/avmextctrl/avmextctrl.h b/src/avmextctrl/avmextctrl.h
new file mode 100644
index 0000000..aa2735e
--- /dev/null
+++ b/src/avmextctrl/avmextctrl.h
@@ -0,0 +1,60 @@
+#pragma once
+#include <windows.h>
+
+#define IOCTL_AVM_RDTSC_EMULATION_ENABLE \
+ CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define IOCTL_AVM_RDTSC_EMULATION_DISABLE \
+ CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define IOCTL_AVM_RDTSC_EMULATION_GET_LOG_TABLE_SIZE_IN_BYTES \
+ CTL_CODE(FILE_DEVICE_UNKNOWN, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define IOCTL_AVM_RDTSC_EMULATION_GET_LOG_TABLE_ITEM_COUNT \
+ CTL_CODE(FILE_DEVICE_UNKNOWN, 0x803, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define IOCTL_AVM_RDTSC_EMULATION_GET_LOG_TABLE_CONTENT \
+ CTL_CODE(FILE_DEVICE_UNKNOWN, 0x804, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define IOCTL_AVM_RDTSC_EMULATION_CLEAR_LOG_TABLE \
+ CTL_CODE(FILE_DEVICE_UNKNOWN, 0x805, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define IOCTL_AVM_RDTSC_EMULATION_GET_CONFIGURATION \
+ CTL_CODE(FILE_DEVICE_UNKNOWN, 0x806, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define IOCTL_AVM_RDTSC_EMULATION_SET_CONFIGURATION \
+ CTL_CODE(FILE_DEVICE_UNKNOWN, 0x807, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+typedef enum _AVM_RDTSC_EMULATION_INSTRUCTION_TYPE
+{
+ AvmRdtscType,
+ AvmRdtscpType,
+} AVM_RDTSC_EMULATION_INSTRUCTION_TYPE;
+
+typedef struct _AVM_RDTSC_EMULATION_LOG_TABLE_ITEM
+{
+ ULONG ProcessId;
+ ULONG ReturnedEax;
+ ULONG ReturnedEdx;
+ ULONG ReturnedEcx;
+ PVOID Eip;
+ AVM_RDTSC_EMULATION_INSTRUCTION_TYPE Instruction;
+} AVM_RDTSC_EMULATION_LOG_TABLE_ITEM, *PAVM_RDTSC_EMULATION_LOG_TABLE_ITEM;
+
+typedef enum _AVM_RDTSC_EMULATION_METHOD_TYPE
+{
+ AvmRdtscEmulationConstantMethodType,
+ AvmRdtscEmulationIncreasingMethodType,
+} AVM_RDTSC_EMULATION_METHOD_TYPE;
+
+typedef struct _AVM_RDTSC_EMULATION_CONFIGURATION
+{
+ AVM_RDTSC_EMULATION_METHOD_TYPE Method;
+ ULONG ProcessId;
+
+ ULONGLONG TscValue;
+ ULONG TscAux;
+
+ ULONG DeltaFrom;
+ ULONG DeltaTo;
+} AVM_RDTSC_EMULATION_CONFIGURATION, *PAVM_RDTSC_EMULATION_CONFIGURATION;
diff --git a/src/avmextctrl/avmextctrl.vcxproj b/src/avmextctrl/avmextctrl.vcxproj
new file mode 100644
index 0000000..8e94617
--- /dev/null
+++ b/src/avmextctrl/avmextctrl.vcxproj
@@ -0,0 +1,165 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{E14D2DC8-99BE-44EC-815C-8A0A2A4EE259}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>avmextctrl</RootNamespace>
+ <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v140</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v140</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v140</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v140</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="Shared">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ <OutDir>$(SolutionDir)bin\$(PlatformShortName)\$(Configuration)\</OutDir>
+ <IntDir>$(SolutionDir)bin\obj\$(PlatformShortName)\$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <LinkIncremental>true</LinkIncremental>
+ <OutDir>$(SolutionDir)bin\$(PlatformShortName)\$(Configuration)\</OutDir>
+ <IntDir>$(SolutionDir)bin\obj\$(PlatformShortName)\$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>$(SolutionDir)bin\$(PlatformShortName)\$(Configuration)\</OutDir>
+ <IntDir>$(SolutionDir)bin\obj\$(PlatformShortName)\$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>$(SolutionDir)bin\$(PlatformShortName)\$(Configuration)\</OutDir>
+ <IntDir>$(SolutionDir)bin\obj\$(PlatformShortName)\$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="avmextctrl.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="avmextctrl.h" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/src/avmextctrl/avmextctrl.vcxproj.filters b/src/avmextctrl/avmextctrl.vcxproj.filters
new file mode 100644
index 0000000..49aba6d
--- /dev/null
+++ b/src/avmextctrl/avmextctrl.vcxproj.filters
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="avmextctrl.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="avmextctrl.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/src/avmextctrl/avmextctrl.vcxproj.user b/src/avmextctrl/avmextctrl.vcxproj.user
new file mode 100644
index 0000000..786b676
--- /dev/null
+++ b/src/avmextctrl/avmextctrl.vcxproj.user
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LocalDebuggerCommandArguments>--enable --method increasing --delta-from 50 --delta-to 100 --tsc-aux 30 --print-config --print-table --test</LocalDebuggerCommandArguments>
+ <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+ </PropertyGroup>
+</Project>
\ No newline at end of file
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Thu, Nov 14, 4:08 PM (10 h, 36 m)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
9d/2c/d889cbe8a5e39025c6f165ce6c91
Attached To
rAVM avmext
Event Timeline
Log In to Comment