├── Imgs ├── Tracer.gif ├── readme.jpg ├── custom-qemu-1.jpg ├── custom-qemu-2.jpg ├── custom-qemu-3.PNG └── custom-qemu-4.png ├── Message Tracing ├── exe │ ├── event.vcxproj.user │ ├── event.vcxproj.Filters │ ├── event.vcxproj │ ├── eventtest.c │ └── install.c ├── wdm │ ├── event.rc │ ├── RCa02068 │ ├── public.h │ ├── event.h │ ├── event.vcxproj.Filters │ ├── event.vcxproj │ └── event.c ├── eventsample.sln └── README.md ├── ObRegisterCallbacks ├── ObRegisterCallbacks │ ├── ObRegisterCallbacks.vcxproj.user │ ├── ObRegisterCallbacks.vcxproj.filters │ ├── Driver.h │ ├── Driver.c │ ├── ObRegisterCallbacks.inf │ ├── Handlers.c │ └── ObRegisterCallbacks.vcxproj └── ObRegisterCallbacks.sln ├── HypervisorBypassWithNMI ├── README.md ├── HypervisorBypassWithNMI │ ├── Driver.c │ ├── HypervisorBypassWithNMI.vcxproj.filters │ ├── ReadMe.txt │ ├── HypervisorBypass.c │ ├── HypervisorBypassWithNMI.inf │ ├── HypervisorBypass.h │ ├── Queue.c │ └── HypervisorBypassWithNMI.vcxproj └── HypervisorBypassWithNMI.sln ├── TypeInfoCallbacksHooker ├── Driver.h ├── Header.h ├── TypeInfoCallbacksHooker.vcxproj.filters ├── TypeInfoCallbacksHooker.inf ├── TypeInfoCallbacksHooker.vcxproj └── Driver.c ├── README.md ├── TypeInfoCallbacksHooker.sln ├── custom-qemu-for-instrumentation └── readme.md └── .gitignore /Imgs/Tracer.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SinaKarvandi/Misc/HEAD/Imgs/Tracer.gif -------------------------------------------------------------------------------- /Imgs/readme.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SinaKarvandi/Misc/HEAD/Imgs/readme.jpg -------------------------------------------------------------------------------- /Imgs/custom-qemu-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SinaKarvandi/Misc/HEAD/Imgs/custom-qemu-1.jpg -------------------------------------------------------------------------------- /Imgs/custom-qemu-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SinaKarvandi/Misc/HEAD/Imgs/custom-qemu-2.jpg -------------------------------------------------------------------------------- /Imgs/custom-qemu-3.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SinaKarvandi/Misc/HEAD/Imgs/custom-qemu-3.PNG -------------------------------------------------------------------------------- /Imgs/custom-qemu-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SinaKarvandi/Misc/HEAD/Imgs/custom-qemu-4.png -------------------------------------------------------------------------------- /Message Tracing/exe/event.vcxproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /ObRegisterCallbacks/ObRegisterCallbacks/ObRegisterCallbacks.vcxproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Message Tracing/wdm/event.rc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #define VER_FILETYPE VFT_DRV 6 | #define VER_FILESUBTYPE VFT2_DRV_SYSTEM 7 | #define VER_FILEDESCRIPTION_STR "Sample Event Driver" 8 | #define VER_INTERNALNAME_STR "event.sys" 9 | 10 | #include "common.ver" 11 | 12 | -------------------------------------------------------------------------------- /HypervisorBypassWithNMI/README.md: -------------------------------------------------------------------------------- 1 | This file contains a possible bypass to Hypervisors that virtualize an already running system using NMI. 2 | 3 | The POC is derived from : https://www.unknowncheats.me/forum/c-and-c-/390593-vm-escape-via-nmi.html#post2772568 4 | 5 | When you're in VMX Root, an attacker can send an NMI and that NMI will be serviced in VMX ROOT. If you use a same IDT for vmx root and vmx non root then you probably have this problem. 6 | -------------------------------------------------------------------------------- /HypervisorBypassWithNMI/HypervisorBypassWithNMI/Driver.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include 4 | 5 | BOOLEAN LoadNmiCallback(); 6 | 7 | VOID DrvUnload(PDRIVER_OBJECT DriverObject) { return STATUS_SUCCESS; } 8 | NTSTATUS 9 | DriverEntry(_In_ PDRIVER_OBJECT DriverObject, 10 | _In_ PUNICODE_STRING RegistryPath) { 11 | NTSTATUS status = STATUS_SUCCESS; 12 | 13 | DriverObject->DriverUnload = DrvUnload; 14 | 15 | 16 | // 17 | // Test in kernel 18 | // 19 | LoadNmiCallback(); 20 | 21 | return status; 22 | } 23 | -------------------------------------------------------------------------------- /TypeInfoCallbacksHooker/Driver.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Module Name: 4 | 5 | driver.h 6 | 7 | Abstract: 8 | 9 | This file contains the driver definitions. 10 | 11 | Environment: 12 | 13 | Kernel-mode Driver Framework 14 | 15 | --*/ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | 22 | 23 | EXTERN_C_START 24 | 25 | // 26 | // WDFDRIVER Events 27 | // 28 | 29 | DRIVER_INITIALIZE DriverEntry; 30 | EVT_WDF_DRIVER_DEVICE_ADD TypeInfoCallbacksHookerEvtDeviceAdd; 31 | EVT_WDF_OBJECT_CONTEXT_CLEANUP TypeInfoCallbacksHookerEvtDriverContextCleanup; 32 | 33 | EXTERN_C_END 34 | -------------------------------------------------------------------------------- /TypeInfoCallbacksHooker/Header.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | 5 | typedef struct _OBJECT_DUMP_CONTROL 6 | { 7 | /* 0x0000 */ void* Stream; 8 | /* 0x0008 */ unsigned long Detail; 9 | /* 0x000c */ long __PADDING__[1]; 10 | } OBJECT_DUMP_CONTROL, * POBJECT_DUMP_CONTROL; /* size: 0x0010 */ 11 | 12 | typedef enum _OB_OPEN_REASON 13 | { 14 | ObCreateHandle = 0, 15 | ObOpenHandle = 1, 16 | ObDuplicateHandle = 2, 17 | ObInheritHandle = 3, 18 | ObMaxOpenReason = 4, 19 | } OB_OPEN_REASON, * POB_OPEN_REASON; 20 | 21 | 22 | typedef struct _OB_EXTENDED_PARSE_PARAMETERS 23 | { 24 | /* 0x0000 */ unsigned short Length; 25 | /* 0x0002 */ char Padding_0[2]; 26 | /* 0x0004 */ unsigned long RestrictedAccessMask; 27 | /* 0x0008 */ struct _EJOB* Silo; 28 | } OB_EXTENDED_PARSE_PARAMETERS, * POB_EXTENDED_PARSE_PARAMETERS; /* size: 0x0010 */ 29 | 30 | -------------------------------------------------------------------------------- /Message Tracing/wdm/RCa02068: -------------------------------------------------------------------------------- 1 | #line 1"C:\\Users\\sina\\Desktop\\Windows-driver-samples-master\\Windows-driver-samples-master\\general\\event\\wdm\\event.rc" 2 | #line 1 3 | #include <windows.h> 4 | #line 3 5 | #include <ntverp.h> 6 | #line 5 7 | #define VER_FILETYPE VFT_DRV 8 | #define VER_FILESUBTYPE VFT2_DRV_SYSTEM 9 | #define VER_FILEDESCRIPTION_STR "Sample Event Driver" 10 | #define VER_INTERNALNAME_STR "event.sys" 11 | #line 10 12 | #include "common.ver" 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # misc 2 | This is a place to share my miscellaneous projects. 3 | 4 | ![](https://github.com/SinaKarvandi/Misc/raw/master/Imgs/readme.jpg) 5 | 6 | ## Message Tracing 7 | The message tracing for sharing buffer between Kernel -> to User using DPC and IRP Pending which can be used instead of WPP Tracing. 8 | 9 | ## ObRegisterCallbacks 10 | This is an example of using Windows ObRegisterCallbacks for monitoring handle creation for threads and processes. 11 | This example used in the following tutorial -> [https://rayanfam.com/topics/reversing-windows-internals-part1/] 12 | 13 | ## TypeInfoCallbacksHooker 14 | This is an example of hooking hidden callbacks of different object types in Windows. 15 | This example used in the following tutorial -> [https://rayanfam.com/topics/reversing-windows-internals-part1/] 16 | 17 | ## custom-qemu-for-instrumentation 18 | This project aims to create a fast/light way to save each instruction running in all levels of processor (e.g user/kernel/hypervisor). 19 | 20 | -------------------------------------------------------------------------------- /Message Tracing/wdm/public.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef __PUBLIC__ 3 | #define __PUBLIC__ 4 | 5 | 6 | #include "devioctl.h" 7 | #include 8 | 9 | typedef enum { 10 | IRP_BASED , 11 | EVENT_BASED 12 | } NOTIFY_TYPE; 13 | 14 | typedef struct _REGISTER_EVENT 15 | { 16 | NOTIFY_TYPE Type; 17 | HANDLE hEvent; 18 | 19 | } REGISTER_EVENT , *PREGISTER_EVENT ; 20 | 21 | #define SIZEOF_REGISTER_EVENT sizeof(REGISTER_EVENT ) 22 | 23 | 24 | #define IOCTL_REGISTER_EVENT \ 25 | CTL_CODE( FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS ) 26 | 27 | 28 | #define DRIVER_FUNC_INSTALL 0x01 29 | #define DRIVER_FUNC_REMOVE 0x02 30 | 31 | #define DRIVER_NAME "event" 32 | 33 | #endif // __PUBLIC__ 34 | 35 | // Default buffer size 36 | #define MaximumPacketsCapacity 1000 // number of packets 37 | #define PacketChunkSize 512 38 | #define UsermodeBufferSize sizeof(UINT32) + PacketChunkSize + 1 /* Becausee of Opeation code at the start of the buffer + 1 for null-termminating */ 39 | #define BufferSize MaximumPacketsCapacity * (PacketChunkSize + sizeof(BUFFER_HEADER)) 40 | -------------------------------------------------------------------------------- /Message Tracing/exe/event.vcxproj.Filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;* 6 | {55A3C741-9CBD-4AA7-98D2-AB032642C676} 7 | 8 | 9 | h;hpp;hxx;hm;inl;inc;xsd 10 | {1F31A1C8-AAB4-41AA-9353-F91A6A185B2F} 11 | 12 | 13 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml 14 | {88F38F8A-D5F3-4C24-A9E8-9B6A574D60C6} 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | -------------------------------------------------------------------------------- /Message Tracing/wdm/event.h: -------------------------------------------------------------------------------- 1 | 2 | // 3 | // DEFINES 4 | // 5 | 6 | #define NTDEVICE_NAME_STRING L"\\Device\\Event_Sample" 7 | #define SYMBOLIC_NAME_STRING L"\\DosDevices\\Event_Sample" 8 | #define TAG (ULONG)'TEVE' 9 | 10 | #if DBG 11 | #define DebugPrint(_x_) \ 12 | DbgPrint("EVENT.SYS: ");\ 13 | DbgPrint _x_; 14 | 15 | #else 16 | 17 | #define DebugPrint(_x_) 18 | 19 | #endif 20 | 21 | // 22 | // DATA 23 | // 24 | 25 | typedef struct _NOTIFY_RECORD{ 26 | NOTIFY_TYPE Type; 27 | union { 28 | PKEVENT Event; 29 | PIRP PendingIrp; 30 | } Message; 31 | KDPC Dpc; 32 | } NOTIFY_RECORD, *PNOTIFY_RECORD; 33 | 34 | DRIVER_INITIALIZE DriverEntry; 35 | 36 | _Dispatch_type_(IRP_MJ_CREATE) 37 | DRIVER_DISPATCH EventCreate; 38 | 39 | _Dispatch_type_(IRP_MJ_CLOSE) 40 | DRIVER_DISPATCH EventClose; 41 | 42 | _Dispatch_type_(IRP_MJ_DEVICE_CONTROL) 43 | DRIVER_DISPATCH EventDispatchIoControl; 44 | 45 | DRIVER_UNLOAD EventUnload; 46 | 47 | KDEFERRED_ROUTINE CustomTimerDPC; 48 | 49 | DRIVER_DISPATCH RegisterEventBasedNotification; 50 | 51 | DRIVER_DISPATCH RegisterIrpBasedNotification; 52 | 53 | _Use_decl_annotations_ VOID NotifyUsermodeCallback(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2); -------------------------------------------------------------------------------- /HypervisorBypassWithNMI/HypervisorBypassWithNMI/HypervisorBypassWithNMI.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {8E41214B-6785-4CFE-B992-037D68949A14} 18 | inf;inv;inx;mof;mc; 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | Driver Files 27 | 28 | 29 | 30 | 31 | Header Files 32 | 33 | 34 | 35 | 36 | Source Files 37 | 38 | 39 | Source Files 40 | 41 | 42 | -------------------------------------------------------------------------------- /TypeInfoCallbacksHooker/TypeInfoCallbacksHooker.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {8E41214B-6785-4CFE-B992-037D68949A14} 18 | inf;inv;inx;mof;mc; 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | Driver Files 27 | 28 | 29 | 30 | 31 | Header Files 32 | 33 | 34 | Header Files 35 | 36 | 37 | 38 | 39 | Source Files 40 | 41 | 42 | -------------------------------------------------------------------------------- /ObRegisterCallbacks/ObRegisterCallbacks/ObRegisterCallbacks.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {8E41214B-6785-4CFE-B992-037D68949A14} 18 | inf;inv;inx;mof;mc; 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | Driver Files 27 | 28 | 29 | 30 | 31 | Header Files 32 | 33 | 34 | 35 | 36 | Source Files 37 | 38 | 39 | Source Files 40 | 41 | 42 | -------------------------------------------------------------------------------- /ObRegisterCallbacks/ObRegisterCallbacks/Driver.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Module Name: 4 | 5 | driver.h 6 | 7 | Abstract: 8 | 9 | This file contains the driver definitions. 10 | 11 | Environment: 12 | 13 | Kernel-mode Driver Framework 14 | 15 | --*/ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | // Define funcs 22 | VOID DrvUnload(PDRIVER_OBJECT DriverObject); 23 | 24 | OB_PREOP_CALLBACK_STATUS 25 | PreOperationCallback( 26 | _In_ PVOID RegistrationContext, 27 | _Inout_ POB_PRE_OPERATION_INFORMATION PreInfo 28 | ); 29 | VOID 30 | PostOperationCallback( 31 | _In_ PVOID RegistrationContext, 32 | _In_ POB_POST_OPERATION_INFORMATION PostInfo 33 | ); 34 | 35 | typedef struct _TD_CALLBACK_PARAMETERS { 36 | ACCESS_MASK AccessBitsToClear; 37 | ACCESS_MASK AccessBitsToSet; 38 | } 39 | TD_CALLBACK_PARAMETERS, *PTD_CALLBACK_PARAMETERS; 40 | 41 | // TD_CALLBACK_REGISTRATION 42 | 43 | typedef struct _TD_CALLBACK_REGISTRATION { 44 | 45 | // Handle returned by ObRegisterCallbacks. 46 | PVOID RegistrationHandle; 47 | 48 | // If not NULL, filter only requests to open/duplicate handles to this 49 | // process (or one of its threads). 50 | 51 | PVOID TargetProcess; 52 | HANDLE TargetProcessId; 53 | 54 | 55 | // Currently each TD_CALLBACK_REGISTRATION has at most one process and one 56 | // thread callback. That is, we can't register more than one callback for 57 | // the same object type with a single ObRegisterCallbacks call. 58 | 59 | TD_CALLBACK_PARAMETERS ProcessParams; 60 | TD_CALLBACK_PARAMETERS ThreadParams; 61 | 62 | ULONG RegistrationId; // Index in the global TdCallbacks array. 63 | 64 | } 65 | TD_CALLBACK_REGISTRATION, *PTD_CALLBACK_REGISTRATION; 66 | 67 | -------------------------------------------------------------------------------- /HypervisorBypassWithNMI/HypervisorBypassWithNMI/ReadMe.txt: -------------------------------------------------------------------------------- 1 | ======================================================================== 2 | HypervisorBypassWithNMI Project Overview 3 | ======================================================================== 4 | 5 | This file contains a summary of what you will find in each of the files that make up your project. 6 | 7 | HypervisorBypassWithNMI.vcxproj 8 | This is the main project file for projects generated using an Application Wizard. 9 | It contains information about the version of the product that generated the file, and 10 | information about the platforms, configurations, and project features selected with the 11 | Application Wizard. 12 | 13 | HypervisorBypassWithNMI.vcxproj.filters 14 | This is the filters file for VC++ projects generated using an Application Wizard. 15 | It contains information about the association between the files in your project 16 | and the filters. This association is used in the IDE to show grouping of files with 17 | similar extensions under a specific node (for e.g. ".cpp" files are associated with the 18 | "Source Files" filter). 19 | 20 | Public.h 21 | Header file to be shared with applications. 22 | 23 | Driver.c & Driver.h 24 | DriverEntry and WDFDRIVER related functionality and callbacks. 25 | 26 | Device.c & Device.h 27 | WDFDEVICE related functionality and callbacks. 28 | 29 | Queue.c & Queue.h 30 | WDFQUEUE related functionality and callbacks. 31 | 32 | Trace.h 33 | Definitions for WPP tracing. 34 | 35 | ///////////////////////////////////////////////////////////////////////////// 36 | 37 | Learn more about Kernel Mode Driver Framework here: 38 | 39 | http://msdn.microsoft.com/en-us/library/ff544296(v=VS.85).aspx 40 | 41 | ///////////////////////////////////////////////////////////////////////////// 42 | -------------------------------------------------------------------------------- /Message Tracing/wdm/event.vcxproj.Filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;* 6 | {E8EC7AB7-4A52-40EF-AE2C-2407B7383221} 7 | 8 | 9 | h;hpp;hxx;hm;inl;inc;xsd 10 | {1F009C6F-D429-4D66-99E1-3728B7F559FE} 11 | 12 | 13 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml 14 | {7428ED65-F559-4708-A24F-FE39C1B3C86B} 15 | 16 | 17 | inf;inv;inx;mof;mc; 18 | {C55E0ADA-91DE-4876-88FD-3FF9ED492D70} 19 | 20 | 21 | 22 | 23 | Source Files 24 | 25 | 26 | 27 | 28 | Resource Files 29 | 30 | 31 | 32 | 33 | Header Files 34 | 35 | 36 | Header Files 37 | 38 | 39 | Header Files 40 | 41 | 42 | -------------------------------------------------------------------------------- /ObRegisterCallbacks/ObRegisterCallbacks/Driver.c: -------------------------------------------------------------------------------- 1 | #include "driver.h" 2 | 3 | // Global Vars 4 | OB_CALLBACK_REGISTRATION ObRegistration = { 0 }; 5 | OB_OPERATION_REGISTRATION OperationRegistrations[2] = { { 0 }, { 0 } }; 6 | UNICODE_STRING Altitude = { 0 }; 7 | // The following are for setting up callbacks for Process and Thread filtering 8 | PVOID RegistrationHandle = NULL; 9 | TD_CALLBACK_REGISTRATION CallbackRegistration = { 0 }; 10 | 11 | 12 | 13 | 14 | NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath) 15 | { 16 | NTSTATUS NtStatus = STATUS_SUCCESS; 17 | UINT64 uiIndex = 0; 18 | PDEVICE_OBJECT pDeviceObject = NULL; 19 | UNICODE_STRING usDriverName, usDosDeviceName; 20 | 21 | DbgPrint("\n[*] DriverEntry Called.\n"); 22 | 23 | DbgPrint("[*] Setting Devices major function for unload.\n"); 24 | pDriverObject->DriverUnload = DrvUnload; 25 | 26 | // ============================================== 27 | 28 | // Setup the Ob Registration calls 29 | OperationRegistrations[0].ObjectType = PsProcessType; 30 | OperationRegistrations[0].Operations |= OB_OPERATION_HANDLE_CREATE; 31 | OperationRegistrations[0].Operations |= OB_OPERATION_HANDLE_DUPLICATE; 32 | OperationRegistrations[0].PreOperation = PreOperationCallback; 33 | OperationRegistrations[0].PostOperation = PostOperationCallback; 34 | 35 | OperationRegistrations[1].ObjectType = PsThreadType; 36 | OperationRegistrations[1].Operations |= OB_OPERATION_HANDLE_CREATE; 37 | OperationRegistrations[1].Operations |= OB_OPERATION_HANDLE_DUPLICATE; 38 | OperationRegistrations[1].PreOperation = PreOperationCallback; 39 | OperationRegistrations[1].PostOperation = PostOperationCallback; 40 | 41 | 42 | RtlInitUnicodeString(&Altitude, L"1001"); 43 | 44 | ObRegistration.Version = OB_FLT_REGISTRATION_VERSION; 45 | ObRegistration.OperationRegistrationCount = 2; 46 | ObRegistration.Altitude = Altitude; 47 | ObRegistration.RegistrationContext = &CallbackRegistration; 48 | ObRegistration.OperationRegistration = OperationRegistrations; 49 | 50 | 51 | NtStatus = ObRegisterCallbacks( 52 | &ObRegistration, 53 | &RegistrationHandle // save the registration handle to remove callbacks later 54 | ); 55 | 56 | return NtStatus; 57 | } 58 | 59 | VOID DrvUnload(PDRIVER_OBJECT DriverObject) 60 | { 61 | // Unregistering callback 62 | ObUnRegisterCallbacks(RegistrationHandle); 63 | 64 | } 65 | -------------------------------------------------------------------------------- /Message Tracing/eventsample.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0 5 | MinimumVisualStudioVersion = 12.0 6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Exe", "Exe", "{2FC03CC0-1C79-456A-9014-274D87327B9A}" 7 | EndProject 8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Wdm", "Wdm", "{D1C7DC44-3DC6-475C-A445-CBDF807DC810}" 9 | EndProject 10 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "event", "exe\event.vcxproj", "{43F430EA-B1A7-4A80-B390-121C1C5A99C4}" 11 | EndProject 12 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "event", "wdm\event.vcxproj", "{21F8EA86-F950-4D2D-B256-721B3151157A}" 13 | EndProject 14 | Global 15 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 16 | Debug|Win32 = Debug|Win32 17 | Release|Win32 = Release|Win32 18 | Debug|x64 = Debug|x64 19 | Release|x64 = Release|x64 20 | EndGlobalSection 21 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 22 | {43F430EA-B1A7-4A80-B390-121C1C5A99C4}.Debug|Win32.ActiveCfg = Debug|Win32 23 | {43F430EA-B1A7-4A80-B390-121C1C5A99C4}.Debug|Win32.Build.0 = Debug|Win32 24 | {43F430EA-B1A7-4A80-B390-121C1C5A99C4}.Release|Win32.ActiveCfg = Release|Win32 25 | {43F430EA-B1A7-4A80-B390-121C1C5A99C4}.Release|Win32.Build.0 = Release|Win32 26 | {43F430EA-B1A7-4A80-B390-121C1C5A99C4}.Debug|x64.ActiveCfg = Debug|x64 27 | {43F430EA-B1A7-4A80-B390-121C1C5A99C4}.Debug|x64.Build.0 = Debug|x64 28 | {43F430EA-B1A7-4A80-B390-121C1C5A99C4}.Release|x64.ActiveCfg = Release|x64 29 | {43F430EA-B1A7-4A80-B390-121C1C5A99C4}.Release|x64.Build.0 = Release|x64 30 | {21F8EA86-F950-4D2D-B256-721B3151157A}.Debug|Win32.ActiveCfg = Debug|Win32 31 | {21F8EA86-F950-4D2D-B256-721B3151157A}.Debug|Win32.Build.0 = Debug|Win32 32 | {21F8EA86-F950-4D2D-B256-721B3151157A}.Release|Win32.ActiveCfg = Release|Win32 33 | {21F8EA86-F950-4D2D-B256-721B3151157A}.Release|Win32.Build.0 = Release|Win32 34 | {21F8EA86-F950-4D2D-B256-721B3151157A}.Debug|x64.ActiveCfg = Debug|x64 35 | {21F8EA86-F950-4D2D-B256-721B3151157A}.Debug|x64.Build.0 = Debug|x64 36 | {21F8EA86-F950-4D2D-B256-721B3151157A}.Release|x64.ActiveCfg = Release|x64 37 | {21F8EA86-F950-4D2D-B256-721B3151157A}.Release|x64.Build.0 = Release|x64 38 | EndGlobalSection 39 | GlobalSection(SolutionProperties) = preSolution 40 | HideSolutionNode = FALSE 41 | EndGlobalSection 42 | GlobalSection(NestedProjects) = preSolution 43 | {43F430EA-B1A7-4A80-B390-121C1C5A99C4} = {2FC03CC0-1C79-456A-9014-274D87327B9A} 44 | {21F8EA86-F950-4D2D-B256-721B3151157A} = {D1C7DC44-3DC6-475C-A445-CBDF807DC810} 45 | EndGlobalSection 46 | EndGlobal 47 | -------------------------------------------------------------------------------- /HypervisorBypassWithNMI/HypervisorBypassWithNMI/HypervisorBypass.c: -------------------------------------------------------------------------------- 1 | #include "HypervisorBypass.h" 2 | #include 3 | 4 | // 5 | // Global Variables 6 | // 7 | 8 | PVOID NmiRegPointer; 9 | 10 | BOOLEAN 11 | XxxNmiCallback(IN PVOID Context, IN BOOLEAN Handled) { 12 | 13 | UINT64 VmcsLink = 0; 14 | UINT64 GuestRip = 0; 15 | 16 | __vmx_vmread(VMCS_LINK_POINTER, &VmcsLink); 17 | 18 | if (VmcsLink != 0) { 19 | __vmx_vmread(GUEST_RIP, &GuestRip); 20 | if (GuestRip != NULL) { 21 | *(UINT64 *)Context = GuestRip; 22 | } 23 | } 24 | return TRUE; 25 | } 26 | 27 | ULONG_PTR IpiBroadcastOnCore(ULONG_PTR context) { 28 | ULONG CurrentCore = KeGetCurrentProcessorIndex(); 29 | for (size_t i = 0; i < 100; i++) { 30 | 31 | // 32 | // The 0th core is responsible to inject NMI on each core 33 | // 34 | if (CurrentCore != 0) { 35 | int Info[4] = {0}; 36 | __cpuidex(Info, 0, 0); 37 | } else { 38 | 39 | // 40 | // In XAPIC mode the ICR is addressed as two 32-bit registers, ICR_LOW 41 | // (FFE0 0300H) and ICR_HIGH (FFE0 0310H). In x2APIC mode, the ICR uses 42 | // MSR 830H. 43 | // 44 | 45 | // 46 | // System software can place the local APIC in the x2APIC mode by setting 47 | // the x2APIC mode enable bit(bit 10) in the IA32_APIC_BASE MSR at MSR 48 | // address 01BH. 49 | // 50 | 51 | // 52 | // Read Apic MSR 53 | // 54 | 55 | UINT64 ICR = __readmsr(MSR_x2APIC_ICR); 56 | 57 | ICR |= ((4 << 8) | (1 << 14) | (3 << 18)); 58 | 59 | // 60 | // Apply the NMI 61 | // 62 | __writemsr(MSR_x2APIC_ICR, ICR); 63 | } 64 | } 65 | 66 | return 0; 67 | } 68 | 69 | // 70 | // If the NMI Exiting control is 0 and an NMI arrives while in VMX-non-root 71 | // mode, the NMI is delivered to the guest via the guest's IDT. If the NMI 72 | // Exiting control is 1, an NMI causes a VM exit.[Intel SDM, volume 3, 73 | // section 24.6.1, table 24 - 5] 74 | // 75 | BOOLEAN LoadNmiCallback() { 76 | 77 | PVOID BufferAddress; 78 | 79 | BufferAddress = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, 0x41424344); 80 | 81 | if (BufferAddress == NULL) { 82 | return FALSE; 83 | } 84 | RtlZeroMemory(BufferAddress, PAGE_SIZE); 85 | 86 | DbgPrint("Enabling nmi callback\n"); 87 | NmiRegPointer = KeRegisterNmiCallback(XxxNmiCallback, BufferAddress); 88 | 89 | if (!NmiRegPointer) { 90 | return FALSE; 91 | } 92 | 93 | KeIpiGenericCall(IpiBroadcastOnCore, NULL); 94 | DbgBreakPoint(); 95 | return TRUE; 96 | } 97 | 98 | VOID UnloadNmiCallback() { 99 | if (NmiRegPointer) 100 | KeDeregisterNmiCallback(NmiRegPointer); 101 | return; 102 | } 103 | -------------------------------------------------------------------------------- /HypervisorBypassWithNMI/HypervisorBypassWithNMI.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29613.14 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HypervisorBypassWithNMI", "HypervisorBypassWithNMI\HypervisorBypassWithNMI.vcxproj", "{0098100B-EE58-43E9-9952-9C7B4E3FE89D}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|ARM = Debug|ARM 11 | Debug|ARM64 = Debug|ARM64 12 | Debug|x64 = Debug|x64 13 | Debug|x86 = Debug|x86 14 | Release|ARM = Release|ARM 15 | Release|ARM64 = Release|ARM64 16 | Release|x64 = Release|x64 17 | Release|x86 = Release|x86 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {0098100B-EE58-43E9-9952-9C7B4E3FE89D}.Debug|ARM.ActiveCfg = Debug|ARM 21 | {0098100B-EE58-43E9-9952-9C7B4E3FE89D}.Debug|ARM.Build.0 = Debug|ARM 22 | {0098100B-EE58-43E9-9952-9C7B4E3FE89D}.Debug|ARM.Deploy.0 = Debug|ARM 23 | {0098100B-EE58-43E9-9952-9C7B4E3FE89D}.Debug|ARM64.ActiveCfg = Debug|ARM64 24 | {0098100B-EE58-43E9-9952-9C7B4E3FE89D}.Debug|ARM64.Build.0 = Debug|ARM64 25 | {0098100B-EE58-43E9-9952-9C7B4E3FE89D}.Debug|ARM64.Deploy.0 = Debug|ARM64 26 | {0098100B-EE58-43E9-9952-9C7B4E3FE89D}.Debug|x64.ActiveCfg = Debug|x64 27 | {0098100B-EE58-43E9-9952-9C7B4E3FE89D}.Debug|x64.Build.0 = Debug|x64 28 | {0098100B-EE58-43E9-9952-9C7B4E3FE89D}.Debug|x64.Deploy.0 = Debug|x64 29 | {0098100B-EE58-43E9-9952-9C7B4E3FE89D}.Debug|x86.ActiveCfg = Debug|Win32 30 | {0098100B-EE58-43E9-9952-9C7B4E3FE89D}.Debug|x86.Build.0 = Debug|Win32 31 | {0098100B-EE58-43E9-9952-9C7B4E3FE89D}.Debug|x86.Deploy.0 = Debug|Win32 32 | {0098100B-EE58-43E9-9952-9C7B4E3FE89D}.Release|ARM.ActiveCfg = Release|ARM 33 | {0098100B-EE58-43E9-9952-9C7B4E3FE89D}.Release|ARM.Build.0 = Release|ARM 34 | {0098100B-EE58-43E9-9952-9C7B4E3FE89D}.Release|ARM.Deploy.0 = Release|ARM 35 | {0098100B-EE58-43E9-9952-9C7B4E3FE89D}.Release|ARM64.ActiveCfg = Release|ARM64 36 | {0098100B-EE58-43E9-9952-9C7B4E3FE89D}.Release|ARM64.Build.0 = Release|ARM64 37 | {0098100B-EE58-43E9-9952-9C7B4E3FE89D}.Release|ARM64.Deploy.0 = Release|ARM64 38 | {0098100B-EE58-43E9-9952-9C7B4E3FE89D}.Release|x64.ActiveCfg = Release|x64 39 | {0098100B-EE58-43E9-9952-9C7B4E3FE89D}.Release|x64.Build.0 = Release|x64 40 | {0098100B-EE58-43E9-9952-9C7B4E3FE89D}.Release|x64.Deploy.0 = Release|x64 41 | {0098100B-EE58-43E9-9952-9C7B4E3FE89D}.Release|x86.ActiveCfg = Release|Win32 42 | {0098100B-EE58-43E9-9952-9C7B4E3FE89D}.Release|x86.Build.0 = Release|Win32 43 | {0098100B-EE58-43E9-9952-9C7B4E3FE89D}.Release|x86.Deploy.0 = Release|Win32 44 | EndGlobalSection 45 | GlobalSection(SolutionProperties) = preSolution 46 | HideSolutionNode = FALSE 47 | EndGlobalSection 48 | GlobalSection(ExtensibilityGlobals) = postSolution 49 | SolutionGuid = {0D41542D-DA4D-4DF4-B658-0E7E45D90CE3} 50 | EndGlobalSection 51 | EndGlobal 52 | -------------------------------------------------------------------------------- /ObRegisterCallbacks/ObRegisterCallbacks.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.28010.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ObRegisterCallbacks", "ObRegisterCallbacks\ObRegisterCallbacks.vcxproj", "{6206DABB-C8F6-4194-8878-B79ABF197E95}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|ARM = Debug|ARM 11 | Debug|ARM64 = Debug|ARM64 12 | Debug|x64 = Debug|x64 13 | Debug|x86 = Debug|x86 14 | Release|ARM = Release|ARM 15 | Release|ARM64 = Release|ARM64 16 | Release|x64 = Release|x64 17 | Release|x86 = Release|x86 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {6206DABB-C8F6-4194-8878-B79ABF197E95}.Debug|ARM.ActiveCfg = Debug|ARM 21 | {6206DABB-C8F6-4194-8878-B79ABF197E95}.Debug|ARM.Build.0 = Debug|ARM 22 | {6206DABB-C8F6-4194-8878-B79ABF197E95}.Debug|ARM.Deploy.0 = Debug|ARM 23 | {6206DABB-C8F6-4194-8878-B79ABF197E95}.Debug|ARM64.ActiveCfg = Debug|ARM64 24 | {6206DABB-C8F6-4194-8878-B79ABF197E95}.Debug|ARM64.Build.0 = Debug|ARM64 25 | {6206DABB-C8F6-4194-8878-B79ABF197E95}.Debug|ARM64.Deploy.0 = Debug|ARM64 26 | {6206DABB-C8F6-4194-8878-B79ABF197E95}.Debug|x64.ActiveCfg = Debug|x64 27 | {6206DABB-C8F6-4194-8878-B79ABF197E95}.Debug|x64.Build.0 = Debug|x64 28 | {6206DABB-C8F6-4194-8878-B79ABF197E95}.Debug|x64.Deploy.0 = Debug|x64 29 | {6206DABB-C8F6-4194-8878-B79ABF197E95}.Debug|x86.ActiveCfg = Debug|Win32 30 | {6206DABB-C8F6-4194-8878-B79ABF197E95}.Debug|x86.Build.0 = Debug|Win32 31 | {6206DABB-C8F6-4194-8878-B79ABF197E95}.Debug|x86.Deploy.0 = Debug|Win32 32 | {6206DABB-C8F6-4194-8878-B79ABF197E95}.Release|ARM.ActiveCfg = Release|ARM 33 | {6206DABB-C8F6-4194-8878-B79ABF197E95}.Release|ARM.Build.0 = Release|ARM 34 | {6206DABB-C8F6-4194-8878-B79ABF197E95}.Release|ARM.Deploy.0 = Release|ARM 35 | {6206DABB-C8F6-4194-8878-B79ABF197E95}.Release|ARM64.ActiveCfg = Release|ARM64 36 | {6206DABB-C8F6-4194-8878-B79ABF197E95}.Release|ARM64.Build.0 = Release|ARM64 37 | {6206DABB-C8F6-4194-8878-B79ABF197E95}.Release|ARM64.Deploy.0 = Release|ARM64 38 | {6206DABB-C8F6-4194-8878-B79ABF197E95}.Release|x64.ActiveCfg = Release|x64 39 | {6206DABB-C8F6-4194-8878-B79ABF197E95}.Release|x64.Build.0 = Release|x64 40 | {6206DABB-C8F6-4194-8878-B79ABF197E95}.Release|x64.Deploy.0 = Release|x64 41 | {6206DABB-C8F6-4194-8878-B79ABF197E95}.Release|x86.ActiveCfg = Release|Win32 42 | {6206DABB-C8F6-4194-8878-B79ABF197E95}.Release|x86.Build.0 = Release|Win32 43 | {6206DABB-C8F6-4194-8878-B79ABF197E95}.Release|x86.Deploy.0 = Release|Win32 44 | EndGlobalSection 45 | GlobalSection(SolutionProperties) = preSolution 46 | HideSolutionNode = FALSE 47 | EndGlobalSection 48 | GlobalSection(ExtensibilityGlobals) = postSolution 49 | SolutionGuid = {6B66CA09-4526-4037-842C-99E6C4DB90F0} 50 | EndGlobalSection 51 | EndGlobal 52 | -------------------------------------------------------------------------------- /TypeInfoCallbacksHooker.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29509.3 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TypeInfoCallbacksHooker", "TypeInfoCallbacksHooker\TypeInfoCallbacksHooker.vcxproj", "{53D0AEA9-E6B9-45D8-914F-470F0534FEE7}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|ARM = Debug|ARM 11 | Debug|ARM64 = Debug|ARM64 12 | Debug|x64 = Debug|x64 13 | Debug|x86 = Debug|x86 14 | Release|ARM = Release|ARM 15 | Release|ARM64 = Release|ARM64 16 | Release|x64 = Release|x64 17 | Release|x86 = Release|x86 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {53D0AEA9-E6B9-45D8-914F-470F0534FEE7}.Debug|ARM.ActiveCfg = Debug|ARM 21 | {53D0AEA9-E6B9-45D8-914F-470F0534FEE7}.Debug|ARM.Build.0 = Debug|ARM 22 | {53D0AEA9-E6B9-45D8-914F-470F0534FEE7}.Debug|ARM.Deploy.0 = Debug|ARM 23 | {53D0AEA9-E6B9-45D8-914F-470F0534FEE7}.Debug|ARM64.ActiveCfg = Debug|ARM64 24 | {53D0AEA9-E6B9-45D8-914F-470F0534FEE7}.Debug|ARM64.Build.0 = Debug|ARM64 25 | {53D0AEA9-E6B9-45D8-914F-470F0534FEE7}.Debug|ARM64.Deploy.0 = Debug|ARM64 26 | {53D0AEA9-E6B9-45D8-914F-470F0534FEE7}.Debug|x64.ActiveCfg = Debug|x64 27 | {53D0AEA9-E6B9-45D8-914F-470F0534FEE7}.Debug|x64.Build.0 = Debug|x64 28 | {53D0AEA9-E6B9-45D8-914F-470F0534FEE7}.Debug|x64.Deploy.0 = Debug|x64 29 | {53D0AEA9-E6B9-45D8-914F-470F0534FEE7}.Debug|x86.ActiveCfg = Debug|Win32 30 | {53D0AEA9-E6B9-45D8-914F-470F0534FEE7}.Debug|x86.Build.0 = Debug|Win32 31 | {53D0AEA9-E6B9-45D8-914F-470F0534FEE7}.Debug|x86.Deploy.0 = Debug|Win32 32 | {53D0AEA9-E6B9-45D8-914F-470F0534FEE7}.Release|ARM.ActiveCfg = Release|ARM 33 | {53D0AEA9-E6B9-45D8-914F-470F0534FEE7}.Release|ARM.Build.0 = Release|ARM 34 | {53D0AEA9-E6B9-45D8-914F-470F0534FEE7}.Release|ARM.Deploy.0 = Release|ARM 35 | {53D0AEA9-E6B9-45D8-914F-470F0534FEE7}.Release|ARM64.ActiveCfg = Release|ARM64 36 | {53D0AEA9-E6B9-45D8-914F-470F0534FEE7}.Release|ARM64.Build.0 = Release|ARM64 37 | {53D0AEA9-E6B9-45D8-914F-470F0534FEE7}.Release|ARM64.Deploy.0 = Release|ARM64 38 | {53D0AEA9-E6B9-45D8-914F-470F0534FEE7}.Release|x64.ActiveCfg = Release|x64 39 | {53D0AEA9-E6B9-45D8-914F-470F0534FEE7}.Release|x64.Build.0 = Release|x64 40 | {53D0AEA9-E6B9-45D8-914F-470F0534FEE7}.Release|x64.Deploy.0 = Release|x64 41 | {53D0AEA9-E6B9-45D8-914F-470F0534FEE7}.Release|x86.ActiveCfg = Release|Win32 42 | {53D0AEA9-E6B9-45D8-914F-470F0534FEE7}.Release|x86.Build.0 = Release|Win32 43 | {53D0AEA9-E6B9-45D8-914F-470F0534FEE7}.Release|x86.Deploy.0 = Release|Win32 44 | EndGlobalSection 45 | GlobalSection(SolutionProperties) = preSolution 46 | HideSolutionNode = FALSE 47 | EndGlobalSection 48 | GlobalSection(ExtensibilityGlobals) = postSolution 49 | SolutionGuid = {6F6C366B-A615-4955-A86E-E15B3BDE8D27} 50 | EndGlobalSection 51 | EndGlobal 52 | -------------------------------------------------------------------------------- /ObRegisterCallbacks/ObRegisterCallbacks/ObRegisterCallbacks.inf: -------------------------------------------------------------------------------- 1 | ; 2 | ; ObRegisterCallbacks.inf 3 | ; 4 | 5 | [Version] 6 | Signature="$WINDOWS NT$" 7 | Class=Sample ; TODO: edit Class 8 | ClassGuid={78A1C341-4539-11d3-B88D-00C04FAD5171} ; TODO: edit ClassGuid 9 | Provider=%ManufacturerName% 10 | CatalogFile=ObRegisterCallbacks.cat 11 | DriverVer= ; TODO: set DriverVer in stampinf property pages 12 | 13 | [DestinationDirs] 14 | DefaultDestDir = 12 15 | ObRegisterCallbacks_Device_CoInstaller_CopyFiles = 11 16 | 17 | ; ================= Class section ===================== 18 | 19 | [ClassInstall32] 20 | Addreg=SampleClassReg 21 | 22 | [SampleClassReg] 23 | HKR,,,0,%ClassName% 24 | HKR,,Icon,,-5 25 | 26 | [SourceDisksNames] 27 | 1 = %DiskName%,,,"" 28 | 29 | [SourceDisksFiles] 30 | ObRegisterCallbacks.sys = 1,, 31 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll=1 ; make sure the number matches with SourceDisksNames 32 | 33 | ;***************************************** 34 | ; Install Section 35 | ;***************************************** 36 | 37 | [Manufacturer] 38 | %ManufacturerName%=Standard,NT$ARCH$ 39 | 40 | [Standard.NT$ARCH$] 41 | %ObRegisterCallbacks.DeviceDesc%=ObRegisterCallbacks_Device, Root\ObRegisterCallbacks ; TODO: edit hw-id 42 | 43 | [ObRegisterCallbacks_Device.NT] 44 | CopyFiles=Drivers_Dir 45 | 46 | [Drivers_Dir] 47 | ObRegisterCallbacks.sys 48 | 49 | ;-------------- Service installation 50 | [ObRegisterCallbacks_Device.NT.Services] 51 | AddService = ObRegisterCallbacks,%SPSVCINST_ASSOCSERVICE%, ObRegisterCallbacks_Service_Inst 52 | 53 | ; -------------- ObRegisterCallbacks driver install sections 54 | [ObRegisterCallbacks_Service_Inst] 55 | DisplayName = %ObRegisterCallbacks.SVCDESC% 56 | ServiceType = 1 ; SERVICE_KERNEL_DRIVER 57 | StartType = 3 ; SERVICE_DEMAND_START 58 | ErrorControl = 1 ; SERVICE_ERROR_NORMAL 59 | ServiceBinary = %12%\ObRegisterCallbacks.sys 60 | 61 | ; 62 | ;--- ObRegisterCallbacks_Device Coinstaller installation ------ 63 | ; 64 | 65 | [ObRegisterCallbacks_Device.NT.CoInstallers] 66 | AddReg=ObRegisterCallbacks_Device_CoInstaller_AddReg 67 | CopyFiles=ObRegisterCallbacks_Device_CoInstaller_CopyFiles 68 | 69 | [ObRegisterCallbacks_Device_CoInstaller_AddReg] 70 | HKR,,CoInstallers32,0x00010000, "WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll,WdfCoInstaller" 71 | 72 | [ObRegisterCallbacks_Device_CoInstaller_CopyFiles] 73 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll 74 | 75 | [ObRegisterCallbacks_Device.NT.Wdf] 76 | KmdfService = ObRegisterCallbacks, ObRegisterCallbacks_wdfsect 77 | [ObRegisterCallbacks_wdfsect] 78 | KmdfLibraryVersion = $KMDFVERSION$ 79 | 80 | [Strings] 81 | SPSVCINST_ASSOCSERVICE= 0x00000002 82 | ManufacturerName="" ;TODO: Replace with your manufacturer name 83 | ClassName="Samples" ; TODO: edit ClassName 84 | DiskName = "ObRegisterCallbacks Installation Disk" 85 | ObRegisterCallbacks.DeviceDesc = "ObRegisterCallbacks Device" 86 | ObRegisterCallbacks.SVCDESC = "ObRegisterCallbacks Service" 87 | -------------------------------------------------------------------------------- /HypervisorBypassWithNMI/HypervisorBypassWithNMI/HypervisorBypassWithNMI.inf: -------------------------------------------------------------------------------- 1 | ; 2 | ; HypervisorBypassWithNMI.inf 3 | ; 4 | 5 | [Version] 6 | Signature="$WINDOWS NT$" 7 | Class=Sample ; TODO: edit Class 8 | ClassGuid={78A1C341-4539-11d3-B88D-00C04FAD5171} ; TODO: edit ClassGuid 9 | Provider=%ManufacturerName% 10 | CatalogFile=HypervisorBypassWithNMI.cat 11 | DriverVer= ; TODO: set DriverVer in stampinf property pages 12 | 13 | [DestinationDirs] 14 | DefaultDestDir = 12 15 | HypervisorBypassWithNMI_Device_CoInstaller_CopyFiles = 11 16 | 17 | ; ================= Class section ===================== 18 | 19 | [ClassInstall32] 20 | Addreg=SampleClassReg 21 | 22 | [SampleClassReg] 23 | HKR,,,0,%ClassName% 24 | HKR,,Icon,,-5 25 | 26 | [SourceDisksNames] 27 | 1 = %DiskName%,,,"" 28 | 29 | [SourceDisksFiles] 30 | HypervisorBypassWithNMI.sys = 1,, 31 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll=1 ; make sure the number matches with SourceDisksNames 32 | 33 | ;***************************************** 34 | ; Install Section 35 | ;***************************************** 36 | 37 | [Manufacturer] 38 | %ManufacturerName%=Standard,NT$ARCH$ 39 | 40 | [Standard.NT$ARCH$] 41 | %HypervisorBypassWithNMI.DeviceDesc%=HypervisorBypassWithNMI_Device, Root\HypervisorBypassWithNMI ; TODO: edit hw-id 42 | 43 | [HypervisorBypassWithNMI_Device.NT] 44 | CopyFiles=Drivers_Dir 45 | 46 | [Drivers_Dir] 47 | HypervisorBypassWithNMI.sys 48 | 49 | ;-------------- Service installation 50 | [HypervisorBypassWithNMI_Device.NT.Services] 51 | AddService = HypervisorBypassWithNMI,%SPSVCINST_ASSOCSERVICE%, HypervisorBypassWithNMI_Service_Inst 52 | 53 | ; -------------- HypervisorBypassWithNMI driver install sections 54 | [HypervisorBypassWithNMI_Service_Inst] 55 | DisplayName = %HypervisorBypassWithNMI.SVCDESC% 56 | ServiceType = 1 ; SERVICE_KERNEL_DRIVER 57 | StartType = 3 ; SERVICE_DEMAND_START 58 | ErrorControl = 1 ; SERVICE_ERROR_NORMAL 59 | ServiceBinary = %12%\HypervisorBypassWithNMI.sys 60 | 61 | ; 62 | ;--- HypervisorBypassWithNMI_Device Coinstaller installation ------ 63 | ; 64 | 65 | [HypervisorBypassWithNMI_Device.NT.CoInstallers] 66 | AddReg=HypervisorBypassWithNMI_Device_CoInstaller_AddReg 67 | CopyFiles=HypervisorBypassWithNMI_Device_CoInstaller_CopyFiles 68 | 69 | [HypervisorBypassWithNMI_Device_CoInstaller_AddReg] 70 | HKR,,CoInstallers32,0x00010000, "WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll,WdfCoInstaller" 71 | 72 | [HypervisorBypassWithNMI_Device_CoInstaller_CopyFiles] 73 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll 74 | 75 | [HypervisorBypassWithNMI_Device.NT.Wdf] 76 | KmdfService = HypervisorBypassWithNMI, HypervisorBypassWithNMI_wdfsect 77 | [HypervisorBypassWithNMI_wdfsect] 78 | KmdfLibraryVersion = $KMDFVERSION$ 79 | 80 | [Strings] 81 | SPSVCINST_ASSOCSERVICE= 0x00000002 82 | ManufacturerName="" ;TODO: Replace with your manufacturer name 83 | ClassName="Samples" ; TODO: edit ClassName 84 | DiskName = "HypervisorBypassWithNMI Installation Disk" 85 | HypervisorBypassWithNMI.DeviceDesc = "HypervisorBypassWithNMI Device" 86 | HypervisorBypassWithNMI.SVCDESC = "HypervisorBypassWithNMI Service" 87 | -------------------------------------------------------------------------------- /TypeInfoCallbacksHooker/TypeInfoCallbacksHooker.inf: -------------------------------------------------------------------------------- 1 | ; 2 | ; TypeInfoCallbacksHooker.inf 3 | ; 4 | 5 | [Version] 6 | Signature="$WINDOWS NT$" 7 | Class=Sample ; TODO: edit Class 8 | ClassGuid={78A1C341-4539-11d3-B88D-00C04FAD5171} ; TODO: edit ClassGuid 9 | Provider=%ManufacturerName% 10 | CatalogFile=TypeInfoCallbacksHooker.cat 11 | DriverVer= ; TODO: set DriverVer in stampinf property pages 12 | 13 | [DestinationDirs] 14 | DefaultDestDir = 12 15 | TypeInfoCallbacksHooker_Device_CoInstaller_CopyFiles = 11 16 | 17 | ; ================= Class section ===================== 18 | 19 | [ClassInstall32] 20 | Addreg=SampleClassReg 21 | 22 | [SampleClassReg] 23 | HKR,,,0,%ClassName% 24 | HKR,,Icon,,-5 25 | 26 | [SourceDisksNames] 27 | 1 = %DiskName%,,,"" 28 | 29 | [SourceDisksFiles] 30 | TypeInfoCallbacksHooker.sys = 1,, 31 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll=1 ; make sure the number matches with SourceDisksNames 32 | 33 | ;***************************************** 34 | ; Install Section 35 | ;***************************************** 36 | 37 | [Manufacturer] 38 | %ManufacturerName%=Standard,NT$ARCH$ 39 | 40 | [Standard.NT$ARCH$] 41 | %TypeInfoCallbacksHooker.DeviceDesc%=TypeInfoCallbacksHooker_Device, Root\TypeInfoCallbacksHooker ; TODO: edit hw-id 42 | 43 | [TypeInfoCallbacksHooker_Device.NT] 44 | CopyFiles=Drivers_Dir 45 | 46 | [Drivers_Dir] 47 | TypeInfoCallbacksHooker.sys 48 | 49 | ;-------------- Service installation 50 | [TypeInfoCallbacksHooker_Device.NT.Services] 51 | AddService = TypeInfoCallbacksHooker,%SPSVCINST_ASSOCSERVICE%, TypeInfoCallbacksHooker_Service_Inst 52 | 53 | ; -------------- TypeInfoCallbacksHooker driver install sections 54 | [TypeInfoCallbacksHooker_Service_Inst] 55 | DisplayName = %TypeInfoCallbacksHooker.SVCDESC% 56 | ServiceType = 1 ; SERVICE_KERNEL_DRIVER 57 | StartType = 3 ; SERVICE_DEMAND_START 58 | ErrorControl = 1 ; SERVICE_ERROR_NORMAL 59 | ServiceBinary = %12%\TypeInfoCallbacksHooker.sys 60 | 61 | ; 62 | ;--- TypeInfoCallbacksHooker_Device Coinstaller installation ------ 63 | ; 64 | 65 | [TypeInfoCallbacksHooker_Device.NT.CoInstallers] 66 | AddReg=TypeInfoCallbacksHooker_Device_CoInstaller_AddReg 67 | CopyFiles=TypeInfoCallbacksHooker_Device_CoInstaller_CopyFiles 68 | 69 | [TypeInfoCallbacksHooker_Device_CoInstaller_AddReg] 70 | HKR,,CoInstallers32,0x00010000, "WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll,WdfCoInstaller" 71 | 72 | [TypeInfoCallbacksHooker_Device_CoInstaller_CopyFiles] 73 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll 74 | 75 | [TypeInfoCallbacksHooker_Device.NT.Wdf] 76 | KmdfService = TypeInfoCallbacksHooker, TypeInfoCallbacksHooker_wdfsect 77 | [TypeInfoCallbacksHooker_wdfsect] 78 | KmdfLibraryVersion = $KMDFVERSION$ 79 | 80 | [Strings] 81 | SPSVCINST_ASSOCSERVICE= 0x00000002 82 | ManufacturerName="" ;TODO: Replace with your manufacturer name 83 | ClassName="Samples" ; TODO: edit ClassName 84 | DiskName = "TypeInfoCallbacksHooker Installation Disk" 85 | TypeInfoCallbacksHooker.DeviceDesc = "TypeInfoCallbacksHooker Device" 86 | TypeInfoCallbacksHooker.SVCDESC = "TypeInfoCallbacksHooker Service" 87 | -------------------------------------------------------------------------------- /ObRegisterCallbacks/ObRegisterCallbacks/Handlers.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include 4 | #include 5 | #include 6 | #include "Driver.h" 7 | 8 | 9 | OB_PREOP_CALLBACK_STATUS 10 | PreOperationCallback( 11 | _In_ PVOID RegistrationContext, 12 | _Inout_ POB_PRE_OPERATION_INFORMATION PreInfo 13 | ) 14 | { 15 | 16 | ACCESS_MASK AccessBitsToClear = 0; 17 | ACCESS_MASK AccessBitsToSet = 0; 18 | ACCESS_MASK InitialDesiredAccess = 0; 19 | ACCESS_MASK OriginalDesiredAccess = 0; 20 | 21 | 22 | PACCESS_MASK DesiredAccess = NULL; 23 | 24 | LPCWSTR ObjectTypeName = NULL; 25 | LPCWSTR OperationName = NULL; 26 | 27 | 28 | ASSERT(PreInfo->CallContext == NULL); 29 | 30 | 31 | if (PreInfo->ObjectType == *PsProcessType) { 32 | 33 | // Process that tries to open/duplicate the current process handle (process itself) 34 | 35 | if (PreInfo->Object == PsGetCurrentProcess()) { 36 | DbgPrintEx( 37 | DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL, 38 | "PreOperationCallback: ignore process open/duplicate from the protected process itself\n"); 39 | } 40 | 41 | ObjectTypeName = L"PsProcessType"; 42 | AccessBitsToClear = 0; 43 | AccessBitsToSet = 0; 44 | } 45 | 46 | 47 | 48 | else if (PreInfo->ObjectType == *PsThreadType) { 49 | HANDLE ProcessIdOfTargetThread = PsGetThreadProcessId((PETHREAD)PreInfo->Object); 50 | 51 | 52 | // Threads which try to open/duplicate from the protected process itself 53 | if (ProcessIdOfTargetThread == PsGetCurrentProcessId()) { 54 | DbgPrintEx( 55 | DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL, 56 | "PreOperationCallback: ignore thread open/duplicate from the protected process itself\n"); 57 | } 58 | 59 | ObjectTypeName = L"PsThreadType"; 60 | AccessBitsToClear = 0; 61 | AccessBitsToSet = 0; 62 | } 63 | else { 64 | DbgPrintEx( 65 | DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, 66 | "PreOperationCallback: unexpected object type\n"); 67 | 68 | // Breakpoint if any ! 69 | DbgBreakPoint(); 70 | goto Exit; 71 | } 72 | 73 | switch (PreInfo->Operation) { 74 | case OB_OPERATION_HANDLE_CREATE: 75 | DesiredAccess = &PreInfo->Parameters->CreateHandleInformation.DesiredAccess; 76 | OriginalDesiredAccess = PreInfo->Parameters->CreateHandleInformation.OriginalDesiredAccess; 77 | 78 | OperationName = L"OB_OPERATION_HANDLE_CREATE"; 79 | break; 80 | 81 | case OB_OPERATION_HANDLE_DUPLICATE: 82 | DesiredAccess = &PreInfo->Parameters->DuplicateHandleInformation.DesiredAccess; 83 | OriginalDesiredAccess = PreInfo->Parameters->DuplicateHandleInformation.OriginalDesiredAccess; 84 | 85 | OperationName = L"OB_OPERATION_HANDLE_DUPLICATE"; 86 | break; 87 | 88 | default: 89 | ASSERT(FALSE); 90 | break; 91 | } 92 | 93 | InitialDesiredAccess = *DesiredAccess; 94 | 95 | // Filter only if request made outside of the kernel 96 | if (PreInfo->KernelHandle != 1) { 97 | *DesiredAccess &= ~AccessBitsToClear; 98 | *DesiredAccess |= AccessBitsToSet; 99 | } 100 | 101 | DbgPrint( 102 | "PreOperationCallback ,\n" 103 | " Client Id: %p:%p\n" 104 | " Object: %p\n" 105 | " Type: %ls\n" 106 | " Operation: %ls (KernelHandle=%d)\n" 107 | " OriginalDesiredAccess: 0x%x\n" 108 | " DesiredAccess (in): 0x%x\n" 109 | " DesiredAccess (out): 0x%x\n" 110 | " =========================================================\n", 111 | PsGetCurrentProcessId(), 112 | PsGetCurrentThreadId(), 113 | PreInfo->Object, 114 | ObjectTypeName, 115 | OperationName, 116 | PreInfo->KernelHandle, 117 | OriginalDesiredAccess, 118 | InitialDesiredAccess, 119 | *DesiredAccess 120 | ); 121 | 122 | Exit: 123 | 124 | return OB_PREOP_SUCCESS; 125 | } 126 | 127 | VOID 128 | PostOperationCallback( 129 | _In_ PVOID RegistrationContext, 130 | _In_ POB_POST_OPERATION_INFORMATION PostInfo 131 | ) 132 | { } 133 | -------------------------------------------------------------------------------- /custom-qemu-for-instrumentation/readme.md: -------------------------------------------------------------------------------- 1 | # Custom QEMU for Instrumentation 2 | 3 | If you need a fast way to instrument user/kernel/hypervisor then you have custom-qemu-for-instrumentation as a fast and light option. As the TCG plugins are much slower than using this method, so I prefer to have a custom QEMU. This project might not work on the future versions of QEMU but in such case, it'll be updated. You can also save r/e flags and general purpose registers based on your needs. 4 | 5 | **This project only works for x86 and AMD64 emulator version of QEMU.** 6 | 7 | ![QEMU Instrumentation](https://github.com/SinaKarvandi/misc/raw/master/Imgs/custom-qemu-1.jpg) 8 | 9 | 10 | 11 | Instructions (and optionally gp registers and r/e flags) will be saved into files. 12 | 13 | ![QEMU Saved Instr. with GP and flags](https://github.com/SinaKarvandi/misc/raw/master/Imgs/custom-qemu-3.PNG) 14 | 15 | ## How to use 16 | Copy the `translate.c` file into your QEMU Source path and replace this file with `/qemu/target/i386/translate.c`. 17 | 18 | Make sure to see the below section about configuration. 19 | 20 | ## Configuratioon 21 | You have to change the path to save the logs of instrumentation in the `translate.c`. 22 | 23 | Take a look at this picture : 24 | ![QEMU Configuration](https://github.com/SinaKarvandi/misc/raw/master/Imgs/custom-qemu-4.png) 25 | 26 | Set the `save_path` to the path you want to save the instrumentation results. (you have to use `%d` in your path as an index to add into each instrumentation log.) 27 | 28 | * You can also use `packet_capacity`, modify this constant will increase/decrease the amount of instructions to be saved. 29 | * If you don't need hex assemblies then undefine `save_assembly_hex_bytes`. 30 | * If you don't need general purpose and r/e flags registers to be saved then undefine `save_gp_registers`. 31 | * If you don't wanna see the debug messages then undefine `my_debug`. 32 | * If you undefine `modify_qemu`, all the modifications to qemu will be ignored. 33 | 34 | ## Build QEMU 35 | The build instructions come from : (https://stackoverflow.com/questions/53084815/compile-qemu-under-windows-10-64-bit-for-windows-10-64-bit) 36 | 37 | Here's a complete step-by-step guide for compiling qemu-system-x86\_64.exe: 38 | 39 | 40 | OS: Microsoft Windows 10 Home 64-bit 41 | 42 | Guide based on: [https://wiki.qemu.org/Hosts/W32#Native\_builds\_with\_MSYS2](https://wiki.qemu.org/Hosts/W32#Native_builds_with_MSYS2) 43 | 44 | * Download and install msys2 to C:\\msys64: [http://repo.msys2.org/distrib/x86\_64/msys2-x86\_64-20180531.exe](http://repo.msys2.org/distrib/x86_64/msys2-x86_64-20180531.exe) 45 | * Start C:\\msys64\\mingw64.exe 46 | * Updates (then close window and restart mingw64.exe): pacman -Syu 47 | * Updates: pacman -Su 48 | * Install basic packets: pacman -S base-devel mingw-w64-x86\_64-toolchain git python 49 | * Install QEMU specific packets: pacman -S mingw-w64-x86\_64-glib2 mingw-w64-x86\_64-gtk3 mingw-w64-x86\_64-SDL2 50 | * Get QEMU sources: 51 | * git clone git://git.qemu-project.org/qemu.git 52 | * cd qemu 53 | * git submodule update --init ui/keycodemapdb 54 | * git submodule update --init capstone 55 | * git submodule update --init dtc 56 | * Insert void \_\_stack\_chk\_fail(void); void \_\_stack\_chk\_fail(void) { } to qemu\\util\\oslib-win32.c e.g. at line 44 57 | * Comment out (#) Capstone (line 508) in qemu\\Makefile (Instead of commenting out capstone line, you can add --disable-capstone to configure arguments in the case if it didn't work. 58 | * Build QEMU: 59 | * ./configure --enable-gtk --enable-sdl --target-list=x86\_64-softmmu --disable-werror --disable-stack-protector 60 | * make 61 | * Run in qemu/x86\_64-softmmu ./qemu-system-x86\_64 -L ./../pc-bios 62 | * Optional (for better performance): Install HAXM according to this guide: [https://www.qemu.org/2017/11/22/haxm-usage-windows/](https://www.qemu.org/2017/11/22/haxm-usage-windows/) and start QEMU with option -accel hax 63 | 64 | ## QEMU Architecture 65 | ![QEMU Architecture](https://github.com/SinaKarvandi/misc/raw/master/Imgs/custom-qemu-2.jpg) 66 | 67 | -------------------------------------------------------------------------------- /Message Tracing/README.md: -------------------------------------------------------------------------------- 1 | # Custom Message Tracing and Buffer Transformation 2 | 3 | This project is extending a Microsoft sample for IRP Pending into a Message Tracing and Buffer Sharing from Kernel mode -> Usermode. 4 | 5 | ![](https://github.com/SinaKarvandi/Misc/raw/master/Imgs/Tracer.gif) 6 | 7 | ## Why you should use it instead of WPP Tracing? 8 | It's because WPP Tracing needs extra applications to translate the buffer but instead this messaging mechanism is really simple, you don't need to deal with .etl and .tmf files to read the messages of WPP Tracing. 9 | 10 | ## Design 11 | I used DPC and IRP Based Pending mechanisms in Windows to handle messages, you can send both a raw buffer and a message (`sprintf` like format to the usermode.). 12 | Each core has it's separate pool for THE message, you can insert message to another core's pool. 13 | 14 | A core buffer is like this , it's divided into `MaximumPacketsCapacity` chucks, 15 | each chunk has `PacketChunkSize + sizeof(BUFFER_HEADER)` size. 16 | ``` 17 | 18 | _________________________ 19 | | BUFFER_HEADER | 20 | |_________________________| 21 | | | 22 | | BODY | 23 | | (Buffer) | 24 | | size = PacketChunkSize | 25 | | | 26 | |_________________________| 27 | | BUFFER_HEADER | 28 | |_________________________| 29 | | | 30 | | BODY | 31 | | (Buffer) | 32 | | size = PacketChunkSize | 33 | | | 34 | |_________________________| 35 | | | 36 | | | 37 | | | 38 | | | 39 | | . | 40 | | . | 41 | | . | 42 | | | 43 | | | 44 | | | 45 | | | 46 | |_________________________| 47 | | BUFFER_HEADER | 48 | |_________________________| 49 | | | 50 | | BODY | 51 | | (Buffer) | 52 | | size = PacketChunkSize | 53 | | | 54 | |_________________________| 55 | 56 | ``` 57 | 58 | ## Configuration 59 | You can change the following lines in order to change the buffer size and change the maximum capacity for each pool. 60 | ``` 61 | // Default buffer size 62 | #define MaximumPacketsCapacity 1000 // number of packets 63 | #define PacketChunkSize 512 64 | #define UsermodeBufferSize sizeof(UINT32) + PacketChunkSize + 1 /* Becausee of Opeation code at the start of the buffer + 1 for null-termminating */ 65 | #define BufferSize MaximumPacketsCapacity * (PacketChunkSize + sizeof(BUFFER_HEADER)) 66 | ``` 67 | ## How to use? 68 | 69 | In order to use this event tracing, you can use the following function in you code to send a buffer to the pool. 70 | ``` 71 | SendBuffer(UINT32 OperationCode, PVOID Buffer, UINT32 BufferLength, UINT32 CoreIndex); 72 | ``` 73 | The above method gets the `OperationCode`, this code will be sent to the usermode code to describe the intention of this message, send the buffer and also the length of the buffer + an index to specify the core which you want to send your message into its pool. 74 | 75 | ``` 76 | BOOLEAN ReadBuffer(UINT32 CoreIndex, PVOID BufferToSaveMessage, UINT32* ReturnedLength); 77 | ``` 78 | `ReadBuffer` reads the buffer from a special core pool. 79 | ``` 80 | BOOLEAN CheckForNewMessage(UINT32 CoreIndex); 81 | ``` 82 | Checks whether a special core pool has a new message or not. 83 | ``` 84 | BOOLEAN SendMessageToQueue(UINT32 OperationCode, UINT32 CoreIndex, const char* Fmt, ...) 85 | ``` 86 | The above functions are used to send `Printf` and `Sprintf` like buffers to the usermode. e.g. as a message tracing for debugging purposes. 87 | 88 | In order to send a special message (look at the .gif above), you can change the following line or put this function everywhere you need. 89 | ``` 90 | // change the following line 91 | SendMessageToQueue(0x85, 0, "Sina's answer is %s [%d] and %s - + 0x%x tttuuii", "Hello", counter, "Second Hello", 0x1234); 92 | // end changes 93 | ``` 94 | ## Run the sample 95 | 96 | To test this driver, copy the test application, event.exe, and the driver to the same directory, and run the application. The application will automatically load the driver, if it's not already loaded, and interact with the driver. When you exit the app, the driver will be stopped, unloaded, and removed. 97 | 98 | To run the test application, enter the following command in the command window: 99 | 100 | `C:\>event.exe <0|1>` 101 | 102 | *Only 0 is for transferring buffer from kernel to user, if you use 1 then it's just triggering an event and not passing message buffers.* 103 | The first command-line parameter, `<0|1>`, specify 0 for IRP-based notification and 1 for event-based notification. 104 | 105 | License 106 | ---- 107 | 108 | MIT 109 | 110 | 111 | [//]: # (These are reference links used in the body of this note and get stripped out when the markdown processor does its job. There is no need to format nicely because it shouldn't be seen. Thanks SO - http://stackoverflow.com/questions/4823468/store-comments-in-markdown-syntax) 112 | 113 | -------------------------------------------------------------------------------- /HypervisorBypassWithNMI/HypervisorBypassWithNMI/HypervisorBypass.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // 4 | // MSRs 5 | // 6 | #define MSR_x2APIC_ICR 0x830 7 | 8 | 9 | typedef enum _VMCS_FIELDS { 10 | VIRTUAL_PROCESSOR_ID = 0x00000000, 11 | POSTED_INTR_NOTIFICATION_VECTOR = 0x00000002, 12 | EPTP_INDEX = 0x00000004, 13 | #define GUEST_SEG_SELECTOR(sel) (GUEST_ES_SELECTOR + (sel)*2) /* ES ... GS */ 14 | GUEST_ES_SELECTOR = 0x00000800, 15 | GUEST_CS_SELECTOR = 0x00000802, 16 | GUEST_SS_SELECTOR = 0x00000804, 17 | GUEST_DS_SELECTOR = 0x00000806, 18 | GUEST_FS_SELECTOR = 0x00000808, 19 | GUEST_GS_SELECTOR = 0x0000080a, 20 | GUEST_LDTR_SELECTOR = 0x0000080c, 21 | GUEST_TR_SELECTOR = 0x0000080e, 22 | GUEST_INTR_STATUS = 0x00000810, 23 | GUEST_PML_INDEX = 0x00000812, 24 | HOST_ES_SELECTOR = 0x00000c00, 25 | HOST_CS_SELECTOR = 0x00000c02, 26 | HOST_SS_SELECTOR = 0x00000c04, 27 | HOST_DS_SELECTOR = 0x00000c06, 28 | HOST_FS_SELECTOR = 0x00000c08, 29 | HOST_GS_SELECTOR = 0x00000c0a, 30 | HOST_TR_SELECTOR = 0x00000c0c, 31 | IO_BITMAP_A = 0x00002000, 32 | IO_BITMAP_B = 0x00002002, 33 | MSR_BITMAP = 0x00002004, 34 | VM_EXIT_MSR_STORE_ADDR = 0x00002006, 35 | VM_EXIT_MSR_LOAD_ADDR = 0x00002008, 36 | VM_ENTRY_MSR_LOAD_ADDR = 0x0000200a, 37 | PML_ADDRESS = 0x0000200e, 38 | TSC_OFFSET = 0x00002010, 39 | VIRTUAL_APIC_PAGE_ADDR = 0x00002012, 40 | APIC_ACCESS_ADDR = 0x00002014, 41 | PI_DESC_ADDR = 0x00002016, 42 | VM_FUNCTION_CONTROL = 0x00002018, 43 | EPT_POINTER = 0x0000201a, 44 | EOI_EXIT_BITMAP0 = 0x0000201c, 45 | #define EOI_EXIT_BITMAP(n) (EOI_EXIT_BITMAP0 + (n)*2) /* n = 0...3 */ 46 | EPTP_LIST_ADDR = 0x00002024, 47 | VMREAD_BITMAP = 0x00002026, 48 | VMWRITE_BITMAP = 0x00002028, 49 | VIRT_EXCEPTION_INFO = 0x0000202a, 50 | XSS_EXIT_BITMAP = 0x0000202c, 51 | TSC_MULTIPLIER = 0x00002032, 52 | GUEST_PHYSICAL_ADDRESS = 0x00002400, 53 | VMCS_LINK_POINTER = 0x00002800, 54 | GUEST_IA32_DEBUGCTL = 0x00002802, 55 | GUEST_IA32_DEBUGCTL_HIGH = 0x00002803, 56 | GUEST_PAT = 0x00002804, 57 | GUEST_EFER = 0x00002806, 58 | GUEST_PERF_GLOBAL_CTRL = 0x00002808, 59 | GUEST_PDPTE0 = 0x0000280a, 60 | #define GUEST_PDPTE(n) (GUEST_PDPTE0 + (n)*2) /* n = 0...3 */ 61 | GUEST_BNDCFGS = 0x00002812, 62 | HOST_PAT = 0x00002c00, 63 | HOST_EFER = 0x00002c02, 64 | HOST_PERF_GLOBAL_CTRL = 0x00002c04, 65 | PIN_BASED_VM_EXEC_CONTROL = 0x00004000, 66 | CPU_BASED_VM_EXEC_CONTROL = 0x00004002, 67 | EXCEPTION_BITMAP = 0x00004004, 68 | PAGE_FAULT_ERROR_CODE_MASK = 0x00004006, 69 | PAGE_FAULT_ERROR_CODE_MATCH = 0x00004008, 70 | CR3_TARGET_COUNT = 0x0000400a, 71 | VM_EXIT_CONTROLS = 0x0000400c, 72 | VM_EXIT_MSR_STORE_COUNT = 0x0000400e, 73 | VM_EXIT_MSR_LOAD_COUNT = 0x00004010, 74 | VM_ENTRY_CONTROLS = 0x00004012, 75 | VM_ENTRY_MSR_LOAD_COUNT = 0x00004014, 76 | VM_ENTRY_INTR_INFO = 0x00004016, 77 | VM_ENTRY_EXCEPTION_ERROR_CODE = 0x00004018, 78 | VM_ENTRY_INSTRUCTION_LEN = 0x0000401a, 79 | TPR_THRESHOLD = 0x0000401c, 80 | SECONDARY_VM_EXEC_CONTROL = 0x0000401e, 81 | PLE_GAP = 0x00004020, 82 | PLE_WINDOW = 0x00004022, 83 | VM_INSTRUCTION_ERROR = 0x00004400, 84 | VM_EXIT_REASON = 0x00004402, 85 | VM_EXIT_INTR_INFO = 0x00004404, 86 | VM_EXIT_INTR_ERROR_CODE = 0x00004406, 87 | IDT_VECTORING_INFO = 0x00004408, 88 | IDT_VECTORING_ERROR_CODE = 0x0000440a, 89 | VM_EXIT_INSTRUCTION_LEN = 0x0000440c, 90 | VMX_INSTRUCTION_INFO = 0x0000440e, 91 | #define GUEST_SEG_LIMIT(sel) (GUEST_ES_LIMIT + (sel)*2) /* ES ... GS */ 92 | GUEST_ES_LIMIT = 0x00004800, 93 | GUEST_CS_LIMIT = 0x00004802, 94 | GUEST_SS_LIMIT = 0x00004804, 95 | GUEST_DS_LIMIT = 0x00004806, 96 | GUEST_FS_LIMIT = 0x00004808, 97 | GUEST_GS_LIMIT = 0x0000480a, 98 | GUEST_LDTR_LIMIT = 0x0000480c, 99 | GUEST_TR_LIMIT = 0x0000480e, 100 | GUEST_GDTR_LIMIT = 0x00004810, 101 | GUEST_IDTR_LIMIT = 0x00004812, 102 | #define GUEST_SEG_AR_BYTES(sel) (GUEST_ES_AR_BYTES + (sel)*2) /* ES ... GS */ 103 | GUEST_ES_AR_BYTES = 0x00004814, 104 | GUEST_CS_AR_BYTES = 0x00004816, 105 | GUEST_SS_AR_BYTES = 0x00004818, 106 | GUEST_DS_AR_BYTES = 0x0000481a, 107 | GUEST_FS_AR_BYTES = 0x0000481c, 108 | GUEST_GS_AR_BYTES = 0x0000481e, 109 | GUEST_LDTR_AR_BYTES = 0x00004820, 110 | GUEST_TR_AR_BYTES = 0x00004822, 111 | GUEST_INTERRUPTIBILITY_INFO = 0x00004824, 112 | GUEST_ACTIVITY_STATE = 0x00004826, 113 | GUEST_SMBASE = 0x00004828, 114 | GUEST_SYSENTER_CS = 0x0000482a, 115 | GUEST_PREEMPTION_TIMER = 0x0000482e, 116 | HOST_SYSENTER_CS = 0x00004c00, 117 | CR0_GUEST_HOST_MASK = 0x00006000, 118 | CR4_GUEST_HOST_MASK = 0x00006002, 119 | CR0_READ_SHADOW = 0x00006004, 120 | CR4_READ_SHADOW = 0x00006006, 121 | CR3_TARGET_VALUE0 = 0x00006008, 122 | CR3_TARGET_VALUE1 = 0x0000600a, 123 | CR3_TARGET_VALUE2 = 0x0000600c, 124 | CR3_TARGET_VALUE3 = 0x0000600e, 125 | EXIT_QUALIFICATION = 0x00006400, 126 | GUEST_LINEAR_ADDRESS = 0x0000640a, 127 | GUEST_CR0 = 0x00006800, 128 | GUEST_CR3 = 0x00006802, 129 | GUEST_CR4 = 0x00006804, 130 | #define GUEST_SEG_BASE(sel) (GUEST_ES_BASE + (sel)*2) /* ES ... GS */ 131 | GUEST_ES_BASE = 0x00006806, 132 | GUEST_CS_BASE = 0x00006808, 133 | GUEST_SS_BASE = 0x0000680a, 134 | GUEST_DS_BASE = 0x0000680c, 135 | GUEST_FS_BASE = 0x0000680e, 136 | GUEST_GS_BASE = 0x00006810, 137 | GUEST_LDTR_BASE = 0x00006812, 138 | GUEST_TR_BASE = 0x00006814, 139 | GUEST_GDTR_BASE = 0x00006816, 140 | GUEST_IDTR_BASE = 0x00006818, 141 | GUEST_DR7 = 0x0000681a, 142 | GUEST_RSP = 0x0000681c, 143 | GUEST_RIP = 0x0000681e, 144 | GUEST_RFLAGS = 0x00006820, 145 | GUEST_PENDING_DBG_EXCEPTIONS = 0x00006822, 146 | GUEST_SYSENTER_ESP = 0x00006824, 147 | GUEST_SYSENTER_EIP = 0x00006826, 148 | HOST_CR0 = 0x00006c00, 149 | HOST_CR3 = 0x00006c02, 150 | HOST_CR4 = 0x00006c04, 151 | HOST_FS_BASE = 0x00006c06, 152 | HOST_GS_BASE = 0x00006c08, 153 | HOST_TR_BASE = 0x00006c0a, 154 | HOST_GDTR_BASE = 0x00006c0c, 155 | HOST_IDTR_BASE = 0x00006c0e, 156 | HOST_SYSENTER_ESP = 0x00006c10, 157 | HOST_SYSENTER_EIP = 0x00006c12, 158 | HOST_RSP = 0x00006c14, 159 | HOST_RIP = 0x00006c16, 160 | } VMCS_FIELDS; 161 | -------------------------------------------------------------------------------- /HypervisorBypassWithNMI/HypervisorBypassWithNMI/Queue.c: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Module Name: 4 | 5 | queue.c 6 | 7 | Abstract: 8 | 9 | This file contains the queue entry points and callbacks. 10 | 11 | Environment: 12 | 13 | Kernel-mode Driver Framework 14 | 15 | --*/ 16 | 17 | #include "driver.h" 18 | #include "queue.tmh" 19 | 20 | #ifdef ALLOC_PRAGMA 21 | #pragma alloc_text (PAGE, HypervisorBypassWithNMIQueueInitialize) 22 | #endif 23 | 24 | NTSTATUS 25 | HypervisorBypassWithNMIQueueInitialize( 26 | _In_ WDFDEVICE Device 27 | ) 28 | /*++ 29 | 30 | Routine Description: 31 | 32 | The I/O dispatch callbacks for the frameworks device object 33 | are configured in this function. 34 | 35 | A single default I/O Queue is configured for parallel request 36 | processing, and a driver context memory allocation is created 37 | to hold our structure QUEUE_CONTEXT. 38 | 39 | Arguments: 40 | 41 | Device - Handle to a framework device object. 42 | 43 | Return Value: 44 | 45 | VOID 46 | 47 | --*/ 48 | { 49 | WDFQUEUE queue; 50 | NTSTATUS status; 51 | WDF_IO_QUEUE_CONFIG queueConfig; 52 | 53 | PAGED_CODE(); 54 | 55 | // 56 | // Configure a default queue so that requests that are not 57 | // configure-fowarded using WdfDeviceConfigureRequestDispatching to goto 58 | // other queues get dispatched here. 59 | // 60 | WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE( 61 | &queueConfig, 62 | WdfIoQueueDispatchParallel 63 | ); 64 | 65 | queueConfig.EvtIoDeviceControl = HypervisorBypassWithNMIEvtIoDeviceControl; 66 | queueConfig.EvtIoStop = HypervisorBypassWithNMIEvtIoStop; 67 | 68 | status = WdfIoQueueCreate( 69 | Device, 70 | &queueConfig, 71 | WDF_NO_OBJECT_ATTRIBUTES, 72 | &queue 73 | ); 74 | 75 | if(!NT_SUCCESS(status)) { 76 | TraceEvents(TRACE_LEVEL_ERROR, TRACE_QUEUE, "WdfIoQueueCreate failed %!STATUS!", status); 77 | return status; 78 | } 79 | 80 | return status; 81 | } 82 | 83 | VOID 84 | HypervisorBypassWithNMIEvtIoDeviceControl( 85 | _In_ WDFQUEUE Queue, 86 | _In_ WDFREQUEST Request, 87 | _In_ size_t OutputBufferLength, 88 | _In_ size_t InputBufferLength, 89 | _In_ ULONG IoControlCode 90 | ) 91 | /*++ 92 | 93 | Routine Description: 94 | 95 | This event is invoked when the framework receives IRP_MJ_DEVICE_CONTROL request. 96 | 97 | Arguments: 98 | 99 | Queue - Handle to the framework queue object that is associated with the 100 | I/O request. 101 | 102 | Request - Handle to a framework request object. 103 | 104 | OutputBufferLength - Size of the output buffer in bytes 105 | 106 | InputBufferLength - Size of the input buffer in bytes 107 | 108 | IoControlCode - I/O control code. 109 | 110 | Return Value: 111 | 112 | VOID 113 | 114 | --*/ 115 | { 116 | TraceEvents(TRACE_LEVEL_INFORMATION, 117 | TRACE_QUEUE, 118 | "%!FUNC! Queue 0x%p, Request 0x%p OutputBufferLength %d InputBufferLength %d IoControlCode %d", 119 | Queue, Request, (int) OutputBufferLength, (int) InputBufferLength, IoControlCode); 120 | 121 | WdfRequestComplete(Request, STATUS_SUCCESS); 122 | 123 | return; 124 | } 125 | 126 | VOID 127 | HypervisorBypassWithNMIEvtIoStop( 128 | _In_ WDFQUEUE Queue, 129 | _In_ WDFREQUEST Request, 130 | _In_ ULONG ActionFlags 131 | ) 132 | /*++ 133 | 134 | Routine Description: 135 | 136 | This event is invoked for a power-managed queue before the device leaves the working state (D0). 137 | 138 | Arguments: 139 | 140 | Queue - Handle to the framework queue object that is associated with the 141 | I/O request. 142 | 143 | Request - Handle to a framework request object. 144 | 145 | ActionFlags - A bitwise OR of one or more WDF_REQUEST_STOP_ACTION_FLAGS-typed flags 146 | that identify the reason that the callback function is being called 147 | and whether the request is cancelable. 148 | 149 | Return Value: 150 | 151 | VOID 152 | 153 | --*/ 154 | { 155 | TraceEvents(TRACE_LEVEL_INFORMATION, 156 | TRACE_QUEUE, 157 | "%!FUNC! Queue 0x%p, Request 0x%p ActionFlags %d", 158 | Queue, Request, ActionFlags); 159 | 160 | // 161 | // In most cases, the EvtIoStop callback function completes, cancels, or postpones 162 | // further processing of the I/O request. 163 | // 164 | // Typically, the driver uses the following rules: 165 | // 166 | // - If the driver owns the I/O request, it calls WdfRequestUnmarkCancelable 167 | // (if the request is cancelable) and either calls WdfRequestStopAcknowledge 168 | // with a Requeue value of TRUE, or it calls WdfRequestComplete with a 169 | // completion status value of STATUS_SUCCESS or STATUS_CANCELLED. 170 | // 171 | // Before it can call these methods safely, the driver must make sure that 172 | // its implementation of EvtIoStop has exclusive access to the request. 173 | // 174 | // In order to do that, the driver must synchronize access to the request 175 | // to prevent other threads from manipulating the request concurrently. 176 | // The synchronization method you choose will depend on your driver's design. 177 | // 178 | // For example, if the request is held in a shared context, the EvtIoStop callback 179 | // might acquire an internal driver lock, take the request from the shared context, 180 | // and then release the lock. At this point, the EvtIoStop callback owns the request 181 | // and can safely complete or requeue the request. 182 | // 183 | // - If the driver has forwarded the I/O request to an I/O target, it either calls 184 | // WdfRequestCancelSentRequest to attempt to cancel the request, or it postpones 185 | // further processing of the request and calls WdfRequestStopAcknowledge with 186 | // a Requeue value of FALSE. 187 | // 188 | // A driver might choose to take no action in EvtIoStop for requests that are 189 | // guaranteed to complete in a small amount of time. 190 | // 191 | // In this case, the framework waits until the specified request is complete 192 | // before moving the device (or system) to a lower power state or removing the device. 193 | // Potentially, this inaction can prevent a system from entering its hibernation state 194 | // or another low system power state. In extreme cases, it can cause the system 195 | // to crash with bugcheck code 9F. 196 | // 197 | 198 | return; 199 | } 200 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Ww][Ii][Nn]32/ 27 | [Aa][Rr][Mm]/ 28 | [Aa][Rr][Mm]64/ 29 | bld/ 30 | [Bb]in/ 31 | [Oo]bj/ 32 | [Ll]og/ 33 | [Ll]ogs/ 34 | 35 | # Visual Studio 2015/2017 cache/options directory 36 | .vs/ 37 | # Uncomment if you have tasks that create the project's static files in wwwroot 38 | #wwwroot/ 39 | 40 | # Visual Studio 2017 auto generated files 41 | Generated\ Files/ 42 | 43 | # MSTest test Results 44 | [Tt]est[Rr]esult*/ 45 | [Bb]uild[Ll]og.* 46 | 47 | # NUnit 48 | *.VisualState.xml 49 | TestResult.xml 50 | nunit-*.xml 51 | 52 | # Build Results of an ATL Project 53 | [Dd]ebugPS/ 54 | [Rr]eleasePS/ 55 | dlldata.c 56 | 57 | # Benchmark Results 58 | BenchmarkDotNet.Artifacts/ 59 | 60 | # .NET Core 61 | project.lock.json 62 | project.fragment.lock.json 63 | artifacts/ 64 | 65 | # ASP.NET Scaffolding 66 | ScaffoldingReadMe.txt 67 | 68 | # StyleCop 69 | StyleCopReport.xml 70 | 71 | # Files built by Visual Studio 72 | *_i.c 73 | *_p.c 74 | *_h.h 75 | *.ilk 76 | *.meta 77 | *.obj 78 | *.iobj 79 | *.pch 80 | *.pdb 81 | *.ipdb 82 | *.pgc 83 | *.pgd 84 | *.rsp 85 | *.sbr 86 | *.tlb 87 | *.tli 88 | *.tlh 89 | *.tmp 90 | *.tmp_proj 91 | *_wpftmp.csproj 92 | *.log 93 | *.vspscc 94 | *.vssscc 95 | .builds 96 | *.pidb 97 | *.svclog 98 | *.scc 99 | 100 | # Chutzpah Test files 101 | _Chutzpah* 102 | 103 | # Visual C++ cache files 104 | ipch/ 105 | *.aps 106 | *.ncb 107 | *.opendb 108 | *.opensdf 109 | *.sdf 110 | *.cachefile 111 | *.VC.db 112 | *.VC.VC.opendb 113 | 114 | # Visual Studio profiler 115 | *.psess 116 | *.vsp 117 | *.vspx 118 | *.sap 119 | 120 | # Visual Studio Trace Files 121 | *.e2e 122 | 123 | # TFS 2012 Local Workspace 124 | $tf/ 125 | 126 | # Guidance Automation Toolkit 127 | *.gpState 128 | 129 | # ReSharper is a .NET coding add-in 130 | _ReSharper*/ 131 | *.[Rr]e[Ss]harper 132 | *.DotSettings.user 133 | 134 | # TeamCity is a build add-in 135 | _TeamCity* 136 | 137 | # DotCover is a Code Coverage Tool 138 | *.dotCover 139 | 140 | # AxoCover is a Code Coverage Tool 141 | .axoCover/* 142 | !.axoCover/settings.json 143 | 144 | # Coverlet is a free, cross platform Code Coverage Tool 145 | coverage*[.json, .xml, .info] 146 | 147 | # Visual Studio code coverage results 148 | *.coverage 149 | *.coveragexml 150 | 151 | # NCrunch 152 | _NCrunch_* 153 | .*crunch*.local.xml 154 | nCrunchTemp_* 155 | 156 | # MightyMoose 157 | *.mm.* 158 | AutoTest.Net/ 159 | 160 | # Web workbench (sass) 161 | .sass-cache/ 162 | 163 | # Installshield output folder 164 | [Ee]xpress/ 165 | 166 | # DocProject is a documentation generator add-in 167 | DocProject/buildhelp/ 168 | DocProject/Help/*.HxT 169 | DocProject/Help/*.HxC 170 | DocProject/Help/*.hhc 171 | DocProject/Help/*.hhk 172 | DocProject/Help/*.hhp 173 | DocProject/Help/Html2 174 | DocProject/Help/html 175 | 176 | # Click-Once directory 177 | publish/ 178 | 179 | # Publish Web Output 180 | *.[Pp]ublish.xml 181 | *.azurePubxml 182 | # Note: Comment the next line if you want to checkin your web deploy settings, 183 | # but database connection strings (with potential passwords) will be unencrypted 184 | *.pubxml 185 | *.publishproj 186 | 187 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 188 | # checkin your Azure Web App publish settings, but sensitive information contained 189 | # in these scripts will be unencrypted 190 | PublishScripts/ 191 | 192 | # NuGet Packages 193 | *.nupkg 194 | # NuGet Symbol Packages 195 | *.snupkg 196 | # The packages folder can be ignored because of Package Restore 197 | **/[Pp]ackages/* 198 | # except build/, which is used as an MSBuild target. 199 | !**/[Pp]ackages/build/ 200 | # Uncomment if necessary however generally it will be regenerated when needed 201 | #!**/[Pp]ackages/repositories.config 202 | # NuGet v3's project.json files produces more ignorable files 203 | *.nuget.props 204 | *.nuget.targets 205 | 206 | # Microsoft Azure Build Output 207 | csx/ 208 | *.build.csdef 209 | 210 | # Microsoft Azure Emulator 211 | ecf/ 212 | rcf/ 213 | 214 | # Windows Store app package directories and files 215 | AppPackages/ 216 | BundleArtifacts/ 217 | Package.StoreAssociation.xml 218 | _pkginfo.txt 219 | *.appx 220 | *.appxbundle 221 | *.appxupload 222 | 223 | # Visual Studio cache files 224 | # files ending in .cache can be ignored 225 | *.[Cc]ache 226 | # but keep track of directories ending in .cache 227 | !?*.[Cc]ache/ 228 | 229 | # Others 230 | ClientBin/ 231 | ~$* 232 | *~ 233 | *.dbmdl 234 | *.dbproj.schemaview 235 | *.jfm 236 | *.pfx 237 | *.publishsettings 238 | orleans.codegen.cs 239 | 240 | # Including strong name files can present a security risk 241 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 242 | #*.snk 243 | 244 | # Since there are multiple workflows, uncomment next line to ignore bower_components 245 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 246 | #bower_components/ 247 | 248 | # RIA/Silverlight projects 249 | Generated_Code/ 250 | 251 | # Backup & report files from converting an old project file 252 | # to a newer Visual Studio version. Backup files are not needed, 253 | # because we have git ;-) 254 | _UpgradeReport_Files/ 255 | Backup*/ 256 | UpgradeLog*.XML 257 | UpgradeLog*.htm 258 | ServiceFabricBackup/ 259 | *.rptproj.bak 260 | 261 | # SQL Server files 262 | *.mdf 263 | *.ldf 264 | *.ndf 265 | 266 | # Business Intelligence projects 267 | *.rdl.data 268 | *.bim.layout 269 | *.bim_*.settings 270 | *.rptproj.rsuser 271 | *- [Bb]ackup.rdl 272 | *- [Bb]ackup ([0-9]).rdl 273 | *- [Bb]ackup ([0-9][0-9]).rdl 274 | 275 | # Microsoft Fakes 276 | FakesAssemblies/ 277 | 278 | # GhostDoc plugin setting file 279 | *.GhostDoc.xml 280 | 281 | # Node.js Tools for Visual Studio 282 | .ntvs_analysis.dat 283 | node_modules/ 284 | 285 | # Visual Studio 6 build log 286 | *.plg 287 | 288 | # Visual Studio 6 workspace options file 289 | *.opt 290 | 291 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 292 | *.vbw 293 | 294 | # Visual Studio LightSwitch build output 295 | **/*.HTMLClient/GeneratedArtifacts 296 | **/*.DesktopClient/GeneratedArtifacts 297 | **/*.DesktopClient/ModelManifest.xml 298 | **/*.Server/GeneratedArtifacts 299 | **/*.Server/ModelManifest.xml 300 | _Pvt_Extensions 301 | 302 | # Paket dependency manager 303 | .paket/paket.exe 304 | paket-files/ 305 | 306 | # FAKE - F# Make 307 | .fake/ 308 | 309 | # CodeRush personal settings 310 | .cr/personal 311 | 312 | # Python Tools for Visual Studio (PTVS) 313 | __pycache__/ 314 | *.pyc 315 | 316 | # Cake - Uncomment if you are using it 317 | # tools/** 318 | # !tools/packages.config 319 | 320 | # Tabs Studio 321 | *.tss 322 | 323 | # Telerik's JustMock configuration file 324 | *.jmconfig 325 | 326 | # BizTalk build output 327 | *.btp.cs 328 | *.btm.cs 329 | *.odx.cs 330 | *.xsd.cs 331 | 332 | # OpenCover UI analysis results 333 | OpenCover/ 334 | 335 | # Azure Stream Analytics local run output 336 | ASALocalRun/ 337 | 338 | # MSBuild Binary and Structured Log 339 | *.binlog 340 | 341 | # NVidia Nsight GPU debugger configuration file 342 | *.nvuser 343 | 344 | # MFractors (Xamarin productivity tool) working folder 345 | .mfractor/ 346 | 347 | # Local History for Visual Studio 348 | .localhistory/ 349 | 350 | # BeatPulse healthcheck temp database 351 | healthchecksdb 352 | 353 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 354 | MigrationBackup/ 355 | 356 | # Ionide (cross platform F# VS Code tools) working folder 357 | .ionide/ 358 | 359 | # Fody - auto-generated XML schema 360 | FodyWeavers.xsd 361 | -------------------------------------------------------------------------------- /Message Tracing/wdm/event.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {21F8EA86-F950-4D2D-B256-721B3151157A} 23 | $(MSBuildProjectName) 24 | Debug 25 | Win32 26 | {CB8CC3B6-AB82-4CC0-A34E-F410EECB74B1} 27 | 28 | 29 | 30 | Windows10 31 | False 32 | Desktop 33 | WDM 34 | WindowsKernelModeDriver10.0 35 | Driver 36 | 37 | 38 | Windows10 39 | True 40 | Desktop 41 | WDM 42 | WindowsKernelModeDriver10.0 43 | Driver 44 | false 45 | 46 | 47 | Windows10 48 | False 49 | Desktop 50 | WDM 51 | WindowsKernelModeDriver10.0 52 | Driver 53 | 54 | 55 | Windows10 56 | True 57 | Desktop 58 | WDM 59 | WindowsKernelModeDriver10.0 60 | Driver 61 | 62 | 63 | 64 | $(IntDir) 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | event 81 | 82 | 83 | event 84 | 85 | 86 | event 87 | 88 | 89 | event 90 | 91 | 92 | 93 | %(PreprocessorDefinitions);POOL_NX_OPTIN=1 94 | true 95 | Level4 96 | 97 | 98 | 99 | 100 | %(PreprocessorDefinitions);POOL_NX_OPTIN=1 101 | false 102 | Level4 103 | 104 | 105 | 106 | 107 | %(PreprocessorDefinitions);POOL_NX_OPTIN=1 108 | true 109 | Level4 110 | 111 | 112 | 113 | 114 | %(PreprocessorDefinitions);POOL_NX_OPTIN=1 115 | true 116 | Level4 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | %(PreprocessorDefinitions);POOL_NX_OPTIN=1 126 | 127 | 128 | 129 | 130 | 131 | 132 | %(PreprocessorDefinitions);POOL_NX_OPTIN=1 133 | 134 | 135 | 136 | 137 | 138 | 139 | %(PreprocessorDefinitions);POOL_NX_OPTIN=1 140 | 141 | 142 | 143 | 144 | 145 | 146 | %(PreprocessorDefinitions);POOL_NX_OPTIN=1 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | -------------------------------------------------------------------------------- /Message Tracing/exe/event.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {43F430EA-B1A7-4A80-B390-121C1C5A99C4} 23 | $(MSBuildProjectName) 24 | Debug 25 | Win32 26 | {BF9BBA5B-7BCF-4527-B357-39679BBF1DBA} 27 | 28 | 29 | 30 | Windows10 31 | False 32 | Desktop 33 | 34 | WindowsApplicationForDrivers10.0 35 | Application 36 | 37 | 38 | Windows10 39 | True 40 | Desktop 41 | 42 | WindowsApplicationForDrivers10.0 43 | Application 44 | false 45 | 46 | 47 | Windows10 48 | False 49 | Desktop 50 | 51 | WindowsApplicationForDrivers10.0 52 | Application 53 | 54 | 55 | Windows10 56 | True 57 | Desktop 58 | 59 | WindowsApplicationForDrivers10.0 60 | Application 61 | 62 | 63 | 64 | $(IntDir) 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | event 81 | 82 | 83 | event 84 | 85 | 86 | event 87 | 88 | 89 | event 90 | 91 | 92 | 93 | true 94 | Level4 95 | %(AdditionalIncludeDirectories);..\wdm 96 | 97 | 98 | 99 | 100 | %(AdditionalIncludeDirectories);..\wdm 101 | 102 | 103 | %(AdditionalIncludeDirectories);..\wdm 104 | 105 | 106 | 107 | 108 | false 109 | Level4 110 | %(AdditionalIncludeDirectories);..\wdm 111 | 112 | 113 | MultiThreadedDebug 114 | 115 | 116 | %(AdditionalIncludeDirectories);..\wdm 117 | 118 | 119 | %(AdditionalIncludeDirectories);..\wdm 120 | 121 | 122 | 123 | 124 | true 125 | Level4 126 | %(AdditionalIncludeDirectories);..\wdm 127 | 128 | 129 | 130 | 131 | %(AdditionalIncludeDirectories);..\wdm 132 | 133 | 134 | %(AdditionalIncludeDirectories);..\wdm 135 | 136 | 137 | 138 | 139 | true 140 | Level4 141 | %(AdditionalIncludeDirectories);..\wdm 142 | 143 | 144 | 145 | 146 | %(AdditionalIncludeDirectories);..\wdm 147 | 148 | 149 | %(AdditionalIncludeDirectories);..\wdm 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | -------------------------------------------------------------------------------- /Message Tracing/exe/eventtest.c: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) Microsoft Corporation. All rights reserved. 4 | 5 | THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY 6 | KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 7 | IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR 8 | PURPOSE. 9 | 10 | Module Name: 11 | 12 | EventTest.c 13 | 14 | Abstract: 15 | 16 | Simple console test app for the event.sys driver. 17 | 18 | Enviroment: 19 | 20 | User Mode 21 | 22 | Revision History: 23 | 24 | --*/ 25 | 26 | // 27 | // INCLUDES 28 | // 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include "public.h" 37 | 38 | BOOLEAN 39 | ManageDriver( 40 | _In_ LPCTSTR DriverName, 41 | _In_ LPCTSTR ServiceName, 42 | _In_ USHORT Function 43 | ); 44 | 45 | BOOLEAN 46 | SetupDriverName( 47 | _Inout_updates_bytes_all_(BufferLength) PCHAR DriverLocation, 48 | _In_ ULONG BufferLength 49 | ); 50 | 51 | #define USAGE() {\ 52 | printf("event <0/1>\n");\ 53 | printf("\t 0 for IRP based and 1 for event based notification.\n");\ 54 | } 55 | 56 | // 57 | // MAIN 58 | // 59 | VOID __cdecl 60 | main( 61 | _In_ ULONG argc, 62 | _In_reads_(argc) PCHAR argv[] 63 | ) 64 | { 65 | BOOL bStatus; 66 | HANDLE hDevice; 67 | ULONG ulReturnedLength; 68 | REGISTER_EVENT registerEvent; 69 | UINT type = EVENT_BASED; 70 | DWORD errNum = 0; 71 | TCHAR driverLocation[MAX_PATH] = { 0 }; 72 | 73 | 74 | if ( (argc < 2) || (argv[1] == NULL) ) { 75 | USAGE(); 76 | exit(1); 77 | } 78 | 79 | 80 | if (sscanf_s( argv[1], "%d", &type ) == 0) { 81 | printf("sscanf_s failed\n"); 82 | exit(1); 83 | } 84 | 85 | // 86 | // open the device 87 | // 88 | if ((hDevice = CreateFile( 89 | "\\\\.\\Event_Sample", // lpFileName 90 | GENERIC_READ | GENERIC_WRITE, // dwDesiredAccess 91 | FILE_SHARE_READ | FILE_SHARE_WRITE, // dwShareMode 92 | NULL, // lpSecurityAttributes 93 | OPEN_EXISTING, // dwCreationDistribution 94 | 0, // dwFlagsAndAttributes 95 | NULL // hTemplateFile 96 | )) == INVALID_HANDLE_VALUE) 97 | { 98 | 99 | errNum = GetLastError(); 100 | 101 | if (errNum != ERROR_FILE_NOT_FOUND) { 102 | 103 | printf("CreateFile failed! ERROR_FILE_NOT_FOUND = %d\n", errNum); 104 | 105 | return ; 106 | } 107 | 108 | // 109 | // The driver is not started yet so let us the install driver. 110 | // First setup full path to driver name. 111 | // 112 | 113 | if (!SetupDriverName(driverLocation, sizeof(driverLocation) )) { 114 | 115 | return ; 116 | } 117 | 118 | if (!ManageDriver(DRIVER_NAME, 119 | driverLocation, 120 | DRIVER_FUNC_INSTALL 121 | )) { 122 | 123 | printf("Unable to install driver. \n"); 124 | 125 | // 126 | // Error - remove driver. 127 | // 128 | 129 | ManageDriver(DRIVER_NAME, 130 | driverLocation, 131 | DRIVER_FUNC_REMOVE 132 | ); 133 | 134 | return; 135 | } 136 | 137 | // 138 | // Now open the device again. 139 | // 140 | hDevice = CreateFile( 141 | "\\\\.\\Event_Sample", // lpFileName 142 | GENERIC_READ | GENERIC_WRITE, // dwDesiredAccess 143 | FILE_SHARE_READ | FILE_SHARE_WRITE, // dwShareMode 144 | NULL, // lpSecurityAttributes 145 | OPEN_EXISTING, // dwCreationDistribution 146 | 0, // dwFlagsAndAttributes 147 | NULL // hTemplateFile 148 | ); 149 | 150 | if ( hDevice == INVALID_HANDLE_VALUE ){ 151 | printf ( "Error: CreatFile Failed : %d\n", GetLastError()); 152 | return; 153 | } 154 | 155 | } 156 | 157 | // 158 | // set the event signal delay. Use relative time for this sample 159 | // 160 | registerEvent.Type = type; 161 | 162 | if (type == EVENT_BASED) { 163 | // 164 | // 165 | // 166 | registerEvent.hEvent = CreateEvent( 167 | NULL, // lpEventAttributes 168 | TRUE, // bManualReset 169 | FALSE, // bInitialState 170 | #ifdef DBG 171 | "TEST_EVENT" // use WinObj to view named events for DBG 172 | #else 173 | NULL // lpName 174 | #endif 175 | ); 176 | 177 | 178 | if ( !registerEvent.hEvent ) { 179 | printf("CreateEvent error = %d\n", GetLastError() ); 180 | } else { 181 | 182 | printf("Event HANDLE = %p\n", registerEvent.hEvent ); 183 | printf("Press any key to exit.\n"); 184 | while( !_kbhit() ) { 185 | bStatus = DeviceIoControl( 186 | hDevice, // Handle to device 187 | IOCTL_REGISTER_EVENT, // IO Control code 188 | ®isterEvent, // Input Buffer to driver. 189 | SIZEOF_REGISTER_EVENT, // Length of input buffer in bytes. 190 | NULL, // Output Buffer from driver. 191 | 0, // Length of output buffer in bytes. 192 | &ulReturnedLength, // Bytes placed in buffer. 193 | NULL // synchronous call 194 | ); 195 | 196 | if ( !bStatus ) { 197 | printf("Ioctl failed with code %d\n", GetLastError() ); 198 | break; 199 | } else { 200 | printf("Waiting for Event...\n"); 201 | 202 | WaitForSingleObject(registerEvent.hEvent, 203 | INFINITE ); 204 | 205 | printf("Event signalled.\n\n"); 206 | 207 | ResetEvent( registerEvent.hEvent); 208 | //printf("Event reset.\n"); 209 | } 210 | } 211 | } 212 | 213 | }else if (type == IRP_BASED) { 214 | 215 | printf("Press any key to exit.\n"); 216 | registerEvent.hEvent = NULL; 217 | registerEvent.Type = IRP_BASED; 218 | 219 | while( !_kbhit() ) { 220 | 221 | char OutputBuffer[UsermodeBufferSize]; 222 | 223 | memset(OutputBuffer, 0, UsermodeBufferSize); 224 | 225 | bStatus = DeviceIoControl( 226 | hDevice, // Handle to device 227 | IOCTL_REGISTER_EVENT, // IO Control code 228 | ®isterEvent, // Input Buffer to driver. 229 | SIZEOF_REGISTER_EVENT, // Length of input buffer in bytes. 230 | OutputBuffer, // Output Buffer from driver. 231 | sizeof(OutputBuffer), // Length of output buffer in bytes. 232 | &ulReturnedLength, // Bytes placed in buffer. 233 | NULL // synchronous call 234 | ); 235 | 236 | // Sleep(3000); 237 | printf("Returned Size : 0x%x \n", ulReturnedLength); 238 | 239 | UINT32 OperationCode = 0; 240 | memcpy(&OperationCode, OutputBuffer, sizeof(UINT32)); 241 | printf("Operation Code : 0x%x \n", OperationCode); 242 | 243 | 244 | printf("Buffer : %s \n", OutputBuffer + sizeof(UINT32)); 245 | 246 | if ( !bStatus ) { 247 | printf("Ioctl failed with code %d\n", GetLastError() ); 248 | break; 249 | } 250 | printf("Event occurred.\n\n"); 251 | printf("\nRegistering event again....\n\n"); 252 | } 253 | 254 | }else { //unknown type 255 | USAGE(); 256 | } 257 | 258 | // 259 | // close the handle to the device. 260 | // 261 | CloseHandle(hDevice); 262 | 263 | // 264 | // Unload the driver if loaded. Ignore any errors. 265 | // 266 | if (driverLocation[0] != (TCHAR)0) { 267 | ManageDriver(DRIVER_NAME, 268 | driverLocation, 269 | DRIVER_FUNC_REMOVE 270 | ); 271 | 272 | } 273 | 274 | return; 275 | } 276 | -------------------------------------------------------------------------------- /HypervisorBypassWithNMI/HypervisorBypassWithNMI/HypervisorBypassWithNMI.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | Debug 22 | ARM 23 | 24 | 25 | Release 26 | ARM 27 | 28 | 29 | Debug 30 | ARM64 31 | 32 | 33 | Release 34 | ARM64 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | {0098100B-EE58-43E9-9952-9C7B4E3FE89D} 52 | {497e31cb-056b-4f31-abb8-447fd55ee5a5} 53 | v4.5 54 | 12.0 55 | Debug 56 | Win32 57 | HypervisorBypassWithNMI 58 | 59 | 60 | 61 | Windows10 62 | true 63 | WindowsKernelModeDriver10.0 64 | Driver 65 | KMDF 66 | Universal 67 | false 68 | 69 | 70 | Windows10 71 | false 72 | WindowsKernelModeDriver10.0 73 | Driver 74 | KMDF 75 | Universal 76 | 77 | 78 | Windows10 79 | true 80 | WindowsKernelModeDriver10.0 81 | Driver 82 | KMDF 83 | Universal 84 | false 85 | 86 | 87 | Windows10 88 | false 89 | WindowsKernelModeDriver10.0 90 | Driver 91 | KMDF 92 | Universal 93 | 94 | 95 | Windows10 96 | true 97 | WindowsKernelModeDriver10.0 98 | Driver 99 | KMDF 100 | Universal 101 | 102 | 103 | Windows10 104 | false 105 | WindowsKernelModeDriver10.0 106 | Driver 107 | KMDF 108 | Universal 109 | 110 | 111 | Windows10 112 | true 113 | WindowsKernelModeDriver10.0 114 | Driver 115 | KMDF 116 | Universal 117 | 118 | 119 | Windows10 120 | false 121 | WindowsKernelModeDriver10.0 122 | Driver 123 | KMDF 124 | Universal 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | DbgengKernelDebugger 136 | 137 | 138 | DbgengKernelDebugger 139 | 140 | 141 | DbgengKernelDebugger 142 | 143 | 144 | DbgengKernelDebugger 145 | 146 | 147 | DbgengKernelDebugger 148 | 149 | 150 | DbgengKernelDebugger 151 | 152 | 153 | DbgengKernelDebugger 154 | 155 | 156 | DbgengKernelDebugger 157 | 158 | 159 | 160 | true 161 | true 162 | trace.h 163 | true 164 | false 165 | 166 | 167 | 168 | 169 | true 170 | true 171 | trace.h 172 | true 173 | 174 | 175 | 176 | 177 | false 178 | true 179 | trace.h 180 | true 181 | false 182 | 183 | 184 | 185 | 186 | true 187 | true 188 | trace.h 189 | true 190 | 191 | 192 | 193 | 194 | true 195 | true 196 | trace.h 197 | true 198 | 199 | 200 | 201 | 202 | true 203 | true 204 | trace.h 205 | true 206 | 207 | 208 | 209 | 210 | true 211 | true 212 | trace.h 213 | true 214 | 215 | 216 | 217 | 218 | true 219 | true 220 | trace.h 221 | true 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | -------------------------------------------------------------------------------- /TypeInfoCallbacksHooker/TypeInfoCallbacksHooker.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | Debug 22 | ARM 23 | 24 | 25 | Release 26 | ARM 27 | 28 | 29 | Debug 30 | ARM64 31 | 32 | 33 | Release 34 | ARM64 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | {53D0AEA9-E6B9-45D8-914F-470F0534FEE7} 52 | {497e31cb-056b-4f31-abb8-447fd55ee5a5} 53 | v4.5 54 | 12.0 55 | Debug 56 | Win32 57 | TypeInfoCallbacksHooker 58 | 59 | 60 | 61 | Windows10 62 | true 63 | WindowsKernelModeDriver10.0 64 | Driver 65 | KMDF 66 | Universal 67 | 68 | 69 | Windows10 70 | false 71 | WindowsKernelModeDriver10.0 72 | Driver 73 | KMDF 74 | Universal 75 | 76 | 77 | Windows10 78 | true 79 | WindowsKernelModeDriver10.0 80 | Driver 81 | KMDF 82 | Universal 83 | false 84 | 85 | 86 | Windows10 87 | false 88 | WindowsKernelModeDriver10.0 89 | Driver 90 | KMDF 91 | Universal 92 | 93 | 94 | Windows10 95 | true 96 | WindowsKernelModeDriver10.0 97 | Driver 98 | KMDF 99 | Universal 100 | 101 | 102 | Windows10 103 | false 104 | WindowsKernelModeDriver10.0 105 | Driver 106 | KMDF 107 | Universal 108 | 109 | 110 | Windows10 111 | true 112 | WindowsKernelModeDriver10.0 113 | Driver 114 | KMDF 115 | Universal 116 | 117 | 118 | Windows10 119 | false 120 | WindowsKernelModeDriver10.0 121 | Driver 122 | KMDF 123 | Universal 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | DbgengKernelDebugger 135 | 136 | 137 | DbgengKernelDebugger 138 | 139 | 140 | DbgengKernelDebugger 141 | 142 | 143 | DbgengKernelDebugger 144 | 145 | 146 | DbgengKernelDebugger 147 | 148 | 149 | DbgengKernelDebugger 150 | 151 | 152 | DbgengKernelDebugger 153 | 154 | 155 | DbgengKernelDebugger 156 | 157 | 158 | 159 | true 160 | true 161 | trace.h 162 | true 163 | 164 | 165 | 166 | 167 | true 168 | true 169 | trace.h 170 | true 171 | 172 | 173 | 174 | 175 | false 176 | true 177 | trace.h 178 | true 179 | false 180 | 181 | 182 | 183 | 184 | true 185 | true 186 | trace.h 187 | true 188 | 189 | 190 | 191 | 192 | true 193 | true 194 | trace.h 195 | true 196 | 197 | 198 | 199 | 200 | true 201 | true 202 | trace.h 203 | true 204 | 205 | 206 | 207 | 208 | true 209 | true 210 | trace.h 211 | true 212 | 213 | 214 | 215 | 216 | true 217 | true 218 | trace.h 219 | true 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | -------------------------------------------------------------------------------- /ObRegisterCallbacks/ObRegisterCallbacks/ObRegisterCallbacks.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | Debug 22 | ARM 23 | 24 | 25 | Release 26 | ARM 27 | 28 | 29 | Debug 30 | ARM64 31 | 32 | 33 | Release 34 | ARM64 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | {6206DABB-C8F6-4194-8878-B79ABF197E95} 52 | {497e31cb-056b-4f31-abb8-447fd55ee5a5} 53 | v4.5 54 | 12.0 55 | Debug 56 | Win32 57 | ObRegisterCallbacks 58 | 59 | 60 | 61 | Windows10 62 | true 63 | WindowsKernelModeDriver10.0 64 | Driver 65 | KMDF 66 | Universal 67 | 68 | 69 | Windows10 70 | false 71 | WindowsKernelModeDriver10.0 72 | Driver 73 | KMDF 74 | Universal 75 | 76 | 77 | Windows10 78 | true 79 | WindowsKernelModeDriver10.0 80 | Driver 81 | KMDF 82 | Universal 83 | 84 | 85 | Windows10 86 | false 87 | WindowsKernelModeDriver10.0 88 | Driver 89 | KMDF 90 | Universal 91 | 92 | 93 | Windows10 94 | true 95 | WindowsKernelModeDriver10.0 96 | Driver 97 | KMDF 98 | Universal 99 | 100 | 101 | Windows10 102 | false 103 | WindowsKernelModeDriver10.0 104 | Driver 105 | KMDF 106 | Universal 107 | 108 | 109 | Windows10 110 | true 111 | WindowsKernelModeDriver10.0 112 | Driver 113 | KMDF 114 | Universal 115 | 116 | 117 | Windows10 118 | false 119 | WindowsKernelModeDriver10.0 120 | Driver 121 | KMDF 122 | Universal 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | DbgengKernelDebugger 134 | 135 | 136 | DbgengKernelDebugger 137 | 138 | 139 | DbgengKernelDebugger 140 | 141 | 142 | DbgengKernelDebugger 143 | 144 | 145 | DbgengKernelDebugger 146 | 147 | 148 | DbgengKernelDebugger 149 | 150 | 151 | DbgengKernelDebugger 152 | 153 | 154 | DbgengKernelDebugger 155 | 156 | 157 | 158 | true 159 | true 160 | trace.h 161 | true 162 | 163 | 164 | 165 | 166 | true 167 | true 168 | trace.h 169 | true 170 | 171 | 172 | 173 | 174 | false 175 | true 176 | trace.h 177 | true 178 | false 179 | 180 | 181 | C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\lib\amd64;%(AdditionalLibraryDirectories) 182 | 183 | 184 | 185 | 186 | true 187 | true 188 | trace.h 189 | true 190 | 191 | 192 | 193 | 194 | true 195 | true 196 | trace.h 197 | true 198 | 199 | 200 | 201 | 202 | true 203 | true 204 | trace.h 205 | true 206 | 207 | 208 | 209 | 210 | true 211 | true 212 | trace.h 213 | true 214 | 215 | 216 | 217 | 218 | true 219 | true 220 | trace.h 221 | true 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | -------------------------------------------------------------------------------- /TypeInfoCallbacksHooker/Driver.c: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Module Name: 4 | 5 | driver.c 6 | 7 | Abstract: 8 | 9 | This file contains the driver entry points and callbacks. 10 | 11 | Environment: 12 | 13 | Kernel-mode Driver Framework 14 | 15 | --*/ 16 | 17 | #include "driver.h" 18 | #include "Header.h" 19 | 20 | UINT64 CallbacksList; 21 | 22 | #ifdef ALLOC_PRAGMA 23 | #pragma alloc_text (INIT, DriverEntry) 24 | #endif 25 | 26 | 27 | typedef unsigned int DWORD; 28 | 29 | 30 | int OkayToCloseProcedure_Hook( 31 | PEPROCESS Process, 32 | DWORD DW, 33 | HANDLE Handle, 34 | KPROCESSOR_MODE PreviousMode) 35 | { 36 | if (PreviousMode == KernelMode) 37 | DbgPrint("Attempt to close the handle : %x to a process opened by the kernel process : %s\n", Handle, (PUCHAR)Process + 0x450 /*+0x450 ImageFileName : [15] UChar*/); 38 | else 39 | DbgPrint("Attempt to close the handle : %x to a process opened by the usermode process : %s\n", Handle, (PUCHAR)Process + 0x450/*+0x450 ImageFileName : [15] UChar*/); 40 | return 1; 41 | } 42 | 43 | typedef int(*DumpProcedure)(PVOID Object, OBJECT_DUMP_CONTROL* DumpControl); 44 | DumpProcedure _DumpProcedure; 45 | 46 | int DumpProcedure_Hook( 47 | PVOID Object, 48 | OBJECT_DUMP_CONTROL* DumpControl) 49 | { 50 | DbgPrint("[*] DumpProcedure called for object : 0x%llx \n", Object); 51 | return _DumpProcedure(Object, DumpControl); 52 | } 53 | 54 | typedef int(*OpenProcedure)(OB_OPEN_REASON OpenReason, CHAR AccessMode, PEPROCESS TargetProcess, PVOID Object, PULONG GrantedAccess, ULONG HandleCount); 55 | OpenProcedure _OpenProcedure; 56 | 57 | int OpenProcedure_Hook( 58 | OB_OPEN_REASON OpenReason, 59 | CHAR AccessMode, 60 | PEPROCESS TargetProcess, 61 | PVOID Object, 62 | PULONG GrantedAccess, 63 | ULONG HandleCount) 64 | { 65 | DbgPrint("[*] OpenProcedure called for object : 0x%llx , TargetProcess : %s , Access Mode : %d , Granted Access : %x\n", 66 | Object, (PUCHAR)TargetProcess + 0x450, AccessMode, GrantedAccess); 67 | 68 | return _OpenProcedure(OpenReason, AccessMode, TargetProcess, Object, GrantedAccess, HandleCount); 69 | } 70 | 71 | typedef int(*CloseProcedure)(PEPROCESS Process, PVOID Object, ULONG ProcessHandleCount, ULONG SystemHandleCount); 72 | CloseProcedure _CloseProcedure; 73 | 74 | int CloseProcedure_Hook( 75 | PEPROCESS Process, 76 | PVOID Object, 77 | ULONG ProcessHandleCount, 78 | ULONG SystemHandleCount) 79 | { 80 | DbgPrint("[*] CloseProcedure called for object : 0x%llx, Process : %s \n", Object, (PUCHAR)Process + 0x450); 81 | return _CloseProcedure(Process, Object, ProcessHandleCount, SystemHandleCount); 82 | } 83 | 84 | typedef int(*DeleteProcedure)(PVOID Object); 85 | DeleteProcedure _DeleteProcedure; 86 | 87 | int DeleteProcedure_Hook( 88 | PVOID Object) 89 | { 90 | DbgPrint("[*] DeleteProcedure called for object : 0x%llx \n", Object); 91 | return _DeleteProcedure(Object); 92 | } 93 | 94 | typedef int(*ParseProcedure)(PVOID ParseObject, PVOID ObjectType, PACCESS_STATE AccessState, CHAR AccessMode, ULONG Attributes, UNICODE_STRING* CompleteName, UNICODE_STRING* RemainingName, PVOID Context, SECURITY_QUALITY_OF_SERVICE* SecurityQos, OB_EXTENDED_PARSE_PARAMETERS* ExtendedParameters, PVOID* Object); 95 | ParseProcedure _ParseProcedure; 96 | 97 | int ParseProcedure_Hook( 98 | PVOID ParseObject, 99 | PVOID ObjectType, 100 | PACCESS_STATE AccessState, 101 | CHAR AccessMode, 102 | ULONG Attributes, 103 | UNICODE_STRING* CompleteName, 104 | UNICODE_STRING* RemainingName, 105 | PVOID Context, 106 | SECURITY_QUALITY_OF_SERVICE* SecurityQos, 107 | OB_EXTENDED_PARSE_PARAMETERS* ExtendedParameters, 108 | PVOID* Object) 109 | { 110 | DbgPrint("[*] ParseProcedure called for ParseObject : 0x%llx \n", ParseObject); 111 | return _ParseProcedure(ParseObject, ObjectType, AccessState, AccessMode, Attributes, CompleteName, RemainingName, Context, SecurityQos, ExtendedParameters, Object); 112 | } 113 | 114 | 115 | typedef int(*SecurityProcedure)(PVOID Object, SECURITY_OPERATION_CODE OperationCode, PULONG SecurityInformation, PVOID SecurityDescriptor, PULONG CapturedLength, PVOID* ObjectsSecurityDescriptor, POOL_TYPE PoolType, PGENERIC_MAPPING GenericMapping, CHAR Mode); 116 | SecurityProcedure _SecurityProcedure; 117 | 118 | int SecurityProcedure_Hook( 119 | PVOID Object, 120 | SECURITY_OPERATION_CODE OperationCode, 121 | PULONG SecurityInformation, 122 | PVOID SecurityDescriptor, 123 | PULONG CapturedLength, 124 | PVOID* ObjectsSecurityDescriptor, 125 | POOL_TYPE PoolType, 126 | PGENERIC_MAPPING GenericMapping, 127 | CHAR Mode) 128 | { 129 | DbgPrint("[*] SecurityProcedure called for Object : 0x%llx \n", Object); 130 | return _SecurityProcedure(Object, OperationCode, SecurityInformation, SecurityDescriptor, CapturedLength, ObjectsSecurityDescriptor, PoolType, GenericMapping, Mode); 131 | } 132 | 133 | typedef int(*QueryNameProcedure)(PVOID Object, UCHAR HasObjectName, POBJECT_NAME_INFORMATION ObjectNameInfo, ULONG Length, PULONG* ReturnLength, CHAR Mode); 134 | QueryNameProcedure _QueryNameProcedure; 135 | 136 | int QueryNameProcedure_Hook( 137 | PVOID Object, 138 | UCHAR HasObjectName, 139 | POBJECT_NAME_INFORMATION ObjectNameInfo, 140 | ULONG Length, 141 | PULONG* ReturnLength, 142 | CHAR Mode) 143 | { 144 | DbgPrint("[*] QueryNameProcedure called for object : 0x%llx \n", Object); 145 | return _QueryNameProcedure(Object, HasObjectName, ObjectNameInfo, Length, ReturnLength, Mode); 146 | } 147 | 148 | 149 | VOID DrvUnload(PDRIVER_OBJECT DriverObject) 150 | { 151 | UNICODE_STRING usDosDeviceName; 152 | 153 | 154 | PUCHAR ObjectType; 155 | //ObjectType = ObGetObjectType(PsGetCurrentProcess()); 156 | ObjectType = (PUCHAR)*PsProcessType; 157 | if (*(INT64*)(ObjectType + 0xa8) == (INT64)OkayToCloseProcedure_Hook) 158 | *(INT64*)(ObjectType + 0xa8) = NULL; 159 | DbgPrint("[+] Hook Deleted for the Process Object\n"); 160 | 161 | 162 | DbgPrint("[*] DrvUnload Called."); 163 | RtlInitUnicodeString(&usDosDeviceName, L"\\DosDevices\\TypeInfoCallbacksHooker"); 164 | IoDeleteSymbolicLink(&usDosDeviceName); 165 | IoDeleteDevice(DriverObject->DeviceObject); 166 | 167 | } 168 | NTSTATUS DrvUnsupported(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) 169 | { 170 | DbgPrint("[*] This function is not supported :( !"); 171 | 172 | Irp->IoStatus.Status = STATUS_SUCCESS; 173 | Irp->IoStatus.Information = 0; 174 | IoCompleteRequest(Irp, IO_NO_INCREMENT); 175 | 176 | return STATUS_SUCCESS; 177 | } 178 | 179 | NTSTATUS 180 | DriverEntry( 181 | _In_ PDRIVER_OBJECT DriverObject, 182 | _In_ PUNICODE_STRING RegistryPath 183 | ) 184 | { 185 | NTSTATUS NtStatus = STATUS_SUCCESS; 186 | UINT64 uiIndex = 0; 187 | PDEVICE_OBJECT pDeviceObject = NULL; 188 | UNICODE_STRING usDriverName, usDosDeviceName; 189 | 190 | DbgPrint("[*] DriverEntry Called."); 191 | 192 | RtlInitUnicodeString(&usDriverName, L"\\Device\\TypeInfoCallbacksHooker"); 193 | 194 | RtlInitUnicodeString(&usDosDeviceName, L"\\DosDevices\\TypeInfoCallbacksHooker"); 195 | 196 | NtStatus = IoCreateDevice(DriverObject, 0, &usDriverName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &pDeviceObject); 197 | 198 | 199 | 200 | if (NtStatus == STATUS_SUCCESS) 201 | { 202 | DbgPrint("[*] Setting Devices major functions."); 203 | 204 | for (uiIndex = 0; uiIndex < IRP_MJ_MAXIMUM_FUNCTION; uiIndex++) 205 | DriverObject->MajorFunction[uiIndex] = DrvUnsupported; 206 | 207 | DriverObject->DriverUnload = DrvUnload; 208 | IoCreateSymbolicLink(&usDosDeviceName, &usDriverName); 209 | } 210 | else { 211 | DbgPrint("[*] There was some errors in creating device."); 212 | } 213 | 214 | PUCHAR ProcessObjectType; 215 | DbgPrint("[*] Hooking The Process Object's OkayToCloseProcedure Callback\n"); 216 | DbgPrint("[*] Every attempt to close a handle to a process will be displayed\n"); 217 | 218 | 219 | /* Get the Process Object Type (OBJECT_TYPE) structure */ 220 | 221 | // ProcessObjectType = ObGetObjectType(PsGetCurrentProcess()); 222 | ProcessObjectType = (PUCHAR)*PsProcessType; 223 | DbgPrint("[*] Process Object Type Structure at : %p\n", ProcessObjectType); 224 | 225 | // Allocating a buffer to store the previous callbacks pointer (if exists) 226 | // 8 Callbacks * 8 Bytes for each pointer 227 | CallbacksList = ExAllocatePoolWithTag(NonPagedPool, 8 * 8, 0x41414141); 228 | 229 | 230 | 231 | /*****************************************************************************************************************/ 232 | /* DumpProcedure_Hook */ 233 | if (*(INT64*)(ProcessObjectType + 0x70) != NULL) { 234 | 235 | // Store the previous pointer 236 | *(INT64*)(CallbacksList + 0) = *(INT64*)(ProcessObjectType + 0x70); 237 | _DumpProcedure = *(INT64*)(ProcessObjectType + 0x70); 238 | 239 | // Save to pointer to new hook address 240 | *(INT64*)(ProcessObjectType + 0x70) = (INT64)DumpProcedure_Hook; 241 | 242 | DbgPrint("[*] DumpProcedure Hook Done !!\n"); 243 | } 244 | else 245 | { 246 | DbgPrint("[*] DumpProcedure Hook Failed"); 247 | } 248 | /*****************************************************************************************************************/ 249 | /* OpenProcedure_Hook */ 250 | if (*(INT64*)(ProcessObjectType + 0x78) != NULL) { 251 | 252 | // Store the previous pointer 253 | *(INT64*)(CallbacksList + 0x8) = *(INT64*)(ProcessObjectType + 0x78); 254 | _OpenProcedure = *(INT64*)(ProcessObjectType + 0x78); 255 | 256 | 257 | // Save to pointer to new hook address 258 | *(INT64*)(ProcessObjectType + 0x78) = (INT64)OpenProcedure_Hook; 259 | 260 | DbgPrint("[*] OpenProcedure Hook Done !!\n"); 261 | } 262 | else 263 | { 264 | DbgPrint("[*] OpenProcedure Hook Failed"); 265 | } 266 | /*****************************************************************************************************************/ 267 | /* CloseProcedure_Hook */ 268 | if (*(INT64*)(ProcessObjectType + 0x80) != NULL) { 269 | 270 | // Store the previous pointer 271 | *(INT64*)(CallbacksList + 0x10) = *(INT64*)(ProcessObjectType + 0x80); 272 | _CloseProcedure = *(INT64*)(ProcessObjectType + 0x80); 273 | 274 | 275 | // Save to pointer to new hook address 276 | *(INT64*)(ProcessObjectType + 0x80) = (INT64)CloseProcedure_Hook; 277 | 278 | DbgPrint("[*] CloseProcedure Hook Done !!\n"); 279 | } 280 | else 281 | { 282 | DbgPrint("[*] CloseProcedure Hook Failed"); 283 | } 284 | /*****************************************************************************************************************/ 285 | /* DeleteProcedure_Hook */ 286 | if (*(INT64*)(ProcessObjectType + 0x88) != NULL) { 287 | 288 | // Store the previous pointer 289 | *(INT64*)(CallbacksList + 0x18) = *(INT64*)(ProcessObjectType + 0x88); 290 | _DeleteProcedure = *(INT64*)(ProcessObjectType + 0x88); 291 | 292 | // Save to pointer to new hook address 293 | *(INT64*)(ProcessObjectType + 0x88) = (INT64)DeleteProcedure_Hook; 294 | 295 | DbgPrint("[*] DeleteProcedure Hook Done !!\n"); 296 | } 297 | else 298 | { 299 | DbgPrint("[*] DeleteProcedure Hook Failed"); 300 | } 301 | /*****************************************************************************************************************/ 302 | /* ParseProcedure & ParseProcedureEx _Hook */ 303 | if (*(INT64*)(ProcessObjectType + 0x90) != NULL) { 304 | 305 | // Store the previous pointer 306 | *(INT64*)(CallbacksList + 0x20) = *(INT64*)(ProcessObjectType + 0x90); 307 | _ParseProcedure = *(INT64*)(ProcessObjectType + 0x90); 308 | 309 | // Save to pointer to new hook address 310 | *(INT64*)(ProcessObjectType + 0x90) = (INT64)ParseProcedure_Hook; 311 | 312 | DbgPrint("[*] ParseProcedure Hook Done !!\n"); 313 | } 314 | else 315 | { 316 | DbgPrint("[*] ParseProcedure Hook Failed"); 317 | } 318 | /*****************************************************************************************************************/ 319 | /* SecurityProcedure_Hook */ 320 | if (*(INT64*)(ProcessObjectType + 0x98) != NULL) { 321 | 322 | // Store the previous pointer 323 | *(INT64*)(CallbacksList + 0x28) = *(INT64*)(ProcessObjectType + 0x98); 324 | _SecurityProcedure = *(INT64*)(ProcessObjectType + 0x98); 325 | 326 | // Save to pointer to new hook address 327 | *(INT64*)(ProcessObjectType + 0x98) = (INT64)SecurityProcedure_Hook; 328 | 329 | DbgPrint("[*] SecurityProcedure Hook Done !!\n"); 330 | } 331 | else 332 | { 333 | DbgPrint("[*] SecurityProcedure Hook Failed"); 334 | } 335 | /*****************************************************************************************************************/ 336 | /* QueryNameProcedure_Hook */ 337 | if (*(INT64*)(ProcessObjectType + 0xa0) != NULL) { 338 | 339 | // Store the previous pointer 340 | *(INT64*)(CallbacksList + 0x30) = *(INT64*)(ProcessObjectType + 0xa0); 341 | _QueryNameProcedure = *(INT64*)(ProcessObjectType + 0xa0); 342 | 343 | // Save to pointer to new hook address 344 | *(INT64*)(ProcessObjectType + 0xa0) = (INT64)QueryNameProcedure_Hook; 345 | 346 | DbgPrint("[*] QueryNameProcedure Hook Done !!\n"); 347 | } 348 | else 349 | { 350 | DbgPrint("[*] QueryNameProcedure Hook Failed"); 351 | } 352 | 353 | /*****************************************************************************************************************/ 354 | /* Set the OkayToCloseProcedure function pointer from the OBJECT_TYPE_INITIALIZER structure to the hook function */ 355 | if (*(INT64*)(ProcessObjectType + 0xa8) == NULL) { 356 | *(INT64*)(ProcessObjectType + 0xa8) = (INT64)OkayToCloseProcedure_Hook; 357 | DbgPrint("[*] OkayToCloseProcedure Hook Done !!\n"); 358 | } 359 | else 360 | { 361 | DbgPrint("[*] OkayToCloseProcedure Hook Failed"); 362 | } 363 | /*****************************************************************************************************************/ 364 | 365 | 366 | return NtStatus; 367 | } 368 | 369 | -------------------------------------------------------------------------------- /Message Tracing/exe/install.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "public.h" 8 | 9 | BOOLEAN 10 | InstallDriver( 11 | _In_ SC_HANDLE SchSCManager, 12 | _In_ LPCTSTR DriverName, 13 | _In_ LPCTSTR ServiceExe 14 | ); 15 | 16 | 17 | BOOLEAN 18 | RemoveDriver( 19 | _In_ SC_HANDLE SchSCManager, 20 | _In_ LPCTSTR DriverName 21 | ); 22 | 23 | BOOLEAN 24 | StartDriver( 25 | _In_ SC_HANDLE SchSCManager, 26 | _In_ LPCTSTR DriverName 27 | ); 28 | 29 | BOOLEAN 30 | StopDriver( 31 | _In_ SC_HANDLE SchSCManager, 32 | _In_ LPCTSTR DriverName 33 | ); 34 | 35 | BOOLEAN 36 | InstallDriver( 37 | _In_ SC_HANDLE SchSCManager, 38 | _In_ LPCTSTR DriverName, 39 | _In_ LPCTSTR ServiceExe 40 | ) 41 | /*++ 42 | 43 | Routine Description: 44 | 45 | Arguments: 46 | 47 | Return Value: 48 | 49 | --*/ 50 | { 51 | SC_HANDLE schService; 52 | DWORD err; 53 | 54 | // 55 | // NOTE: This creates an entry for a standalone driver. If this 56 | // is modified for use with a driver that requires a Tag, 57 | // Group, and/or Dependencies, it may be necessary to 58 | // query the registry for existing driver information 59 | // (in order to determine a unique Tag, etc.). 60 | // 61 | 62 | // 63 | // Create a new a service object. 64 | // 65 | 66 | schService = CreateService(SchSCManager, // handle of service control manager database 67 | DriverName, // address of name of service to start 68 | DriverName, // address of display name 69 | SERVICE_ALL_ACCESS, // type of access to service 70 | SERVICE_KERNEL_DRIVER, // type of service 71 | SERVICE_DEMAND_START, // when to start service 72 | SERVICE_ERROR_NORMAL, // severity if service fails to start 73 | ServiceExe, // address of name of binary file 74 | NULL, // service does not belong to a group 75 | NULL, // no tag requested 76 | NULL, // no dependency names 77 | NULL, // use LocalSystem account 78 | NULL // no password for service account 79 | ); 80 | 81 | if (schService == NULL) { 82 | 83 | err = GetLastError(); 84 | 85 | if (err == ERROR_SERVICE_EXISTS) { 86 | 87 | // 88 | // Ignore this error. 89 | // 90 | 91 | return TRUE; 92 | 93 | } else if (err == ERROR_SERVICE_MARKED_FOR_DELETE) { 94 | // 95 | // Previous instance of the service is not fully deleted so sleep 96 | // and try again. 97 | // 98 | printf("Previous instance of the service is not fully deleted. Try again...\n"); 99 | return FALSE; 100 | } 101 | else { 102 | 103 | printf("CreateService failed! Error = %d \n", err ); 104 | 105 | // 106 | // Indicate an error. 107 | // 108 | 109 | return FALSE; 110 | } 111 | } 112 | 113 | // 114 | // Close the service object. 115 | // 116 | 117 | if (schService) { 118 | 119 | CloseServiceHandle(schService); 120 | } 121 | 122 | // 123 | // Indicate success. 124 | // 125 | 126 | return TRUE; 127 | 128 | } // InstallDriver 129 | 130 | BOOLEAN 131 | ManageDriver( 132 | _In_ LPCTSTR DriverName, 133 | _In_ LPCTSTR ServiceName, 134 | _In_ USHORT Function 135 | ) 136 | { 137 | 138 | SC_HANDLE schSCManager; 139 | 140 | BOOLEAN rCode = TRUE; 141 | 142 | // 143 | // Insure (somewhat) that the driver and service names are valid. 144 | // 145 | 146 | if (!DriverName || !ServiceName) { 147 | 148 | printf("Invalid Driver or Service provided to ManageDriver() \n"); 149 | 150 | return FALSE; 151 | } 152 | 153 | // 154 | // Connect to the Service Control Manager and open the Services database. 155 | // 156 | 157 | schSCManager = OpenSCManager(NULL, // local machine 158 | NULL, // local database 159 | SC_MANAGER_ALL_ACCESS // access required 160 | ); 161 | 162 | if (!schSCManager) { 163 | 164 | printf("Open SC Manager failed! Error = %d \n", GetLastError()); 165 | 166 | return FALSE; 167 | } 168 | 169 | // 170 | // Do the requested function. 171 | // 172 | 173 | switch( Function ) { 174 | 175 | case DRIVER_FUNC_INSTALL: 176 | 177 | // 178 | // Install the driver service. 179 | // 180 | 181 | if (InstallDriver(schSCManager, 182 | DriverName, 183 | ServiceName 184 | )) { 185 | 186 | // 187 | // Start the driver service (i.e. start the driver). 188 | // 189 | 190 | rCode = StartDriver(schSCManager, 191 | DriverName 192 | ); 193 | 194 | } else { 195 | 196 | // 197 | // Indicate an error. 198 | // 199 | 200 | rCode = FALSE; 201 | } 202 | 203 | break; 204 | 205 | case DRIVER_FUNC_REMOVE: 206 | 207 | // 208 | // Stop the driver. 209 | // 210 | 211 | StopDriver(schSCManager, 212 | DriverName 213 | ); 214 | 215 | // 216 | // Remove the driver service. 217 | // 218 | 219 | RemoveDriver(schSCManager, 220 | DriverName 221 | ); 222 | 223 | // 224 | // Ignore all errors. 225 | // 226 | 227 | rCode = TRUE; 228 | 229 | break; 230 | 231 | default: 232 | 233 | printf("Unknown ManageDriver() function. \n"); 234 | 235 | rCode = FALSE; 236 | 237 | break; 238 | } 239 | 240 | // 241 | // Close handle to service control manager. 242 | // 243 | 244 | if (schSCManager) { 245 | 246 | CloseServiceHandle(schSCManager); 247 | } 248 | 249 | return rCode; 250 | 251 | } // ManageDriver 252 | 253 | 254 | BOOLEAN 255 | RemoveDriver( 256 | _In_ SC_HANDLE SchSCManager, 257 | _In_ LPCTSTR DriverName 258 | ) 259 | { 260 | SC_HANDLE schService; 261 | BOOLEAN rCode; 262 | 263 | // 264 | // Open the handle to the existing service. 265 | // 266 | 267 | schService = OpenService(SchSCManager, 268 | DriverName, 269 | SERVICE_ALL_ACCESS 270 | ); 271 | 272 | if (schService == NULL) { 273 | 274 | printf("OpenService failed! Error = %d \n", GetLastError()); 275 | 276 | // 277 | // Indicate error. 278 | // 279 | 280 | return FALSE; 281 | } 282 | 283 | // 284 | // Mark the service for deletion from the service control manager database. 285 | // 286 | 287 | if (DeleteService(schService)) { 288 | 289 | // 290 | // Indicate success. 291 | // 292 | 293 | rCode = TRUE; 294 | 295 | } else { 296 | 297 | printf("DeleteService failed! Error = %d \n", GetLastError()); 298 | 299 | // 300 | // Indicate failure. Fall through to properly close the service handle. 301 | // 302 | 303 | rCode = FALSE; 304 | } 305 | 306 | // 307 | // Close the service object. 308 | // 309 | 310 | if (schService) { 311 | 312 | CloseServiceHandle(schService); 313 | } 314 | 315 | return rCode; 316 | 317 | } // RemoveDriver 318 | 319 | 320 | 321 | BOOLEAN 322 | StartDriver( 323 | _In_ SC_HANDLE SchSCManager, 324 | _In_ LPCTSTR DriverName 325 | ) 326 | { 327 | SC_HANDLE schService; 328 | DWORD err; 329 | 330 | // 331 | // Open the handle to the existing service. 332 | // 333 | 334 | schService = OpenService(SchSCManager, 335 | DriverName, 336 | SERVICE_ALL_ACCESS 337 | ); 338 | 339 | if (schService == NULL) { 340 | 341 | printf("OpenService failed! Error = %d \n", GetLastError()); 342 | 343 | // 344 | // Indicate failure. 345 | // 346 | 347 | return FALSE; 348 | } 349 | 350 | // 351 | // Start the execution of the service (i.e. start the driver). 352 | // 353 | 354 | if (!StartService(schService, // service identifier 355 | 0, // number of arguments 356 | NULL // pointer to arguments 357 | )) { 358 | 359 | err = GetLastError(); 360 | 361 | if (err == ERROR_SERVICE_ALREADY_RUNNING) { 362 | 363 | // 364 | // Ignore this error. 365 | // 366 | 367 | return TRUE; 368 | 369 | } else { 370 | 371 | printf("StartService failure! Error = %d \n", err ); 372 | 373 | // 374 | // Indicate failure. Fall through to properly close the service handle. 375 | // 376 | 377 | return FALSE; 378 | } 379 | 380 | } 381 | 382 | // 383 | // Close the service object. 384 | // 385 | 386 | if (schService) { 387 | 388 | CloseServiceHandle(schService); 389 | } 390 | 391 | return TRUE; 392 | 393 | } // StartDriver 394 | 395 | 396 | 397 | BOOLEAN 398 | StopDriver( 399 | _In_ SC_HANDLE SchSCManager, 400 | _In_ LPCTSTR DriverName 401 | ) 402 | { 403 | BOOLEAN rCode = TRUE; 404 | SC_HANDLE schService; 405 | SERVICE_STATUS serviceStatus; 406 | 407 | // 408 | // Open the handle to the existing service. 409 | // 410 | 411 | schService = OpenService(SchSCManager, 412 | DriverName, 413 | SERVICE_ALL_ACCESS 414 | ); 415 | 416 | if (schService == NULL) { 417 | 418 | printf("OpenService failed! Error = %d \n", GetLastError()); 419 | 420 | return FALSE; 421 | } 422 | 423 | // 424 | // Request that the service stop. 425 | // 426 | 427 | if (ControlService(schService, 428 | SERVICE_CONTROL_STOP, 429 | &serviceStatus 430 | )) { 431 | 432 | // 433 | // Indicate success. 434 | // 435 | 436 | rCode = TRUE; 437 | 438 | } else { 439 | 440 | printf("ControlService failed! Error = %d \n", GetLastError() ); 441 | 442 | // 443 | // Indicate failure. Fall through to properly close the service handle. 444 | // 445 | 446 | rCode = FALSE; 447 | } 448 | 449 | // 450 | // Close the service object. 451 | // 452 | 453 | if (schService) { 454 | 455 | CloseServiceHandle (schService); 456 | } 457 | 458 | return rCode; 459 | 460 | } // StopDriver 461 | 462 | BOOLEAN 463 | SetupDriverName( 464 | _Inout_updates_bytes_all_(BufferLength) PCHAR DriverLocation, 465 | _In_ ULONG BufferLength 466 | ) 467 | { 468 | HANDLE fileHandle; 469 | DWORD driverLocLen = 0; 470 | 471 | // 472 | // Get the current directory. 473 | // 474 | 475 | driverLocLen = GetCurrentDirectory(BufferLength, 476 | DriverLocation 477 | ); 478 | 479 | if (driverLocLen == 0) { 480 | 481 | printf("GetCurrentDirectory failed! Error = %d \n", GetLastError()); 482 | 483 | return FALSE; 484 | } 485 | 486 | // 487 | // Setup path name to driver file. 488 | // 489 | if (FAILED( StringCbCat(DriverLocation, BufferLength, "\\"DRIVER_NAME".sys") )) { 490 | return FALSE; 491 | } 492 | 493 | // 494 | // Insure driver file is in the specified directory. 495 | // 496 | 497 | if ((fileHandle = CreateFile(DriverLocation, 498 | GENERIC_READ, 499 | 0, 500 | NULL, 501 | OPEN_EXISTING, 502 | FILE_ATTRIBUTE_NORMAL, 503 | NULL 504 | )) == INVALID_HANDLE_VALUE) { 505 | 506 | 507 | printf("%s.sys is not loaded.\n", DRIVER_NAME); 508 | 509 | // 510 | // Indicate failure. 511 | // 512 | 513 | return FALSE; 514 | } 515 | 516 | // 517 | // Close open file handle. 518 | // 519 | 520 | if (fileHandle) { 521 | 522 | CloseHandle(fileHandle); 523 | } 524 | 525 | // 526 | // Indicate success. 527 | // 528 | 529 | return TRUE; 530 | 531 | 532 | } // SetupDriverName 533 | 534 | 535 | 536 | -------------------------------------------------------------------------------- /Message Tracing/wdm/event.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "public.h" 4 | #include "event.h" 5 | 6 | 7 | // ===================================================================== 8 | 9 | // Message buffer structure 10 | typedef struct _BUFFER_HEADER { 11 | UINT32 OpeationNumber; // Operation ID to user-mode 12 | UINT32 BufferLength; // The actual length 13 | BOOLEAN Valid; // Determine whether the buffer was valid to send or not 14 | } BUFFER_HEADER, * PBUFFER_HEADER; 15 | 16 | // Core-specific buffers 17 | typedef struct _CORE_BUFFER_INFORMATION { 18 | 19 | UINT32 CoreIndex; // Index of the core 20 | 21 | PNOTIFY_RECORD NotifyRecored; // The record of the thread in IRP Pending state 22 | 23 | UINT64 BufferStartAddress; // Start address of the buffer 24 | UINT64 BufferEndAddress; // End address of the buffer 25 | 26 | KSPIN_LOCK BufferLock; // SpinLock to protect access to the queue 27 | 28 | UINT32 CurrentIndexToSend; // Current buffer index to send to user-mode 29 | UINT32 CurrentIndexToWrite; // Current buffer index to write new messages 30 | 31 | } CORE_BUFFER_INFORMATION, * PCORE_BUFFER_INFORMATION; 32 | 33 | 34 | 35 | // Global Variable for buffer on all cores 36 | CORE_BUFFER_INFORMATION* CoreBufferInformation; 37 | 38 | // Illustrator 39 | /* 40 | A core buffer is like this , it's divided into MaximumPacketsCapacity chucks, 41 | each chunk has PacketChunkSize + sizeof(BUFFER_HEADER) size 42 | 43 | _________________________ 44 | | BUFFER_HEADER | 45 | |_________________________| 46 | | | 47 | | BODY | 48 | | (Buffer) | 49 | | size = PacketChunkSize | 50 | | | 51 | |_________________________| 52 | | BUFFER_HEADER | 53 | |_________________________| 54 | | | 55 | | BODY | 56 | | (Buffer) | 57 | | size = PacketChunkSize | 58 | | | 59 | |_________________________| 60 | | | 61 | | | 62 | | | 63 | | | 64 | | . | 65 | | . | 66 | | . | 67 | | | 68 | | | 69 | | | 70 | | | 71 | |_________________________| 72 | | BUFFER_HEADER | 73 | |_________________________| 74 | | | 75 | | BODY | 76 | | (Buffer) | 77 | | size = PacketChunkSize | 78 | | | 79 | |_________________________| 80 | 81 | */ 82 | 83 | 84 | //////////////////////////////////// Methods \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ 85 | 86 | BOOLEAN SendBuffer(UINT32 OperationCode, PVOID Buffer, UINT32 BufferLength, UINT32 CoreIndex) 87 | { 88 | KIRQL OldIRQL; 89 | 90 | if (BufferLength > PacketChunkSize) 91 | { 92 | // We can't save this huge buffer 93 | return FALSE; 94 | } 95 | // Acquire the lock 96 | KeAcquireSpinLock(&CoreBufferInformation[CoreIndex].BufferLock, &OldIRQL); 97 | 98 | // check if the buffer is filled to it's maximum index or not 99 | if (CoreBufferInformation[CoreIndex].CurrentIndexToWrite > MaximumPacketsCapacity - 1) 100 | { 101 | // start from the begining 102 | CoreBufferInformation[CoreIndex].CurrentIndexToWrite = 0; 103 | } 104 | 105 | // Compute the start of the buffer header 106 | BUFFER_HEADER* Header = (BUFFER_HEADER*)((UINT64)CoreBufferInformation[CoreIndex].BufferStartAddress + (CoreBufferInformation[CoreIndex].CurrentIndexToWrite * (PacketChunkSize + sizeof(BUFFER_HEADER)))); 107 | 108 | // Set the header 109 | Header->OpeationNumber = OperationCode; 110 | Header->BufferLength = BufferLength; 111 | Header->Valid = TRUE; 112 | 113 | /* Now it's time to fill the buffer */ 114 | 115 | // compute the saving index 116 | PVOID SavingBuffer = ((UINT64)CoreBufferInformation[CoreIndex].BufferStartAddress + (CoreBufferInformation[CoreIndex].CurrentIndexToWrite * (PacketChunkSize + sizeof(BUFFER_HEADER))) + sizeof(BUFFER_HEADER)); 117 | 118 | // copy the buffer 119 | RtlCopyBytes(SavingBuffer, Buffer, BufferLength); 120 | 121 | // Increment the next index to write 122 | CoreBufferInformation[CoreIndex].CurrentIndexToWrite = CoreBufferInformation[CoreIndex].CurrentIndexToWrite + 1; 123 | 124 | // check if there is any thread in IRP Pending state, so we can complete their request 125 | if (CoreBufferInformation[CoreIndex].NotifyRecored != NULL) 126 | { 127 | /* there is some threads that needs to be completed */ 128 | 129 | // Insert dpc to queue 130 | KeInsertQueueDpc(&CoreBufferInformation[CoreIndex].NotifyRecored->Dpc, CoreBufferInformation[CoreIndex].NotifyRecored, NULL); 131 | } 132 | 133 | // Release the lock 134 | KeReleaseSpinLock(&CoreBufferInformation[CoreIndex].BufferLock, OldIRQL); 135 | } 136 | 137 | /* return of this function shows whether the read was successfull or not (e.g FALSE shows there's no new buffer available.)*/ 138 | BOOLEAN ReadBuffer(UINT32 CoreIndex, PVOID BufferToSaveMessage, UINT32* ReturnedLength) { 139 | KIRQL OldIRQL; 140 | 141 | // Acquire the lock 142 | KeAcquireSpinLock(&CoreBufferInformation[CoreIndex].BufferLock, &OldIRQL); 143 | 144 | // Compute the current buffer to read 145 | BUFFER_HEADER* Header = (BUFFER_HEADER*)((UINT64)CoreBufferInformation[CoreIndex].BufferStartAddress + (CoreBufferInformation[CoreIndex].CurrentIndexToSend * (PacketChunkSize + sizeof(BUFFER_HEADER)))); 146 | 147 | if (!Header->Valid) 148 | { 149 | // there is nothing to send 150 | return FALSE; 151 | } 152 | 153 | /* If we reached here, means that there is sth to send */ 154 | 155 | // First copy the header 156 | RtlCopyBytes(BufferToSaveMessage, &Header->OpeationNumber, sizeof(UINT32)); 157 | 158 | // Second, save the buffer contents 159 | PVOID SendingBuffer = ((UINT64)CoreBufferInformation[CoreIndex].BufferStartAddress + (CoreBufferInformation[CoreIndex].CurrentIndexToSend * (PacketChunkSize + sizeof(BUFFER_HEADER))) + sizeof(BUFFER_HEADER)); 160 | PVOID SavingAddress = ((UINT64)BufferToSaveMessage + sizeof(UINT32)); // Because we want to pass the header of usermode header 161 | RtlCopyBytes(SavingAddress, SendingBuffer, Header->BufferLength); 162 | 163 | // Finally, set the current index to invalid as we sent it 164 | Header->Valid = FALSE; 165 | 166 | // Set the length to show as the ReturnedByted in usermode ioctl funtion + size of header 167 | *ReturnedLength = Header->BufferLength + sizeof(UINT32); 168 | 169 | 170 | // Last step is to clear the current buffer (we can't do it once when CurrentIndexToSend is zero because 171 | // there might be multiple messages on the start of the queue that didn't read yet) 172 | // we don't free the header 173 | RtlZeroMemory(SendingBuffer, Header->BufferLength); 174 | 175 | // Check to see whether we passed the index or not 176 | if (CoreBufferInformation[CoreIndex].CurrentIndexToSend > MaximumPacketsCapacity - 2) 177 | { 178 | CoreBufferInformation[CoreIndex].CurrentIndexToSend = 0; 179 | } 180 | else 181 | { 182 | // Increment the next index to read 183 | CoreBufferInformation[CoreIndex].CurrentIndexToSend = CoreBufferInformation[CoreIndex].CurrentIndexToSend + 1; 184 | } 185 | 186 | // check if there is any NotifyRecored available so we can free it 187 | if (CoreBufferInformation[CoreIndex].NotifyRecored != NULL) 188 | { 189 | // set notify routine to null 190 | CoreBufferInformation[CoreIndex].NotifyRecored = NULL; 191 | } 192 | // Release the lock 193 | KeReleaseSpinLock(&CoreBufferInformation[CoreIndex].BufferLock, OldIRQL); 194 | 195 | } 196 | 197 | /* return of this function shows whether the read was successfull or not (e.g FALSE shows there's no new buffer available.)*/ 198 | BOOLEAN CheckForNewMessage(UINT32 CoreIndex) { 199 | KIRQL OldIRQL; 200 | 201 | // Compute the current buffer to read 202 | BUFFER_HEADER* Header = (BUFFER_HEADER*)((UINT64)CoreBufferInformation[CoreIndex].BufferStartAddress + (CoreBufferInformation[CoreIndex].CurrentIndexToSend * (PacketChunkSize + sizeof(BUFFER_HEADER)))); 203 | 204 | if (!Header->Valid) 205 | { 206 | // there is nothing to send 207 | return FALSE; 208 | } 209 | 210 | /* If we reached here, means that there is sth to send */ 211 | return TRUE; 212 | } 213 | 214 | // Send string messages and tracing for logging and monitoring 215 | BOOLEAN SendMessageToQueue(UINT32 OperationCode, UINT32 CoreIndex, const char* Fmt, ...) 216 | { 217 | NTSTATUS Status = STATUS_SUCCESS; 218 | va_list ArgList; 219 | size_t WrittenSize; 220 | char LogMessage[PacketChunkSize]; 221 | 222 | // It's actually not necessary to use -1 but because user-mode code might assume a null-terminated buffer so 223 | // it's better to use - 1 224 | va_start(ArgList, Fmt); 225 | Status = RtlStringCchVPrintfA(LogMessage, PacketChunkSize - 1, Fmt, ArgList); 226 | va_end(ArgList); 227 | 228 | RtlStringCchLengthA(LogMessage, PacketChunkSize - 1, &WrittenSize); 229 | 230 | 231 | if (LogMessage[0] == '\0') { 232 | 233 | // nothing to write 234 | DbgBreakPoint(); 235 | return FALSE; 236 | } 237 | 238 | if (Status == STATUS_SUCCESS) 239 | { 240 | return SendBuffer(OperationCode, LogMessage, WrittenSize, CoreIndex); 241 | } 242 | 243 | return FALSE; 244 | } 245 | // ===================================================================== 246 | 247 | #ifdef ALLOC_PRAGMA 248 | #pragma alloc_text (INIT, DriverEntry) 249 | #pragma alloc_text (PAGE, EventCreate) 250 | #pragma alloc_text (PAGE, EventClose) 251 | #pragma alloc_text (PAGE, EventUnload) 252 | #endif 253 | 254 | _Use_decl_annotations_ NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) 255 | { 256 | PDEVICE_OBJECT DeviceObject; 257 | UNICODE_STRING NtDeviceName; 258 | UNICODE_STRING SymbolicLinkName; 259 | NTSTATUS Status; 260 | 261 | UNREFERENCED_PARAMETER(RegistryPath); 262 | 263 | // Opt-in to using non-executable pool memory on Windows 8 and later. 264 | // https://msdn.microsoft.com/en-us/library/windows/hardware/hh920402(v=vs.85).aspx 265 | ExInitializeDriverRuntime(DrvRtPoolNxOptIn); 266 | 267 | // Create the device object 268 | RtlInitUnicodeString(&NtDeviceName, NTDEVICE_NAME_STRING); 269 | 270 | Status = IoCreateDevice(DriverObject, // DriverObject 271 | 0, // DeviceExtensionSize 272 | &NtDeviceName, // DeviceName 273 | FILE_DEVICE_UNKNOWN, // DeviceType 274 | FILE_DEVICE_SECURE_OPEN, // DeviceCharacteristics 275 | FALSE, // Not Exclusive 276 | &DeviceObject // DeviceObject 277 | ); 278 | 279 | if (!NT_SUCCESS(Status)) { 280 | DebugPrint(("\tIoCreateDevice returned 0x%x\n", Status)); 281 | return(Status); 282 | } 283 | 284 | // Set up dispatch entry points for the driver. 285 | DriverObject->MajorFunction[IRP_MJ_CREATE] = EventCreate; 286 | DriverObject->MajorFunction[IRP_MJ_CLOSE] = EventClose; 287 | DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = EventDispatchIoControl; 288 | DriverObject->DriverUnload = EventUnload; 289 | 290 | // Create a symbolic link for userapp to interact with the driver. 291 | RtlInitUnicodeString(&SymbolicLinkName, SYMBOLIC_NAME_STRING); 292 | Status = IoCreateSymbolicLink(&SymbolicLinkName, &NtDeviceName); 293 | 294 | if (!NT_SUCCESS(Status)) { 295 | IoDeleteDevice(DeviceObject); 296 | DebugPrint(("\tIoCreateSymbolicLink returned 0x%x\n", Status)); 297 | return(Status); 298 | } 299 | 300 | // Establish user-buffer access method. 301 | DeviceObject->Flags |= DO_BUFFERED_IO; 302 | 303 | ASSERT(NT_SUCCESS(Status)); 304 | return Status; 305 | } 306 | 307 | _Use_decl_annotations_ VOID EventUnload(PDRIVER_OBJECT DriverObject) 308 | { 309 | 310 | PDEVICE_OBJECT deviceObject; 311 | UNICODE_STRING symbolicLinkName; 312 | 313 | deviceObject = DriverObject->DeviceObject; 314 | 315 | // Delete the user-mode symbolic link and deviceobjct. 316 | RtlInitUnicodeString(&symbolicLinkName, SYMBOLIC_NAME_STRING); 317 | IoDeleteSymbolicLink(&symbolicLinkName); 318 | IoDeleteDevice(deviceObject); 319 | } 320 | 321 | _Use_decl_annotations_ NTSTATUS EventCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp) 322 | { 323 | NTSTATUS Status; 324 | int CoreCount; 325 | 326 | Status = STATUS_SUCCESS; 327 | PAGED_CODE(); 328 | 329 | CoreCount = KeQueryActiveProcessorCount(0); 330 | // Initialize buffers for trace message and data messages 331 | CoreBufferInformation = ExAllocatePoolWithTag(NonPagedPool, sizeof(CORE_BUFFER_INFORMATION)* CoreCount, TAG); 332 | 333 | if (!CoreBufferInformation) 334 | { 335 | Status = STATUS_INSUFFICIENT_RESOURCES; 336 | goto End; 337 | } 338 | 339 | // Zeroing the memory 340 | RtlSecureZeroMemory(CoreBufferInformation, sizeof(CORE_BUFFER_INFORMATION) * CoreCount); 341 | 342 | // Allocate buffer for messages and initialize the core buffer information 343 | for (int i = 0; i < CoreCount; i++) 344 | { 345 | // set the core index 346 | CoreBufferInformation[i].CoreIndex = i; 347 | 348 | // initialize the lock 349 | KeInitializeSpinLock(&CoreBufferInformation[i].BufferLock); 350 | 351 | // allocate the buffer 352 | CoreBufferInformation[i].BufferStartAddress = ExAllocatePoolWithTag(NonPagedPool, BufferSize, TAG); 353 | 354 | if (!CoreBufferInformation[i].BufferStartAddress) 355 | { 356 | Status = STATUS_INSUFFICIENT_RESOURCES; 357 | goto End; 358 | } 359 | 360 | // Zeroing the buffer 361 | RtlSecureZeroMemory(CoreBufferInformation[i].BufferStartAddress, BufferSize); 362 | 363 | // Set the end address 364 | CoreBufferInformation[i].BufferEndAddress = (UINT64)CoreBufferInformation[i].BufferStartAddress + BufferSize; 365 | 366 | } 367 | 368 | End : 369 | Irp->IoStatus.Status = STATUS_SUCCESS; 370 | Irp->IoStatus.Information = 0; 371 | IoCompleteRequest(Irp, IO_NO_INCREMENT); 372 | return STATUS_SUCCESS; 373 | 374 | } 375 | 376 | _Use_decl_annotations_ NTSTATUS EventClose(PDEVICE_OBJECT DeviceObject, PIRP Irp) 377 | { 378 | int CoreCount; 379 | 380 | // Deallocate every buffers 381 | CoreCount = KeQueryActiveProcessorCount(0); 382 | 383 | // de-allocate buffer for messages and initialize the core buffer information 384 | for (int i = 0; i < CoreCount; i++) 385 | { 386 | // Free each core-specific buffers 387 | ExFreePoolWithTag(CoreBufferInformation[i].BufferStartAddress, TAG); 388 | } 389 | 390 | // de-allocate buffers for trace message and data messages 391 | ExFreePoolWithTag(CoreBufferInformation, TAG); 392 | 393 | Irp->IoStatus.Status = STATUS_SUCCESS; 394 | Irp->IoStatus.Information = 0; 395 | IoCompleteRequest(Irp, IO_NO_INCREMENT); 396 | return STATUS_SUCCESS; 397 | 398 | } 399 | int counter = 0; 400 | _Use_decl_annotations_ NTSTATUS EventDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) 401 | { 402 | counter++; 403 | 404 | PIO_STACK_LOCATION IrpStack; 405 | PREGISTER_EVENT RegisterEvent; 406 | NTSTATUS Status; 407 | 408 | IrpStack = IoGetCurrentIrpStackLocation(Irp); 409 | 410 | switch (IrpStack->Parameters.DeviceIoControl.IoControlCode) 411 | { 412 | case IOCTL_REGISTER_EVENT: 413 | 414 | // First validate the parameters. 415 | if (IrpStack->Parameters.DeviceIoControl.InputBufferLength < SIZEOF_REGISTER_EVENT || Irp->AssociatedIrp.SystemBuffer == NULL) { 416 | Status = STATUS_INVALID_PARAMETER; 417 | break; 418 | } 419 | 420 | RegisterEvent = (PREGISTER_EVENT)Irp->AssociatedIrp.SystemBuffer; 421 | 422 | switch (RegisterEvent->Type) { 423 | case IRP_BASED: 424 | // change the following line 425 | SendMessageToQueue(0x85, 0, "Sina's answer is %s [%d] and %s - + 0x%x tttuuii", "Hello", counter, "Second Hello",0x1234); 426 | // end changes 427 | Status = RegisterIrpBasedNotification(DeviceObject, Irp); 428 | break; 429 | case EVENT_BASED: 430 | Status = RegisterEventBasedNotification(DeviceObject, Irp); 431 | break; 432 | default: 433 | ASSERTMSG("\tUnknow notification type from user-mode\n", FALSE); 434 | Status = STATUS_INVALID_PARAMETER; 435 | break; 436 | } 437 | break; 438 | 439 | default: 440 | ASSERT(FALSE); // should never hit this 441 | Status = STATUS_NOT_IMPLEMENTED; 442 | break; 443 | } 444 | 445 | if (Status != STATUS_PENDING) { 446 | Irp->IoStatus.Status = Status; 447 | Irp->IoStatus.Information = 0; 448 | IoCompleteRequest(Irp, IO_NO_INCREMENT); 449 | } 450 | 451 | return Status; 452 | } 453 | 454 | _Use_decl_annotations_ VOID NotifyUsermodeCallback(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2) 455 | { 456 | PNOTIFY_RECORD NotifyRecord; 457 | PIRP Irp; 458 | 459 | UNREFERENCED_PARAMETER(Dpc); 460 | UNREFERENCED_PARAMETER(SystemArgument1); 461 | UNREFERENCED_PARAMETER(SystemArgument2); 462 | 463 | NotifyRecord = DeferredContext; 464 | 465 | ASSERT(NotifyRecord != NULL); // can't be NULL 466 | _Analysis_assume_(NotifyRecord != NULL); 467 | 468 | switch (NotifyRecord->Type) 469 | { 470 | 471 | case IRP_BASED: 472 | Irp = NotifyRecord->Message.PendingIrp; 473 | if (Irp != NULL) { 474 | 475 | PCHAR OutBuff; // pointer to output buffer 476 | ULONG InBuffLength; // Input buffer length 477 | ULONG OutBuffLength; // Output buffer length 478 | PIO_STACK_LOCATION IrpSp; 479 | 480 | IrpSp = IoGetCurrentIrpStackLocation(Irp); 481 | InBuffLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength; 482 | OutBuffLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength; 483 | 484 | if (!InBuffLength || !OutBuffLength) 485 | { 486 | Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; 487 | IoCompleteRequest(Irp, IO_NO_INCREMENT); 488 | break; 489 | } 490 | 491 | // Check again that SystemBuffer is not null 492 | if (!Irp->AssociatedIrp.SystemBuffer) 493 | { 494 | // Buffer is invalid 495 | return; 496 | } 497 | 498 | OutBuff = Irp->AssociatedIrp.SystemBuffer; 499 | 500 | UINT32 Length = 0; 501 | 502 | // Read Buffer might be empty (nothing to send) 503 | if (!ReadBuffer(0, OutBuff, &Length)) 504 | { 505 | // we have to return here as there is nothing to send here 506 | return; 507 | } 508 | 509 | Irp->IoStatus.Information = Length; 510 | 511 | 512 | Irp->IoStatus.Status = STATUS_SUCCESS; 513 | IoCompleteRequest(Irp, IO_NO_INCREMENT); 514 | } 515 | break; 516 | 517 | case EVENT_BASED: 518 | 519 | // Signal the Event created in user-mode. 520 | KeSetEvent(NotifyRecord->Message.Event, 0, FALSE); 521 | 522 | // Dereference the object as we are done with it. 523 | ObDereferenceObject(NotifyRecord->Message.Event); 524 | 525 | break; 526 | 527 | default: 528 | ASSERT(FALSE); 529 | break; 530 | } 531 | 532 | if (NotifyRecord != NULL) { 533 | ExFreePoolWithTag(NotifyRecord, TAG); 534 | } 535 | } 536 | 537 | _Use_decl_annotations_ NTSTATUS RegisterIrpBasedNotification(PDEVICE_OBJECT DeviceObject, PIRP Irp) 538 | { 539 | PNOTIFY_RECORD NotifyRecord; 540 | PIO_STACK_LOCATION IrpStack; 541 | KIRQL OOldIrql; 542 | PREGISTER_EVENT RegisterEvent; 543 | 544 | // check if current core has another thread with pending IRP, if no then put the current thread to pending 545 | // otherwise return and complete thread with STATUS_SUCCESS as there is another thread waiting for message 546 | 547 | //int GetCurrentCoreIndex = KeGetCurrentProcessorNumberEx(0); 548 | int GetCurrentCoreIndex = 0; 549 | 550 | if (CoreBufferInformation[GetCurrentCoreIndex].NotifyRecored == NULL) 551 | { 552 | IrpStack = IoGetCurrentIrpStackLocation(Irp); 553 | RegisterEvent = (PREGISTER_EVENT)Irp->AssociatedIrp.SystemBuffer; 554 | 555 | // Allocate a record and save all the event context. 556 | NotifyRecord = ExAllocatePoolWithQuotaTag(NonPagedPool, sizeof(NOTIFY_RECORD), TAG); 557 | 558 | if (NULL == NotifyRecord) { 559 | return STATUS_INSUFFICIENT_RESOURCES; 560 | } 561 | 562 | NotifyRecord->Type = IRP_BASED; 563 | NotifyRecord->Message.PendingIrp = Irp; 564 | 565 | KeInitializeDpc(&NotifyRecord->Dpc, // Dpc 566 | NotifyUsermodeCallback, // DeferredRoutine 567 | NotifyRecord // DeferredContext 568 | ); 569 | 570 | IoMarkIrpPending(Irp); 571 | 572 | 573 | // Set the notify routine to the global structure 574 | CoreBufferInformation[GetCurrentCoreIndex].NotifyRecored = NotifyRecord; 575 | 576 | // check for new message 577 | if (CheckForNewMessage(GetCurrentCoreIndex)) 578 | { 579 | // Insert dpc to queue 580 | KeInsertQueueDpc(&NotifyRecord->Dpc, NotifyRecord, NULL); 581 | } 582 | 583 | // We will return pending as we have marked the IRP pending. 584 | return STATUS_PENDING; 585 | } 586 | else 587 | { 588 | return STATUS_SUCCESS; 589 | } 590 | } 591 | 592 | _Use_decl_annotations_ NTSTATUS RegisterEventBasedNotification(PDEVICE_OBJECT DeviceObject, PIRP Irp) 593 | { 594 | PNOTIFY_RECORD NotifyRecord; 595 | NTSTATUS Status; 596 | PIO_STACK_LOCATION IrpStack; 597 | PREGISTER_EVENT RegisterEvent; 598 | KIRQL OldIrql; 599 | 600 | IrpStack = IoGetCurrentIrpStackLocation(Irp); 601 | RegisterEvent = (PREGISTER_EVENT)Irp->AssociatedIrp.SystemBuffer; 602 | 603 | // Allocate a record and save all the event context. 604 | NotifyRecord = ExAllocatePoolWithQuotaTag(NonPagedPool, sizeof(NOTIFY_RECORD), TAG); 605 | 606 | if (NULL == NotifyRecord) { 607 | return STATUS_INSUFFICIENT_RESOURCES; 608 | } 609 | 610 | NotifyRecord->Type = EVENT_BASED; 611 | 612 | KeInitializeDpc(&NotifyRecord->Dpc, // Dpc 613 | NotifyUsermodeCallback, // DeferredRoutine 614 | NotifyRecord // DeferredContext 615 | ); 616 | 617 | // Get the object pointer from the handle. Note we must be in the context of the process that created the handle. 618 | Status = ObReferenceObjectByHandle(RegisterEvent->hEvent, 619 | SYNCHRONIZE | EVENT_MODIFY_STATE, 620 | *ExEventObjectType, 621 | Irp->RequestorMode, 622 | &NotifyRecord->Message.Event, 623 | NULL 624 | ); 625 | 626 | if (!NT_SUCCESS(Status)) { 627 | 628 | DebugPrint(("\tUnable to reference User-Mode Event object, Error = 0x%x\n", Status)); 629 | ExFreePoolWithTag(NotifyRecord, TAG); 630 | return Status; 631 | } 632 | 633 | // Insert dpc to the queue 634 | KeInsertQueueDpc(&NotifyRecord->Dpc, NotifyRecord, NULL); 635 | 636 | return STATUS_SUCCESS; 637 | } 638 | --------------------------------------------------------------------------------