├── .gitattributes ├── .gitignore ├── Chapter02 ├── Chapter02.sln └── Sample │ ├── Sample.cpp │ ├── Sample.vcxproj │ └── Sample.vcxproj.filters ├── Chapter03 ├── Beep │ ├── Beep.cpp │ ├── Beep.vcxproj │ └── Beep.vcxproj.filters └── Chapter03.sln ├── Chapter04 ├── Boost │ ├── Boost.cpp │ ├── Boost.vcxproj │ └── Boost.vcxproj.filters ├── Booster │ ├── Booster.cpp │ ├── Booster.vcxproj │ ├── Booster.vcxproj.filters │ └── BoosterCommon.h └── Chapter04.sln ├── Chapter05 ├── Boost │ ├── Boost.cpp │ ├── Boost.vcxproj │ └── Boost.vcxproj.filters ├── Booster │ ├── Booster.cpp │ ├── Booster.vcxproj │ ├── Booster.vcxproj.filters │ └── BoosterCommon.h ├── Booster2 │ ├── Booster2.cpp │ ├── Booster2.h │ ├── Booster2.vcxproj │ ├── Booster2.vcxproj.filters │ ├── BoosterCommon.h │ └── Logging.cpp └── Chapter05.sln ├── Chapter07 ├── Chapter07.sln ├── Zero │ ├── Zero.cpp │ ├── Zero.vcxproj │ ├── Zero.vcxproj.filters │ ├── ZeroCommon.h │ ├── pch.cpp │ └── pch.h └── ZeroTest │ ├── ZeroTest.cpp │ ├── ZeroTest.vcxproj │ ├── ZeroTest.vcxproj.filters │ ├── pch.cpp │ └── pch.h ├── Chapter08 ├── Chapter08.sln ├── EnumProc │ ├── EnumProc.cpp │ ├── EnumProc.vcxproj │ └── EnumProc.vcxproj.filters ├── KMelody │ ├── FastMutex.cpp │ ├── FastMutex.h │ ├── KMelody.cpp │ ├── KMelody.h │ ├── KMelody.vcxproj │ ├── KMelody.vcxproj.filters │ ├── Locker.h │ ├── MelodyPublic.h │ ├── Memory.cpp │ ├── Memory.h │ ├── PlaybackState.cpp │ ├── PlaybackState.h │ ├── pch.cpp │ └── pch.h ├── Melody │ ├── Melody.cpp │ ├── Melody.vcxproj │ └── Melody.vcxproj.filters └── Multi │ ├── Memory.cpp │ ├── Memory.h │ ├── Multi.cpp │ ├── Multi.h │ ├── Multi.vcxproj │ ├── Multi.vcxproj.filters │ ├── MultiCommon.h │ ├── pch.cpp │ └── pch.h ├── Chapter09 ├── Chapter09.sln ├── Detector │ ├── Detector.cpp │ ├── Detector.vcxproj │ └── Detector.vcxproj.filters ├── KDetector │ ├── DetectorPublic.h │ ├── ExecutiveResource.cpp │ ├── ExecutiveResource.h │ ├── FastMutex.cpp │ ├── FastMutex.h │ ├── KDetector.cpp │ ├── KDetector.h │ ├── KDetector.vcxproj │ ├── KDetector.vcxproj.filters │ ├── Locker.h │ ├── LookasideList.h │ ├── pch.cpp │ └── pch.h ├── SysMon │ ├── FastMutex.cpp │ ├── FastMutex.h │ ├── Globals.cpp │ ├── Globals.h │ ├── Locker.h │ ├── SysMon.cpp │ ├── SysMon.h │ ├── SysMon.vcxproj │ ├── SysMon.vcxproj.filters │ ├── SysMonPublic.h │ ├── pch.cpp │ └── pch.h └── SysMonClient │ ├── SysMonClient.cpp │ ├── SysMonClient.vcxproj │ └── SysMonClient.vcxproj.filters ├── Chapter10 ├── Chapter10.sln ├── KProtect │ ├── ExecutiveResource.cpp │ ├── ExecutiveResource.h │ ├── FastMutex.cpp │ ├── FastMutex.h │ ├── KProtect.vcxproj │ ├── KProtect.vcxproj.filters │ ├── Locker.h │ ├── Protector.cpp │ ├── Protector.h │ ├── ProtectorPublic.h │ ├── pch.cpp │ └── pch.h ├── Protect │ ├── Protect.cpp │ ├── Protect.vcxproj │ └── Protect.vcxproj.filters ├── SysMon │ ├── FastMutex.cpp │ ├── FastMutex.h │ ├── Globals.cpp │ ├── Globals.h │ ├── Locker.h │ ├── SysMon.cpp │ ├── SysMon.h │ ├── SysMon.vcxproj │ ├── SysMon.vcxproj.filters │ ├── SysMonPublic.h │ ├── pch.cpp │ └── pch.h └── SysMonClient │ ├── SysMonClient.cpp │ ├── SysMonClient.vcxproj │ └── SysMonClient.vcxproj.filters ├── Chapter11 ├── Callbacks │ ├── Callbacks.cpp │ ├── Callbacks.inf │ ├── Callbacks.vcxproj │ └── Callbacks.vcxproj.filters ├── Chapter11.sln ├── Tables │ ├── FastMutex.cpp │ ├── FastMutex.h │ ├── Locker.h │ ├── Processes.cpp │ ├── Tables.cpp │ ├── Tables.h │ ├── Tables.inf │ ├── Tables.vcxproj │ ├── Tables.vcxproj.filters │ ├── TablesPublic.h │ ├── pch.cpp │ └── pch.h ├── TablesTest │ ├── TablesTest.cpp │ ├── TablesTest.vcxproj │ └── TablesTest.vcxproj.filters ├── Timers │ ├── Timers.cpp │ ├── Timers.vcxproj │ ├── Timers.vcxproj.filters │ └── TimersPublic.h └── TimersTest │ ├── TimersTest.cpp │ ├── TimersTest.vcxproj │ └── TimersTest.vcxproj.filters ├── Chapter12 ├── BackupMon │ ├── BackupMon.cpp │ ├── BackupMon.vcxproj │ ├── BackupMon.vcxproj.filters │ └── BackupMon.vcxproj.user ├── Chapter12.sln ├── DelProtect │ ├── DelProtect.cpp │ ├── DelProtect.vcxproj │ └── DelProtect.vcxproj.filters ├── DelTest │ ├── DelTest.cpp │ ├── DelTest.vcxproj │ └── DelTest.vcxproj.filters ├── Hide │ ├── Hide.cpp │ ├── Hide.vcxproj │ └── Hide.vcxproj.filters ├── KBackup │ ├── Driver.cpp │ ├── Driver.h │ ├── KBackup.vcxproj │ ├── KBackup.vcxproj.filters │ ├── MiniFilter.cpp │ ├── pch.cpp │ └── pch.h ├── KBackup2 │ ├── BackupCommon.h │ ├── Driver.cpp │ ├── Driver.h │ ├── KBackup2.vcxproj │ ├── KBackup2.vcxproj.filters │ ├── MiniFilter.cpp │ ├── pch.cpp │ └── pch.h ├── KDelprotect │ ├── Driver.cpp │ ├── Driver.h │ ├── ExecutiveResource.cpp │ ├── ExecutiveResource.h │ ├── Locker.h │ ├── MiniFilter.cpp │ ├── MiniFilter.h │ ├── kdelprotect.vcxproj │ ├── kdelprotect.vcxproj.filters │ ├── kdelprotectPublic.h │ ├── pch.cpp │ └── pch.h ├── KHide │ ├── Driver.cpp │ ├── Driver.h │ ├── HidePublic.h │ ├── KHide.vcxproj │ ├── KHide.vcxproj.filters │ ├── MiniFilter.cpp │ ├── MiniFilter.h │ ├── pch.cpp │ └── pch.h ├── Restore │ ├── Restore.cpp │ ├── Restore.vcxproj │ └── Restore.vcxproj.filters └── Streams │ ├── Streams.cpp │ ├── Streams.vcxproj │ └── Streams.vcxproj.filters ├── Chapter13 ├── BlockProcess │ ├── BlockProcess.cpp │ ├── BlockProcess.vcxproj │ ├── BlockProcess.vcxproj.filters │ ├── pch.cpp │ └── pch.h ├── Chapter13.sln ├── ProcessNetFilter │ ├── EResource.cpp │ ├── EResource.h │ ├── Globals.cpp │ ├── Globals.h │ ├── Locker.h │ ├── Main.cpp │ ├── Main.h │ ├── Memory.cpp │ ├── Memory.h │ ├── ProcNetFilterPublic.h │ ├── ProcessNetFilter.vcxproj │ ├── ProcessNetFilter.vcxproj.filters │ ├── SpinLock.cpp │ ├── SpinLock.h │ ├── Vector.h │ ├── pch.cpp │ └── pch.h └── wfpfilters │ ├── wfpfilters.cpp │ ├── wfpfilters.vcxproj │ └── wfpfilters.vcxproj.filters ├── Chapter14 ├── Boost │ ├── Boost.cpp │ ├── Boost.vcxproj │ └── Boost.vcxproj.filters ├── Booster │ ├── Booster.cpp │ ├── Booster.inf │ ├── Booster.vcxproj │ ├── Booster.vcxproj.filters │ └── BoosterCommon.h ├── Booster2 │ ├── Booster.cpp │ ├── Booster2.inf │ ├── Booster2.vcxproj │ ├── Booster2.vcxproj.filters │ └── BoosterCommon.h └── Chapter14.sln ├── Chapter15 ├── Chapter15.sln ├── DevMon │ ├── DevMon.cpp │ ├── DevMon.vcxproj │ ├── DevMon.vcxproj.filters │ ├── pch.cpp │ └── pch.h └── KDevMon │ ├── DevMonManager.cpp │ ├── DevMonManager.h │ ├── ExecutiveResource.cpp │ ├── ExecutiveResource.h │ ├── FastMutex.cpp │ ├── FastMutex.h │ ├── KDevMon.cpp │ ├── KDevMon.h │ ├── KDevMon.inf │ ├── KDevMon.vcxproj │ ├── KDevMon.vcxproj.filters │ ├── KDevMonCommon.h │ ├── Locker.h │ ├── pch.cpp │ └── pch.h ├── LICENSE ├── README.md ├── Tools └── dbgkflt.exe └── ktl ├── ktl.sln ├── ktl ├── BasicString.h ├── EResource.cpp ├── EResource.h ├── FastMutex.cpp ├── FastMutex.h ├── FilterFileNameInformation.cpp ├── FilterFileNameInformation.h ├── KernelHandle.cpp ├── KernelHandle.h ├── LinkedList.cpp ├── LinkedList.h ├── Locker.h ├── LookasideList.h ├── Memory.cpp ├── Memory.h ├── Mutex.cpp ├── Mutex.h ├── SpinLock.cpp ├── SpinLock.h ├── Vector.h ├── ktl.cpp ├── ktl.h ├── ktl.vcxproj ├── ktl.vcxproj.filters ├── pch.cpp ├── pch.h └── std.h └── ktl_test ├── Main.cpp ├── ktl_test.vcxproj └── ktl_test.vcxproj.filters /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /Chapter02/Chapter02.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.31702.278 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Sample", "Sample\Sample.vcxproj", "{DEE31B70-3D13-4C7C-9705-31AE555A8211}" 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 | {DEE31B70-3D13-4C7C-9705-31AE555A8211}.Debug|ARM.ActiveCfg = Debug|ARM 21 | {DEE31B70-3D13-4C7C-9705-31AE555A8211}.Debug|ARM.Build.0 = Debug|ARM 22 | {DEE31B70-3D13-4C7C-9705-31AE555A8211}.Debug|ARM.Deploy.0 = Debug|ARM 23 | {DEE31B70-3D13-4C7C-9705-31AE555A8211}.Debug|ARM64.ActiveCfg = Debug|ARM64 24 | {DEE31B70-3D13-4C7C-9705-31AE555A8211}.Debug|ARM64.Build.0 = Debug|ARM64 25 | {DEE31B70-3D13-4C7C-9705-31AE555A8211}.Debug|ARM64.Deploy.0 = Debug|ARM64 26 | {DEE31B70-3D13-4C7C-9705-31AE555A8211}.Debug|x64.ActiveCfg = Debug|x64 27 | {DEE31B70-3D13-4C7C-9705-31AE555A8211}.Debug|x64.Build.0 = Debug|x64 28 | {DEE31B70-3D13-4C7C-9705-31AE555A8211}.Debug|x64.Deploy.0 = Debug|x64 29 | {DEE31B70-3D13-4C7C-9705-31AE555A8211}.Debug|x86.ActiveCfg = Debug|Win32 30 | {DEE31B70-3D13-4C7C-9705-31AE555A8211}.Debug|x86.Build.0 = Debug|Win32 31 | {DEE31B70-3D13-4C7C-9705-31AE555A8211}.Debug|x86.Deploy.0 = Debug|Win32 32 | {DEE31B70-3D13-4C7C-9705-31AE555A8211}.Release|ARM.ActiveCfg = Release|ARM 33 | {DEE31B70-3D13-4C7C-9705-31AE555A8211}.Release|ARM.Build.0 = Release|ARM 34 | {DEE31B70-3D13-4C7C-9705-31AE555A8211}.Release|ARM.Deploy.0 = Release|ARM 35 | {DEE31B70-3D13-4C7C-9705-31AE555A8211}.Release|ARM64.ActiveCfg = Release|ARM64 36 | {DEE31B70-3D13-4C7C-9705-31AE555A8211}.Release|ARM64.Build.0 = Release|ARM64 37 | {DEE31B70-3D13-4C7C-9705-31AE555A8211}.Release|ARM64.Deploy.0 = Release|ARM64 38 | {DEE31B70-3D13-4C7C-9705-31AE555A8211}.Release|x64.ActiveCfg = Release|x64 39 | {DEE31B70-3D13-4C7C-9705-31AE555A8211}.Release|x64.Build.0 = Release|x64 40 | {DEE31B70-3D13-4C7C-9705-31AE555A8211}.Release|x64.Deploy.0 = Release|x64 41 | {DEE31B70-3D13-4C7C-9705-31AE555A8211}.Release|x86.ActiveCfg = Release|Win32 42 | {DEE31B70-3D13-4C7C-9705-31AE555A8211}.Release|x86.Build.0 = Release|Win32 43 | {DEE31B70-3D13-4C7C-9705-31AE555A8211}.Release|x86.Deploy.0 = Release|Win32 44 | EndGlobalSection 45 | GlobalSection(SolutionProperties) = preSolution 46 | HideSolutionNode = FALSE 47 | EndGlobalSection 48 | GlobalSection(ExtensibilityGlobals) = postSolution 49 | SolutionGuid = {26EF3C64-AF0E-4CD8-B49A-22CB2978E050} 50 | EndGlobalSection 51 | EndGlobal 52 | -------------------------------------------------------------------------------- /Chapter02/Sample/Sample.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define DRIVER_TAG 'dcba' 4 | 5 | UNICODE_STRING g_RegistryPath; 6 | 7 | void SampleUnload(_In_ PDRIVER_OBJECT DriverObject) { 8 | UNREFERENCED_PARAMETER(DriverObject); 9 | 10 | ExFreePool(g_RegistryPath.Buffer); 11 | KdPrint(("Sample driver Unload called\n")); 12 | } 13 | 14 | extern "C" NTSTATUS 15 | DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath) { 16 | g_RegistryPath.Buffer = (WCHAR*)ExAllocatePoolWithTag(PagedPool, RegistryPath->Length, DRIVER_TAG); 17 | 18 | if (g_RegistryPath.Buffer == nullptr) { 19 | KdPrint(("Failed to allocate memory\n")); 20 | return STATUS_INSUFFICIENT_RESOURCES; 21 | } 22 | 23 | g_RegistryPath.MaximumLength = RegistryPath->Length; 24 | RtlCopyUnicodeString(&g_RegistryPath, (PCUNICODE_STRING)RegistryPath); 25 | KdPrint(("original registry path: %wZ\n", RegistryPath)); 26 | KdPrint(("Copied registry path: %wZ\n", &g_RegistryPath)); 27 | 28 | DriverObject->DriverUnload = SampleUnload; 29 | 30 | RTL_OSVERSIONINFOW info = { sizeof(info) }; 31 | RtlGetVersion(&info); 32 | KdPrint(("Windows Version: %d.%d.%d\n", 33 | info.dwMajorVersion, info.dwMinorVersion, info.dwBuildNumber)); 34 | 35 | KdPrint(("Sample driver initialized successfully\n")); 36 | 37 | return STATUS_SUCCESS; 38 | } 39 | -------------------------------------------------------------------------------- /Chapter02/Sample/Sample.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 | Source Files 24 | 25 | 26 | -------------------------------------------------------------------------------- /Chapter03/Beep/Beep.cpp: -------------------------------------------------------------------------------- 1 | // Beep.cpp : This file contains the 'main' function. Program execution begins and ends there. 2 | // 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #pragma comment(lib, "ntdll") 10 | 11 | int main(int argc, const char* argv[]) { 12 | printf("beep [ ]\n"); 13 | int freq = 800, duration = 1000; 14 | if (argc > 2) { 15 | freq = atoi(argv[1]); 16 | duration = atoi(argv[2]); 17 | } 18 | 19 | HANDLE hFile; 20 | OBJECT_ATTRIBUTES attr; 21 | UNICODE_STRING name; 22 | RtlInitUnicodeString(&name, DD_BEEP_DEVICE_NAME_U); 23 | InitializeObjectAttributes(&attr, &name, OBJ_CASE_INSENSITIVE, nullptr, nullptr); 24 | IO_STATUS_BLOCK ioStatus; 25 | auto status = ::NtOpenFile(&hFile, GENERIC_WRITE, &attr, &ioStatus, 0, 0); 26 | if (NT_SUCCESS(status)) { 27 | BEEP_SET_PARAMETERS params; 28 | params.Frequency = freq; 29 | params.Duration = duration; 30 | DWORD bytes; 31 | // 32 | // play the sound 33 | // 34 | printf("Playing freq: %u, duration: %u\n", freq, duration); 35 | ::DeviceIoControl(hFile, IOCTL_BEEP_SET, ¶ms, sizeof(params), nullptr, 0, &bytes, nullptr); 36 | 37 | // 38 | // the sound starts playing and the call returns immediately 39 | // Wait so that the app doesn't close 40 | // 41 | ::Sleep(duration); 42 | ::CloseHandle(hFile); 43 | } 44 | else { 45 | printf("Failed in NtOpenFile (status=0x%X)\n", status); 46 | } 47 | return 0; 48 | } 49 | 50 | -------------------------------------------------------------------------------- /Chapter03/Beep/Beep.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;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 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Chapter03/Chapter03.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.31702.278 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Beep", "Beep\Beep.vcxproj", "{DE978E75-8A81-4562-9CF0-F8EA09D1E74C}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {DE978E75-8A81-4562-9CF0-F8EA09D1E74C}.Debug|x64.ActiveCfg = Debug|x64 17 | {DE978E75-8A81-4562-9CF0-F8EA09D1E74C}.Debug|x64.Build.0 = Debug|x64 18 | {DE978E75-8A81-4562-9CF0-F8EA09D1E74C}.Debug|x86.ActiveCfg = Debug|Win32 19 | {DE978E75-8A81-4562-9CF0-F8EA09D1E74C}.Debug|x86.Build.0 = Debug|Win32 20 | {DE978E75-8A81-4562-9CF0-F8EA09D1E74C}.Release|x64.ActiveCfg = Release|x64 21 | {DE978E75-8A81-4562-9CF0-F8EA09D1E74C}.Release|x64.Build.0 = Release|x64 22 | {DE978E75-8A81-4562-9CF0-F8EA09D1E74C}.Release|x86.ActiveCfg = Release|Win32 23 | {DE978E75-8A81-4562-9CF0-F8EA09D1E74C}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {10D6CA16-63A3-48C8-AF90-D293305C8A50} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /Chapter04/Boost/Boost.cpp: -------------------------------------------------------------------------------- 1 | // Boost.cpp : This file contains the 'main' function. Program execution begins and ends there. 2 | // 3 | 4 | #include 5 | #include 6 | #include "..\Booster\BoosterCommon.h" 7 | 8 | int Error(const char* message) { 9 | printf("%s (error=%u)\n", message, GetLastError()); 10 | return 1; 11 | } 12 | 13 | int main(int argc, const char* argv[]) { 14 | if (argc < 3) { 15 | printf("Usage: boost \n"); 16 | return 0; 17 | } 18 | 19 | int tid = atoi(argv[1]); 20 | int priority = atoi(argv[2]); 21 | 22 | HANDLE hDevice = CreateFile(L"\\\\.\\Booster", GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, 0, nullptr); 23 | if (hDevice == INVALID_HANDLE_VALUE) 24 | return Error("Failed to open device"); 25 | 26 | ThreadData data; 27 | data.ThreadId = tid; 28 | data.Priority = priority; 29 | 30 | DWORD returned; 31 | BOOL success = WriteFile(hDevice, 32 | &data, sizeof(data), // buffer and length 33 | &returned, nullptr); 34 | if (!success) 35 | return Error("Priority change failed!"); 36 | 37 | printf("Priority change succeeded!\n"); 38 | 39 | CloseHandle(hDevice); 40 | 41 | return 0; 42 | } 43 | 44 | -------------------------------------------------------------------------------- /Chapter04/Boost/Boost.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;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 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Chapter04/Booster/Booster.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "BoosterCommon.h" 3 | 4 | NTSTATUS BoosterCreateClose(PDEVICE_OBJECT DeviceObject, PIRP Irp); 5 | NTSTATUS BoosterWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp); 6 | void BoosterUnload(PDRIVER_OBJECT DriverObject); 7 | 8 | extern "C" NTSTATUS 9 | DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING /*RegistryPath*/) { 10 | KdPrint(("Boster: DriverEntry\n")); 11 | 12 | DriverObject->DriverUnload = BoosterUnload; 13 | 14 | DriverObject->MajorFunction[IRP_MJ_CREATE] = BoosterCreateClose; 15 | DriverObject->MajorFunction[IRP_MJ_CLOSE] = BoosterCreateClose; 16 | DriverObject->MajorFunction[IRP_MJ_WRITE] = BoosterWrite; 17 | 18 | UNICODE_STRING devName = RTL_CONSTANT_STRING(L"\\Device\\Booster"); 19 | 20 | PDEVICE_OBJECT DeviceObject; 21 | NTSTATUS status = IoCreateDevice( 22 | DriverObject, // our driver object 23 | 0, // no need for extra bytes 24 | &devName, // the device name 25 | FILE_DEVICE_UNKNOWN, // device type 26 | 0, // characteristics flags 27 | FALSE, // not exclusive 28 | &DeviceObject); // the resulting pointer 29 | if (!NT_SUCCESS(status)) { 30 | KdPrint(("Failed to create device object (0x%08X)\n", status)); 31 | return status; 32 | } 33 | 34 | UNICODE_STRING symLink = RTL_CONSTANT_STRING(L"\\??\\Booster"); 35 | status = IoCreateSymbolicLink(&symLink, &devName); 36 | if (!NT_SUCCESS(status)) { 37 | KdPrint(("Failed to create symbolic link (0x%08X)\n", status)); 38 | IoDeleteDevice(DeviceObject); // important! 39 | return status; 40 | } 41 | 42 | return STATUS_SUCCESS; 43 | } 44 | 45 | void BoosterUnload(_In_ PDRIVER_OBJECT DriverObject) { 46 | KdPrint(("Boster: Driver unload\n")); 47 | 48 | UNICODE_STRING symLink = RTL_CONSTANT_STRING(L"\\??\\Booster"); 49 | // delete symbolic link 50 | IoDeleteSymbolicLink(&symLink); 51 | 52 | // delete device object 53 | IoDeleteDevice(DriverObject->DeviceObject); 54 | } 55 | 56 | NTSTATUS BoosterCreateClose(PDEVICE_OBJECT DeviceObject, PIRP Irp) { 57 | UNREFERENCED_PARAMETER(DeviceObject); 58 | 59 | Irp->IoStatus.Status = STATUS_SUCCESS; 60 | Irp->IoStatus.Information = 0; 61 | IoCompleteRequest(Irp, IO_NO_INCREMENT); 62 | return STATUS_SUCCESS; 63 | } 64 | 65 | NTSTATUS BoosterWrite(PDEVICE_OBJECT, PIRP Irp) { 66 | auto status = STATUS_SUCCESS; 67 | ULONG_PTR information = 0; 68 | 69 | auto irpSp = IoGetCurrentIrpStackLocation(Irp); 70 | do { 71 | if (irpSp->Parameters.Write.Length < sizeof(ThreadData)) { 72 | status = STATUS_BUFFER_TOO_SMALL; 73 | break; 74 | } 75 | auto data = static_cast(Irp->UserBuffer); 76 | if (data == nullptr || data->Priority < 1 || data->Priority > 31) { 77 | status = STATUS_INVALID_PARAMETER; 78 | break; 79 | } 80 | PETHREAD thread; 81 | status = PsLookupThreadByThreadId(ULongToHandle(data->ThreadId), &thread); 82 | if (!NT_SUCCESS(status)) { 83 | break; 84 | } 85 | auto oldPriority = KeSetPriorityThread(thread, data->Priority); 86 | KdPrint(("Priority change for thread %u from %d to %d succeeded!\n", 87 | data->ThreadId, oldPriority, data->Priority)); 88 | UNREFERENCED_PARAMETER(oldPriority); 89 | 90 | ObDereferenceObject(thread); 91 | information = sizeof(ThreadData); 92 | } while (false); 93 | 94 | Irp->IoStatus.Status = status; 95 | Irp->IoStatus.Information = information; 96 | IoCompleteRequest(Irp, IO_NO_INCREMENT); 97 | return status; 98 | } 99 | -------------------------------------------------------------------------------- /Chapter04/Booster/Booster.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 | Source Files 24 | 25 | 26 | 27 | 28 | Header Files 29 | 30 | 31 | -------------------------------------------------------------------------------- /Chapter04/Booster/BoosterCommon.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct ThreadData { 4 | ULONG ThreadId; 5 | int Priority; 6 | }; 7 | -------------------------------------------------------------------------------- /Chapter05/Boost/Boost.cpp: -------------------------------------------------------------------------------- 1 | // Boost.cpp : This file contains the 'main' function. Program execution begins and ends there. 2 | // 3 | 4 | #include 5 | #include 6 | #include "..\Booster\BoosterCommon.h" 7 | 8 | int Error(const char* message) { 9 | printf("%s (error=%u)\n", message, GetLastError()); 10 | return 1; 11 | } 12 | 13 | int main(int argc, const char* argv[]) { 14 | if (argc < 3) { 15 | printf("Usage: boost \n"); 16 | return 0; 17 | } 18 | 19 | int tid = atoi(argv[1]); 20 | int priority = atoi(argv[2]); 21 | 22 | HANDLE hDevice = CreateFile(L"\\\\.\\Booster", GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, 0, nullptr); 23 | if (hDevice == INVALID_HANDLE_VALUE) 24 | return Error("Failed to open device"); 25 | 26 | ThreadData data; 27 | data.ThreadId = tid; 28 | data.Priority = priority; 29 | 30 | DWORD returned; 31 | BOOL success = WriteFile(hDevice, 32 | &data, sizeof(data), // buffer and length 33 | &returned, nullptr); 34 | if (!success) 35 | return Error("Priority change failed!"); 36 | 37 | printf("Priority change succeeded!\n"); 38 | 39 | CloseHandle(hDevice); 40 | 41 | return 0; 42 | } 43 | 44 | -------------------------------------------------------------------------------- /Chapter05/Boost/Boost.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;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 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Chapter05/Booster/Booster.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 | Source Files 24 | 25 | 26 | 27 | 28 | Header Files 29 | 30 | 31 | -------------------------------------------------------------------------------- /Chapter05/Booster/BoosterCommon.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct ThreadData { 4 | ULONG ThreadId; 5 | int Priority; 6 | }; 7 | -------------------------------------------------------------------------------- /Chapter05/Booster2/Booster2.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | enum class LogLevel { 4 | Error = 0, 5 | Warning, 6 | Information, 7 | Debug, 8 | Verbose 9 | }; 10 | 11 | ULONG Log(LogLevel level, PCSTR format, ...); 12 | ULONG LogError(PCSTR format, ...); 13 | ULONG LogInfo(PCSTR format, ...); 14 | 15 | 16 | -------------------------------------------------------------------------------- /Chapter05/Booster2/Booster2.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 | Source Files 24 | 25 | 26 | Source Files 27 | 28 | 29 | 30 | 31 | Header Files 32 | 33 | 34 | Header Files 35 | 36 | 37 | -------------------------------------------------------------------------------- /Chapter05/Booster2/BoosterCommon.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct ThreadData { 4 | ULONG ThreadId; 5 | int Priority; 6 | }; 7 | -------------------------------------------------------------------------------- /Chapter05/Booster2/Logging.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "Booster2.h" 3 | #include 4 | 5 | ULONG Log(LogLevel level, PCSTR format, ...) { 6 | va_list list; 7 | va_start(list, format); 8 | return vDbgPrintExWithPrefix("Booster2", DPFLTR_IHVDRIVER_ID, static_cast(level), format, list); 9 | } 10 | 11 | ULONG LogInfo(PCSTR format, ...) { 12 | va_list list; 13 | va_start(list, format); 14 | return vDbgPrintEx(DPFLTR_IHVDRIVER_ID, static_cast(LogLevel::Information), format, list); 15 | } 16 | 17 | ULONG LogError(PCSTR format, ...) { 18 | va_list list; 19 | va_start(list, format); 20 | return vDbgPrintEx(DPFLTR_IHVDRIVER_ID, static_cast(LogLevel::Error), format, list); 21 | } 22 | -------------------------------------------------------------------------------- /Chapter07/Zero/Zero.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 | Source Files 24 | 25 | 26 | Source Files 27 | 28 | 29 | 30 | 31 | Header Files 32 | 33 | 34 | Header Files 35 | 36 | 37 | -------------------------------------------------------------------------------- /Chapter07/Zero/ZeroCommon.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define DEVICE_ZERO 0x8022 4 | 5 | #define IOCTL_ZERO_GET_STATS CTL_CODE(DEVICE_ZERO, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS) 6 | #define IOCTL_ZERO_CLEAR_STATS CTL_CODE(DEVICE_ZERO, 0x801, METHOD_NEITHER, FILE_ANY_ACCESS) 7 | 8 | struct ZeroStats { 9 | long long TotalRead; 10 | long long TotalWritten; 11 | }; 12 | -------------------------------------------------------------------------------- /Chapter07/Zero/pch.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | -------------------------------------------------------------------------------- /Chapter07/Zero/pch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | -------------------------------------------------------------------------------- /Chapter07/ZeroTest/ZeroTest.cpp: -------------------------------------------------------------------------------- 1 | // ZeroTest.cpp : This file contains the 'main' function. Program execution begins and ends there. 2 | // 3 | 4 | #include "pch.h" 5 | #include "..\Zero\ZeroCommon.h" 6 | 7 | int Error(const char* msg) { 8 | printf("%s: error=%d\n", msg, ::GetLastError()); 9 | return 1; 10 | } 11 | 12 | int main() { 13 | HANDLE hDevice = ::CreateFile(L"\\\\.\\Zero", GENERIC_READ | GENERIC_WRITE, 0, nullptr, 14 | OPEN_EXISTING, 0, nullptr); 15 | if (hDevice == INVALID_HANDLE_VALUE) { 16 | return Error("failed to open device"); 17 | } 18 | 19 | // test read 20 | printf("Test read\n"); 21 | BYTE buffer[64]; 22 | for (int i = 0; i < sizeof(buffer); ++i) 23 | buffer[i] = i + 1; 24 | 25 | DWORD bytes; 26 | BOOL ok = ReadFile(hDevice, buffer, sizeof(buffer), &bytes, nullptr); 27 | if (!ok) 28 | return Error("failed to read"); 29 | 30 | if (bytes != sizeof(buffer)) 31 | printf("Wrong number of bytes\n"); 32 | 33 | for (auto n : buffer) 34 | if (n != 0) { 35 | printf("Wrong data!\n"); 36 | break; 37 | } 38 | 39 | // test write 40 | printf("Test write\n"); 41 | BYTE buffer2[1024]; // contains junk 42 | 43 | ok = WriteFile(hDevice, buffer2, sizeof(buffer2), &bytes, nullptr); 44 | if (!ok) 45 | return Error("failed to write"); 46 | 47 | if (bytes != sizeof(buffer2)) 48 | printf("Wrong byte count\n"); 49 | 50 | ZeroStats stats; 51 | if (!DeviceIoControl(hDevice, IOCTL_ZERO_GET_STATS, nullptr, 0, &stats, sizeof(stats), &bytes, nullptr)) 52 | return Error("failed in DeviceIoControl"); 53 | 54 | printf("Total Read: %lld, Total Write: %lld\n", 55 | stats.TotalRead, stats.TotalWritten); 56 | 57 | CloseHandle(hDevice); 58 | } 59 | 60 | -------------------------------------------------------------------------------- /Chapter07/ZeroTest/ZeroTest.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;hh;hpp;hxx;hm;inl;inc;ipp;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 | 18 | 19 | Header Files 20 | 21 | 22 | 23 | 24 | Source Files 25 | 26 | 27 | Source Files 28 | 29 | 30 | -------------------------------------------------------------------------------- /Chapter07/ZeroTest/pch.cpp: -------------------------------------------------------------------------------- 1 | // pch.cpp: source file corresponding to pre-compiled header; necessary for compilation to succeed 2 | 3 | #include "pch.h" 4 | 5 | // In general, ignore this file, but keep it around if you are using pre-compiled headers. 6 | -------------------------------------------------------------------------------- /Chapter07/ZeroTest/pch.h: -------------------------------------------------------------------------------- 1 | // Tips for Getting Started: 2 | // 1. Use the Solution Explorer window to add/manage files 3 | // 2. Use the Team Explorer window to connect to source control 4 | // 3. Use the Output window to see build output and other messages 5 | // 4. Use the Error List window to view errors 6 | // 5. Go to Project > Add New Item to create new code files, or Project > Add Existing Item to add existing code files to the project 7 | // 6. In the future, to open this project again, go to File > Open > Project and select the .sln file 8 | 9 | #ifndef PCH_H 10 | #define PCH_H 11 | 12 | #include 13 | #include 14 | 15 | #endif //PCH_H 16 | -------------------------------------------------------------------------------- /Chapter08/EnumProc/EnumProc.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // copied from 4 | enum SYSTEM_INFORMATION_CLASS { 5 | SystemProcessInformation = 5, 6 | }; 7 | 8 | typedef struct _SYSTEM_PROCESS_INFORMATION { 9 | ULONG NextEntryOffset; 10 | ULONG NumberOfThreads; 11 | UCHAR Reserved1[48]; 12 | UNICODE_STRING ImageName; 13 | KPRIORITY BasePriority; 14 | HANDLE UniqueProcessId; 15 | PVOID Reserved2; 16 | ULONG HandleCount; 17 | ULONG SessionId; 18 | PVOID Reserved3; 19 | SIZE_T PeakVirtualSize; 20 | SIZE_T VirtualSize; 21 | ULONG Reserved4; 22 | SIZE_T PeakWorkingSetSize; 23 | SIZE_T WorkingSetSize; 24 | PVOID Reserved5; 25 | SIZE_T QuotaPagedPoolUsage; 26 | PVOID Reserved6; 27 | SIZE_T QuotaNonPagedPoolUsage; 28 | SIZE_T PagefileUsage; 29 | SIZE_T PeakPagefileUsage; 30 | SIZE_T PrivatePageCount; 31 | LARGE_INTEGER Reserved7[6]; 32 | } SYSTEM_PROCESS_INFORMATION, * PSYSTEM_PROCESS_INFORMATION; 33 | 34 | 35 | extern "C" NTSTATUS ZwQuerySystemInformation( 36 | SYSTEM_INFORMATION_CLASS info, 37 | PVOID buffer, 38 | ULONG size, 39 | PULONG len); 40 | 41 | 42 | void EnumProcesses() { 43 | ULONG size; 44 | ZwQuerySystemInformation(SystemProcessInformation, nullptr, 0, &size); 45 | size += 1 << 12; 46 | 47 | auto buffer = ExAllocatePool2(POOL_FLAG_PAGED, size, 'cprP'); 48 | if (!buffer) 49 | return; 50 | 51 | if (NT_SUCCESS(ZwQuerySystemInformation(SystemProcessInformation, buffer, size, nullptr))) { 52 | auto info = (SYSTEM_PROCESS_INFORMATION*)buffer; 53 | ULONG count = 0; 54 | for (;;) { 55 | DbgPrint("PID: %u Session: %u Handles: %u Threads: %u Image: %wZ\n", 56 | HandleToULong(info->UniqueProcessId), 57 | info->SessionId, info->HandleCount, 58 | info->NumberOfThreads, info->ImageName); 59 | count++; 60 | if (info->NextEntryOffset == 0) 61 | break; 62 | 63 | info = (SYSTEM_PROCESS_INFORMATION*)((PUCHAR)info + info->NextEntryOffset); 64 | } 65 | DbgPrint("Total Processes: %u\n", count); 66 | } 67 | ExFreePool(buffer); 68 | } 69 | 70 | extern "C" NTSTATUS 71 | DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) { 72 | UNREFERENCED_PARAMETER(DriverObject); 73 | UNREFERENCED_PARAMETER(RegistryPath); 74 | 75 | EnumProcesses(); 76 | return STATUS_UNSUCCESSFUL; 77 | } 78 | 79 | -------------------------------------------------------------------------------- /Chapter08/EnumProc/EnumProc.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 | Source Files 24 | 25 | 26 | -------------------------------------------------------------------------------- /Chapter08/KMelody/FastMutex.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "FastMutex.h" 3 | 4 | FastMutex::FastMutex() { 5 | ExInitializeFastMutex(&m_mutex); 6 | } 7 | 8 | void FastMutex::Lock() { 9 | ExAcquireFastMutex(&m_mutex); 10 | } 11 | 12 | void FastMutex::Unlock() { 13 | ExReleaseFastMutex(&m_mutex); 14 | } 15 | 16 | -------------------------------------------------------------------------------- /Chapter08/KMelody/FastMutex.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct FastMutex { 4 | FastMutex(); 5 | void Lock(); 6 | void Unlock(); 7 | 8 | private: 9 | FAST_MUTEX m_mutex; 10 | }; 11 | 12 | -------------------------------------------------------------------------------- /Chapter08/KMelody/KMelody.cpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "pch.h" 4 | #include "MelodyPublic.h" 5 | #include "PlaybackState.h" 6 | #include "KMelody.h" 7 | #include "Memory.h" 8 | 9 | void MelodyUnload(PDRIVER_OBJECT); 10 | NTSTATUS MelodyCreateClose(PDEVICE_OBJECT, PIRP); 11 | NTSTATUS MelodyDeviceControl(PDEVICE_OBJECT, PIRP); 12 | NTSTATUS CompleteRequest(PIRP Irp, NTSTATUS status = STATUS_SUCCESS, ULONG_PTR info = 0); 13 | 14 | PlaybackState* g_State; 15 | 16 | extern "C" NTSTATUS 17 | DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) { 18 | UNREFERENCED_PARAMETER(RegistryPath); 19 | 20 | g_State = new (POOL_FLAG_PAGED) PlaybackState; 21 | if (g_State == nullptr) 22 | return STATUS_INSUFFICIENT_RESOURCES; 23 | 24 | auto status = STATUS_SUCCESS; 25 | PDEVICE_OBJECT DeviceObject = nullptr; 26 | UNICODE_STRING symLink = RTL_CONSTANT_STRING(L"\\??\\KMelody"); 27 | 28 | do { 29 | UNICODE_STRING name = RTL_CONSTANT_STRING(L"\\Device\\KMelody"); 30 | status = IoCreateDevice(DriverObject, 0, &name, FILE_DEVICE_UNKNOWN, 0, FALSE, &DeviceObject); 31 | if (!NT_SUCCESS(status)) 32 | break; 33 | 34 | status = IoCreateSymbolicLink(&symLink, &name); 35 | if (!NT_SUCCESS(status)) 36 | break; 37 | 38 | } while (false); 39 | 40 | if (!NT_SUCCESS(status)) { 41 | KdPrint((DRIVER_PREFIX "Error (0x%08X)\n", status)); 42 | 43 | delete g_State; 44 | if (DeviceObject) 45 | IoDeleteDevice(DeviceObject); 46 | return status; 47 | } 48 | 49 | DriverObject->DriverUnload = MelodyUnload; 50 | DriverObject->MajorFunction[IRP_MJ_CREATE] = DriverObject->MajorFunction[IRP_MJ_CLOSE] = MelodyCreateClose; 51 | DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = MelodyDeviceControl; 52 | 53 | return status; 54 | } 55 | 56 | void MelodyUnload(PDRIVER_OBJECT DriverObject) { 57 | delete g_State; 58 | UNICODE_STRING symLink = RTL_CONSTANT_STRING(L"\\??\\KMelody"); 59 | IoDeleteSymbolicLink(&symLink); 60 | IoDeleteDevice(DriverObject->DeviceObject); 61 | } 62 | 63 | NTSTATUS MelodyCreateClose(PDEVICE_OBJECT DeviceObject, PIRP Irp) { 64 | auto status = STATUS_SUCCESS; 65 | if (IoGetCurrentIrpStackLocation(Irp)->MajorFunction == IRP_MJ_CREATE) { 66 | // 67 | // create the "playback" thread (if needed) 68 | // 69 | status = g_State->Start(DeviceObject); 70 | } 71 | else { 72 | g_State->Stop(); 73 | } 74 | return CompleteRequest(Irp, status); 75 | } 76 | 77 | NTSTATUS MelodyDeviceControl(PDEVICE_OBJECT, PIRP Irp) { 78 | auto irpSp = IoGetCurrentIrpStackLocation(Irp); 79 | auto& dic = irpSp->Parameters.DeviceIoControl; 80 | auto status = STATUS_INVALID_DEVICE_REQUEST; 81 | ULONG info = 0; 82 | 83 | switch (dic.IoControlCode) { 84 | case IOCTL_MELODY_PLAY: 85 | if (dic.InputBufferLength == 0 || dic.InputBufferLength % sizeof(Note) != 0) { 86 | status = STATUS_INVALID_BUFFER_SIZE; 87 | break; 88 | } 89 | auto data = (Note*)Irp->AssociatedIrp.SystemBuffer; 90 | if (data == nullptr) { 91 | status = STATUS_INVALID_PARAMETER; 92 | break; 93 | } 94 | 95 | status = g_State->AddNotes(data, dic.InputBufferLength / sizeof(Note)); 96 | if (!NT_SUCCESS(status)) 97 | break; 98 | info = dic.InputBufferLength; 99 | break; 100 | 101 | } 102 | return CompleteRequest(Irp, status, info); 103 | } 104 | 105 | NTSTATUS CompleteRequest(PIRP Irp, NTSTATUS status, ULONG_PTR info) { 106 | Irp->IoStatus.Status = status; 107 | Irp->IoStatus.Information = info; 108 | IoCompleteRequest(Irp, IO_NO_INCREMENT); 109 | return status; 110 | } 111 | 112 | -------------------------------------------------------------------------------- /Chapter08/KMelody/KMelody.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define DRIVER_TAG 'ydlm' 4 | #define DRIVER_PREFIX "Melody: " 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Chapter08/KMelody/KMelody.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 | Header Files 24 | 25 | 26 | Header Files 27 | 28 | 29 | Header Files 30 | 31 | 32 | Header Files 33 | 34 | 35 | Header Files 36 | 37 | 38 | Header Files 39 | 40 | 41 | 42 | 43 | Source Files 44 | 45 | 46 | Source Files 47 | 48 | 49 | Source Files 50 | 51 | 52 | Source Files 53 | 54 | 55 | Source Files 56 | 57 | 58 | -------------------------------------------------------------------------------- /Chapter08/KMelody/Locker.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | template 4 | struct Locker { 5 | Locker(TLock& lock) : m_lock(lock) { 6 | lock.Lock(); 7 | } 8 | ~Locker() { 9 | m_lock.Unlock(); 10 | } 11 | 12 | private: 13 | TLock& m_lock; 14 | }; 15 | -------------------------------------------------------------------------------- /Chapter08/KMelody/MelodyPublic.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define MELODY_SYMLINK L"\\??\\KMelody" 4 | 5 | struct Note { 6 | ULONG Frequency; 7 | ULONG Duration; 8 | ULONG Delay{ 0 }; 9 | ULONG Repeat{ 1 }; 10 | }; 11 | 12 | #define MELODY_DEVICE 0x8003 13 | 14 | #define IOCTL_MELODY_PLAY CTL_CODE(MELODY_DEVICE, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS) 15 | 16 | -------------------------------------------------------------------------------- /Chapter08/KMelody/Memory.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "KMelody.h" 3 | #include "Memory.h" 4 | 5 | void* __cdecl operator new(size_t size, POOL_FLAGS pool, ULONG tag) { 6 | void* p = ExAllocatePool2(pool, size, tag); 7 | return p; 8 | } 9 | 10 | void* __cdecl operator new(size_t size, POOL_FLAGS pool, EX_POOL_PRIORITY priority, ULONG tag) { 11 | POOL_EXTENDED_PARAMETER pp; 12 | pp.Priority = priority; 13 | pp.Type = PoolExtendedParameterPriority; 14 | return ExAllocatePool3(pool, size, tag, &pp, 1); 15 | } 16 | 17 | void __cdecl operator delete(void* p, size_t) { 18 | ExFreePool(p); 19 | } 20 | 21 | void __cdecl operator delete(void* p, size_t, std::align_val_t) { 22 | ExFreePool(p); 23 | } 24 | -------------------------------------------------------------------------------- /Chapter08/KMelody/Memory.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | void* __cdecl operator new(size_t size, POOL_FLAGS pool, ULONG tag = DRIVER_TAG); 4 | void* __cdecl operator new(size_t size, POOL_FLAGS pool, EX_POOL_PRIORITY priority, ULONG tag = DRIVER_TAG); 5 | void __cdecl operator delete(void* p, size_t); 6 | void __cdecl operator delete(void* p, size_t, std::align_val_t); 7 | -------------------------------------------------------------------------------- /Chapter08/KMelody/PlaybackState.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "FastMutex.h" 4 | 5 | struct Note; 6 | 7 | struct PlaybackState { 8 | PlaybackState(); 9 | ~PlaybackState(); 10 | 11 | NTSTATUS AddNotes(const Note* notes, ULONG count); 12 | NTSTATUS Start(PVOID IoObject); 13 | void Stop(); 14 | 15 | private: 16 | static void PlayMelody(PVOID context); 17 | void PlayMelody(); 18 | 19 | LIST_ENTRY m_head; 20 | FastMutex m_lock; 21 | PAGED_LOOKASIDE_LIST m_lookaside; 22 | KSEMAPHORE m_counter; 23 | KEVENT m_stopEvent; 24 | HANDLE m_hThread{ nullptr }; 25 | }; 26 | -------------------------------------------------------------------------------- /Chapter08/KMelody/pch.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | -------------------------------------------------------------------------------- /Chapter08/KMelody/pch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | -------------------------------------------------------------------------------- /Chapter08/Melody/Melody.cpp: -------------------------------------------------------------------------------- 1 | // Melody.cpp : This file contains the 'main' function. Program execution begins and ends there. 2 | // 3 | 4 | #include 5 | #include 6 | #include "..\KMelody\MelodyPublic.h" 7 | 8 | int Error(const char* msg, DWORD error = GetLastError()) { 9 | printf("%s (%u)\n", msg, error); 10 | return 1; 11 | } 12 | 13 | int main() { 14 | HANDLE hDevice = CreateFile(MELODY_SYMLINK, GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, 0, nullptr); 15 | if (hDevice == INVALID_HANDLE_VALUE) 16 | return Error("Failed to open device handle"); 17 | 18 | // 19 | // let's play some notes 20 | // 21 | Note notes[10]; 22 | for (int i = 0; i < _countof(notes); i++) { 23 | notes[i].Frequency = 400 + i * 30; 24 | notes[i].Duration = 500; 25 | } 26 | DWORD bytes; 27 | if (!DeviceIoControl(hDevice, IOCTL_MELODY_PLAY, notes, sizeof(notes), nullptr, 0, &bytes, nullptr)) 28 | return Error("Failed in DeviceIoControl"); 29 | 30 | for (int i = 0; i < _countof(notes); i++) { 31 | notes[i].Frequency = 1200 - i * 100; 32 | notes[i].Duration = 300; 33 | notes[i].Repeat = 2; 34 | notes[i].Delay = 300; 35 | } 36 | if (!DeviceIoControl(hDevice, IOCTL_MELODY_PLAY, notes, sizeof(notes), nullptr, 0, &bytes, nullptr)) 37 | return Error("Failed in DeviceIoControl"); 38 | 39 | CloseHandle(hDevice); 40 | return 0; 41 | } 42 | 43 | -------------------------------------------------------------------------------- /Chapter08/Melody/Melody.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;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 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Chapter08/Multi/Memory.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "Memory.h" 3 | 4 | void* __cdecl operator new(size_t size, POOL_TYPE pool, ULONG tag) { 5 | return ExAllocatePoolWithTag(pool, size, tag); 6 | } 7 | 8 | void __cdecl operator delete(void* p, size_t) { 9 | ::ExFreePool(p); 10 | } 11 | 12 | -------------------------------------------------------------------------------- /Chapter08/Multi/Memory.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Multi.h" 4 | 5 | void* __cdecl operator new(size_t size, POOL_TYPE pool, ULONG tag = DRIVER_TAG); 6 | void __cdecl operator delete(void* p, size_t); 7 | 8 | -------------------------------------------------------------------------------- /Chapter08/Multi/Multi.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "Memory.h" 3 | 4 | extern "C" NTSTATUS 5 | DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) { 6 | UNREFERENCED_PARAMETER(DriverObject); 7 | UNREFERENCED_PARAMETER(RegistryPath); 8 | 9 | 10 | return STATUS_SUCCESS; 11 | } 12 | 13 | -------------------------------------------------------------------------------- /Chapter08/Multi/Multi.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define DRIVER_TAG 'itlM' 4 | 5 | -------------------------------------------------------------------------------- /Chapter08/Multi/Multi.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 | Header Files 24 | 25 | 26 | Header Files 27 | 28 | 29 | Header Files 30 | 31 | 32 | Header Files 33 | 34 | 35 | 36 | 37 | Source Files 38 | 39 | 40 | Source Files 41 | 42 | 43 | Source Files 44 | 45 | 46 | -------------------------------------------------------------------------------- /Chapter08/Multi/MultiCommon.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define DEVICE_MULTI 0x8008 4 | 5 | #define IOCTL_MULTI_TEST_POOLS CTL_CODE(DEVICE_MULTI, 0x800, METHOD_NEITHER, FILE_ANY_ACCESS) 6 | -------------------------------------------------------------------------------- /Chapter08/Multi/pch.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | -------------------------------------------------------------------------------- /Chapter08/Multi/pch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | -------------------------------------------------------------------------------- /Chapter09/Detector/Detector.cpp: -------------------------------------------------------------------------------- 1 | // Detector.cpp : This file contains the 'main' function. Program execution begins and ends there. 2 | // 3 | 4 | #include 5 | #include 6 | #include "..\KDetector\DetectorPublic.h" 7 | 8 | int Error(const char* text) { 9 | printf("%s (%u)\n", text, GetLastError()); 10 | return 1; 11 | } 12 | 13 | void DisplayTime(const LARGE_INTEGER& time) { 14 | FILETIME local; 15 | FileTimeToLocalFileTime((FILETIME*)&time, &local); 16 | SYSTEMTIME st; 17 | FileTimeToSystemTime(&local, &st); 18 | printf("%02d:%02d:%02d.%03d: ", st.wHour, st.wMinute, st.wSecond, st.wMilliseconds); 19 | } 20 | 21 | void DisplayData(const RemoteThread* data, int count) { 22 | for (int i = 0; i < count; i++) { 23 | auto& rt = data[i]; 24 | DisplayTime(rt.Time); 25 | printf("Remote Thread from PID: %u TID: %u -> PID: %u TID: %u\n", 26 | rt.CreatorProcessId, rt.CreatorThreadId, rt.ProcessId, rt.ThreadId); 27 | } 28 | } 29 | 30 | int main() { 31 | HANDLE hDevice = CreateFile(L"\\\\.\\kdetector", GENERIC_READ, 0, nullptr, OPEN_EXISTING, 0, nullptr); 32 | if (hDevice == INVALID_HANDLE_VALUE) 33 | return Error("Error opening device"); 34 | 35 | RemoteThread rt[20]; 36 | 37 | for (;;) { 38 | DWORD bytes; 39 | if (!ReadFile(hDevice, rt, sizeof(rt), &bytes, nullptr)) 40 | return Error("Failed to read data"); 41 | 42 | DisplayData(rt, bytes / sizeof(RemoteThread)); 43 | Sleep(1000); 44 | } 45 | 46 | CloseHandle(hDevice); 47 | return 0; 48 | } 49 | 50 | -------------------------------------------------------------------------------- /Chapter09/Detector/Detector.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;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 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Chapter09/KDetector/DetectorPublic.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct RemoteThread { 4 | LARGE_INTEGER Time; 5 | ULONG CreatorProcessId; 6 | ULONG CreatorThreadId; 7 | ULONG ProcessId; 8 | ULONG ThreadId; 9 | }; 10 | -------------------------------------------------------------------------------- /Chapter09/KDetector/ExecutiveResource.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "ExecutiveResource.h" 3 | 4 | void ExecutiveResource::Init() { 5 | ExInitializeResourceLite(&m_res); 6 | } 7 | 8 | void ExecutiveResource::Delete() { 9 | ExDeleteResourceLite(&m_res); 10 | } 11 | 12 | void ExecutiveResource::Lock() { 13 | m_CritRegion = KeAreApcsDisabled(); 14 | if(m_CritRegion) 15 | ExAcquireResourceExclusiveLite(&m_res, TRUE); 16 | else 17 | ExEnterCriticalRegionAndAcquireResourceExclusive(&m_res); 18 | } 19 | 20 | void ExecutiveResource::Unlock() { 21 | if (m_CritRegion) 22 | ExReleaseResourceLite(&m_res); 23 | else 24 | ExReleaseResourceAndLeaveCriticalRegion(&m_res); 25 | } 26 | 27 | void ExecutiveResource::LockShared() { 28 | m_CritRegion = KeAreApcsDisabled(); 29 | if (m_CritRegion) 30 | ExAcquireResourceSharedLite(&m_res, TRUE); 31 | else 32 | ExEnterCriticalRegionAndAcquireResourceShared(&m_res); 33 | } 34 | 35 | void ExecutiveResource::UnlockShared() { 36 | Unlock(); 37 | } 38 | -------------------------------------------------------------------------------- /Chapter09/KDetector/ExecutiveResource.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct ExecutiveResource { 4 | void Init(); 5 | void Delete(); 6 | 7 | void Lock(); 8 | void Unlock(); 9 | 10 | void LockShared(); 11 | void UnlockShared(); 12 | 13 | private: 14 | ERESOURCE m_res; 15 | bool m_CritRegion; 16 | }; 17 | 18 | -------------------------------------------------------------------------------- /Chapter09/KDetector/FastMutex.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "FastMutex.h" 3 | 4 | 5 | void FastMutex::Init() { 6 | ExInitializeFastMutex(&m_mutex); 7 | } 8 | 9 | void FastMutex::Lock() { 10 | ExAcquireFastMutex(&m_mutex); 11 | } 12 | 13 | void FastMutex::Unlock() { 14 | ExReleaseFastMutex(&m_mutex); 15 | } 16 | -------------------------------------------------------------------------------- /Chapter09/KDetector/FastMutex.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class FastMutex { 4 | public: 5 | void Init(); 6 | 7 | void Lock(); 8 | void Unlock(); 9 | 10 | private: 11 | FAST_MUTEX m_mutex; 12 | }; 13 | 14 | -------------------------------------------------------------------------------- /Chapter09/KDetector/KDetector.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ExecutiveResource.h" 4 | #include "DetectorPublic.h" 5 | #include "LookasideList.h" 6 | #include "FastMutex.h" 7 | 8 | #define DRIVER_PREFIX "KDetector: " 9 | #define DRIVER_TAG 'tcdk' 10 | 11 | struct RemoteThreadItem { 12 | LIST_ENTRY Link; 13 | RemoteThread Remote; 14 | }; 15 | 16 | NTSTATUS CompleteRequest(PIRP Irp, NTSTATUS status = STATUS_SUCCESS, ULONG_PTR info = 0); 17 | bool AddNewProcess(HANDLE pid); 18 | bool RemoveProcess(HANDLE pid); 19 | bool FindProcess(HANDLE pid); 20 | 21 | const ULONG MaxProcesses = 32; 22 | 23 | ULONG NewProcesses[MaxProcesses]; 24 | ULONG NewProcessesCount; 25 | ExecutiveResource ProcessesLock; 26 | LIST_ENTRY RemoteThreadsHead; 27 | FastMutex RemoteThreadsLock; 28 | LookasideList Lookaside; 29 | -------------------------------------------------------------------------------- /Chapter09/KDetector/KDetector.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 | Source Files 24 | 25 | 26 | Source Files 27 | 28 | 29 | Source Files 30 | 31 | 32 | Source Files 33 | 34 | 35 | 36 | 37 | Header Files 38 | 39 | 40 | Header Files 41 | 42 | 43 | Header Files 44 | 45 | 46 | Header Files 47 | 48 | 49 | Header Files 50 | 51 | 52 | Header Files 53 | 54 | 55 | Header Files 56 | 57 | 58 | -------------------------------------------------------------------------------- /Chapter09/KDetector/Locker.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | template 4 | struct Locker { 5 | Locker(TLock& lock) : m_lock(lock) { 6 | lock.Lock(); 7 | } 8 | ~Locker() { 9 | m_lock.Unlock(); 10 | } 11 | 12 | private: 13 | TLock& m_lock; 14 | }; 15 | 16 | template 17 | struct SharedLocker { 18 | SharedLocker(TLock& lock) : m_lock(lock) { 19 | lock.LockShared(); 20 | } 21 | ~SharedLocker() { 22 | m_lock.UnlockShared(); 23 | } 24 | 25 | private: 26 | TLock& m_lock; 27 | }; 28 | 29 | -------------------------------------------------------------------------------- /Chapter09/KDetector/LookasideList.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | template 4 | struct LookasideList { 5 | NTSTATUS Init(POOL_TYPE pool, ULONG tag) { 6 | return ExInitializeLookasideListEx(&m_lookaside, nullptr, nullptr, pool, 0, sizeof(T), tag, 0); 7 | } 8 | 9 | void Delete() { 10 | ExDeleteLookasideListEx(&m_lookaside); 11 | } 12 | 13 | T* Alloc() { 14 | return (T*)ExAllocateFromLookasideListEx(&m_lookaside); 15 | } 16 | 17 | void Free(T* p) { 18 | ExFreeToLookasideListEx(&m_lookaside, p); 19 | } 20 | 21 | private: 22 | LOOKASIDE_LIST_EX m_lookaside; 23 | }; 24 | -------------------------------------------------------------------------------- /Chapter09/KDetector/pch.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | -------------------------------------------------------------------------------- /Chapter09/KDetector/pch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | -------------------------------------------------------------------------------- /Chapter09/SysMon/FastMutex.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "FastMutex.h" 3 | 4 | 5 | void FastMutex::Init() { 6 | ExInitializeFastMutex(&m_mutex); 7 | } 8 | 9 | void FastMutex::Lock() { 10 | ExAcquireFastMutex(&m_mutex); 11 | } 12 | 13 | void FastMutex::Unlock() { 14 | ExReleaseFastMutex(&m_mutex); 15 | } 16 | -------------------------------------------------------------------------------- /Chapter09/SysMon/FastMutex.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class FastMutex { 4 | public: 5 | void Init(); 6 | 7 | void Lock(); 8 | void Unlock(); 9 | 10 | private: 11 | FAST_MUTEX m_mutex; 12 | }; 13 | 14 | -------------------------------------------------------------------------------- /Chapter09/SysMon/Globals.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "Globals.h" 3 | #include "Locker.h" 4 | #include "SysMon.h" 5 | 6 | void Globals::Init(ULONG maxCount) { 7 | InitializeListHead(&m_ItemsHead); 8 | m_Lock.Init(); 9 | m_Count = 0; 10 | m_MaxCount = maxCount; 11 | } 12 | 13 | void Globals::AddItem(LIST_ENTRY* entry) { 14 | Locker locker(m_Lock); 15 | if (m_Count == m_MaxCount) { 16 | auto head = RemoveHeadList(&m_ItemsHead); 17 | ExFreePool(CONTAINING_RECORD(head, FullItem, Entry)); 18 | m_Count--; 19 | } 20 | 21 | InsertTailList(&m_ItemsHead, entry); 22 | m_Count++; 23 | } 24 | 25 | void Globals::AddHeadItem(LIST_ENTRY* entry) { 26 | Locker locker(m_Lock); 27 | InsertHeadList(&m_ItemsHead, entry); 28 | m_Count++; 29 | } 30 | 31 | LIST_ENTRY* Globals::RemoveItem() { 32 | Locker locker(m_Lock); 33 | auto item = RemoveHeadList(&m_ItemsHead); 34 | if (item == &m_ItemsHead) 35 | return nullptr; 36 | 37 | m_Count--; 38 | return item; 39 | } 40 | -------------------------------------------------------------------------------- /Chapter09/SysMon/Globals.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "FastMutex.h" 4 | 5 | struct Globals { 6 | void Init(ULONG maxItems); 7 | 8 | void AddItem(LIST_ENTRY* entry); 9 | void AddHeadItem(LIST_ENTRY* entry); 10 | LIST_ENTRY* RemoveItem(); 11 | 12 | private: 13 | LIST_ENTRY m_ItemsHead; 14 | ULONG m_Count; 15 | ULONG m_MaxCount; 16 | FastMutex m_Lock; 17 | }; 18 | 19 | -------------------------------------------------------------------------------- /Chapter09/SysMon/Locker.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | template 4 | struct Locker { 5 | Locker(TLock& lock) : m_Lock(lock) { 6 | lock.Lock(); 7 | } 8 | ~Locker() { 9 | m_Lock.Unlock(); 10 | } 11 | 12 | private: 13 | TLock& m_Lock; 14 | }; 15 | -------------------------------------------------------------------------------- /Chapter09/SysMon/SysMon.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "SysMonPublic.h" 4 | 5 | #define DRIVER_PREFIX "SysMon: " 6 | #define DRIVER_TAG 'nmys' 7 | 8 | template 9 | struct FullItem { 10 | LIST_ENTRY Entry; 11 | T Data; 12 | }; 13 | 14 | NTSTATUS CompleteRequest(PIRP Irp, NTSTATUS status = STATUS_SUCCESS, ULONG_PTR info = 0); 15 | -------------------------------------------------------------------------------- /Chapter09/SysMon/SysMon.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 | Source Files 24 | 25 | 26 | Source Files 27 | 28 | 29 | Source Files 30 | 31 | 32 | Source Files 33 | 34 | 35 | 36 | 37 | Header Files 38 | 39 | 40 | Header Files 41 | 42 | 43 | Header Files 44 | 45 | 46 | Header Files 47 | 48 | 49 | Header Files 50 | 51 | 52 | Header Files 53 | 54 | 55 | -------------------------------------------------------------------------------- /Chapter09/SysMon/SysMonPublic.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | enum class ItemType : short { 4 | None, 5 | ProcessCreate, 6 | ProcessExit, 7 | ThreadCreate, 8 | ThreadExit, 9 | ImageLoad 10 | }; 11 | 12 | struct ItemHeader { 13 | ItemType Type; 14 | USHORT Size; 15 | LARGE_INTEGER Time; 16 | }; 17 | 18 | struct ProcessExitInfo : ItemHeader { 19 | ULONG ProcessId; 20 | ULONG ExitCode; 21 | }; 22 | 23 | struct ProcessCreateInfo : ItemHeader { 24 | ULONG ProcessId; 25 | ULONG ParentProcessId; 26 | ULONG CreatingThreadId; 27 | ULONG CreatingProcessId; 28 | USHORT CommandLineLength; 29 | WCHAR CommandLine[1]; 30 | }; 31 | 32 | struct ThreadCreateInfo : ItemHeader { 33 | ULONG ThreadId; 34 | ULONG ProcessId; 35 | }; 36 | 37 | struct ThreadExitInfo : ThreadCreateInfo { 38 | ULONG ExitCode; 39 | }; 40 | 41 | const int MaxImageFileSize = 300; 42 | 43 | struct ImageLoadInfo : ItemHeader { 44 | ULONG ProcessId; 45 | ULONG ImageSize; 46 | ULONG64 LoadAddress; 47 | WCHAR ImageFileName[MaxImageFileSize + 1]; 48 | }; 49 | -------------------------------------------------------------------------------- /Chapter09/SysMon/pch.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | -------------------------------------------------------------------------------- /Chapter09/SysMon/pch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | -------------------------------------------------------------------------------- /Chapter09/SysMonClient/SysMonClient.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;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 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Chapter10/KProtect/ExecutiveResource.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "ExecutiveResource.h" 3 | 4 | void ExecutiveResource::Init() { 5 | ExInitializeResourceLite(&m_res); 6 | } 7 | 8 | void ExecutiveResource::Delete() { 9 | ExDeleteResourceLite(&m_res); 10 | } 11 | 12 | void ExecutiveResource::Lock() { 13 | m_CritRegion = KeAreApcsDisabled(); 14 | if(m_CritRegion) 15 | ExAcquireResourceExclusiveLite(&m_res, TRUE); 16 | else 17 | ExEnterCriticalRegionAndAcquireResourceExclusive(&m_res); 18 | } 19 | 20 | void ExecutiveResource::Unlock() { 21 | if (m_CritRegion) 22 | ExReleaseResourceLite(&m_res); 23 | else 24 | ExReleaseResourceAndLeaveCriticalRegion(&m_res); 25 | } 26 | 27 | void ExecutiveResource::LockShared() { 28 | m_CritRegion = KeAreApcsDisabled(); 29 | if (m_CritRegion) 30 | ExAcquireResourceSharedLite(&m_res, TRUE); 31 | else 32 | ExEnterCriticalRegionAndAcquireResourceShared(&m_res); 33 | } 34 | 35 | void ExecutiveResource::UnlockShared() { 36 | Unlock(); 37 | } 38 | -------------------------------------------------------------------------------- /Chapter10/KProtect/ExecutiveResource.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct ExecutiveResource { 4 | void Init(); 5 | void Delete(); 6 | 7 | void Lock(); 8 | void Unlock(); 9 | 10 | void LockShared(); 11 | void UnlockShared(); 12 | 13 | private: 14 | ERESOURCE m_res; 15 | bool m_CritRegion; 16 | }; 17 | 18 | -------------------------------------------------------------------------------- /Chapter10/KProtect/FastMutex.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "FastMutex.h" 3 | 4 | void FastMutex::Init() { 5 | ExInitializeFastMutex(&m_mutex); 6 | } 7 | 8 | void FastMutex::Lock() { 9 | ExAcquireFastMutex(&m_mutex); 10 | } 11 | 12 | void FastMutex::Unlock() { 13 | ExReleaseFastMutex(&m_mutex); 14 | } 15 | -------------------------------------------------------------------------------- /Chapter10/KProtect/FastMutex.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class FastMutex { 4 | public: 5 | void Init(); 6 | 7 | void Lock(); 8 | void Unlock(); 9 | 10 | private: 11 | FAST_MUTEX m_mutex; 12 | }; 13 | 14 | -------------------------------------------------------------------------------- /Chapter10/KProtect/KProtect.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 | Header Files 24 | 25 | 26 | Header Files 27 | 28 | 29 | Header Files 30 | 31 | 32 | Header Files 33 | 34 | 35 | Header Files 36 | 37 | 38 | 39 | 40 | Source Files 41 | 42 | 43 | Source Files 44 | 45 | 46 | Source Files 47 | 48 | 49 | Source Files 50 | 51 | 52 | -------------------------------------------------------------------------------- /Chapter10/KProtect/Locker.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | template 4 | struct Locker { 5 | Locker(TLock& lock) : m_lock(lock) { 6 | lock.Lock(); 7 | } 8 | ~Locker() { 9 | m_lock.Unlock(); 10 | } 11 | 12 | private: 13 | TLock& m_lock; 14 | }; 15 | 16 | template 17 | struct SharedLocker { 18 | SharedLocker(TLock& lock) : m_lock(lock) { 19 | lock.LockShared(); 20 | } 21 | ~SharedLocker() { 22 | m_lock.UnlockShared(); 23 | } 24 | 25 | private: 26 | TLock& m_lock; 27 | }; 28 | 29 | -------------------------------------------------------------------------------- /Chapter10/KProtect/Protector.h: -------------------------------------------------------------------------------- 1 | #define DRIVER_PREFIX "KProtect: " 2 | 3 | #include "ExecutiveResource.h" 4 | 5 | NTSTATUS CompleteRequest(PIRP Irp, NTSTATUS status = STATUS_SUCCESS, ULONG_PTR info = 0); 6 | 7 | #define PROCESS_TERMINATE 1 8 | 9 | const int MaxPids = 256; 10 | 11 | struct Globals { 12 | ULONG PidsCount; // currently protected process count 13 | ULONG Pids[MaxPids]; // protected PIDs 14 | ExecutiveResource Lock; 15 | PVOID RegHandle; 16 | 17 | void Init() { 18 | Lock.Init(); 19 | } 20 | 21 | void Term() { 22 | Lock.Delete(); 23 | } 24 | }; 25 | -------------------------------------------------------------------------------- /Chapter10/KProtect/ProtectorPublic.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define KPROTECT_DEVICE 0x8101 4 | 5 | #define IOCTL_PROTECT_ADD_PID CTL_CODE(KPROTECT_DEVICE, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS) 6 | #define IOCTL_PROTECT_REMOVE_PID CTL_CODE(KPROTECT_DEVICE, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS) 7 | #define IOCTL_PROTECT_REMOVE_ALL CTL_CODE(KPROTECT_DEVICE, 0x802, METHOD_NEITHER, FILE_ANY_ACCESS) 8 | -------------------------------------------------------------------------------- /Chapter10/KProtect/pch.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | -------------------------------------------------------------------------------- /Chapter10/KProtect/pch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | -------------------------------------------------------------------------------- /Chapter10/Protect/Protect.cpp: -------------------------------------------------------------------------------- 1 | // Protect.cpp : This file contains the 'main' function. Program execution begins and ends there. 2 | // 3 | 4 | #include 5 | #include 6 | #include 7 | #include "..\KProtect\ProtectorPublic.h" 8 | 9 | int Error(const char* msg) { 10 | printf("%s (Error: %u)\n", msg, GetLastError()); 11 | return 1; 12 | } 13 | 14 | int PrintUsage() { 15 | printf("Protect [add | remove | clear] [pid] ...\n"); 16 | return 0; 17 | } 18 | 19 | std::vector ParsePids(const char* buffer[], int count) { 20 | std::vector pids; 21 | for (int i = 0; i < count; i++) 22 | pids.push_back(atoi(buffer[i])); 23 | return pids; 24 | } 25 | 26 | int main(int argc, const char* argv[]) { 27 | if (argc < 2) 28 | return PrintUsage(); 29 | 30 | enum class Options { 31 | Unknown, 32 | Add, Remove, Clear 33 | }; 34 | Options option; 35 | if (_stricmp(argv[1], "add") == 0) 36 | option = Options::Add; 37 | else if (_stricmp(argv[1], "remove") == 0) 38 | option = Options::Remove; 39 | else if (_stricmp(argv[1], "clear") == 0) 40 | option = Options::Clear; 41 | else { 42 | printf("Unknown option.\n"); 43 | return PrintUsage(); 44 | } 45 | 46 | HANDLE hFile = CreateFile(L"\\\\.\\KProtect", GENERIC_WRITE | GENERIC_READ, 0, nullptr, OPEN_EXISTING, 0, nullptr); 47 | if (hFile == INVALID_HANDLE_VALUE) 48 | return Error("Failed to open device"); 49 | 50 | std::vector pids; 51 | BOOL success = FALSE; 52 | DWORD bytes; 53 | switch (option) { 54 | case Options::Add: 55 | pids = ParsePids(argv + 2, argc - 2); 56 | success = DeviceIoControl(hFile, IOCTL_PROTECT_ADD_PID, 57 | pids.data(), static_cast(pids.size()) * sizeof(DWORD), 58 | nullptr, 0, &bytes, nullptr); 59 | break; 60 | 61 | case Options::Remove: 62 | pids = ParsePids(argv + 2, argc - 2); 63 | success = ::DeviceIoControl(hFile, IOCTL_PROTECT_REMOVE_PID, 64 | pids.data(), static_cast(pids.size()) * sizeof(DWORD), 65 | nullptr, 0, &bytes, nullptr); 66 | break; 67 | 68 | case Options::Clear: 69 | success = ::DeviceIoControl(hFile, IOCTL_PROTECT_REMOVE_ALL, 70 | nullptr, 0, nullptr, 0, &bytes, nullptr); 71 | break; 72 | 73 | } 74 | 75 | if (!success) 76 | return Error("Failed in DeviceIoControl"); 77 | 78 | printf("Operation succeeded.\n"); 79 | 80 | CloseHandle(hFile); 81 | 82 | return 0; 83 | } 84 | 85 | -------------------------------------------------------------------------------- /Chapter10/Protect/Protect.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;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 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Chapter10/SysMon/FastMutex.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "FastMutex.h" 3 | 4 | 5 | void FastMutex::Init() { 6 | ExInitializeFastMutex(&m_mutex); 7 | } 8 | 9 | void FastMutex::Lock() { 10 | ExAcquireFastMutex(&m_mutex); 11 | } 12 | 13 | void FastMutex::Unlock() { 14 | ExReleaseFastMutex(&m_mutex); 15 | } 16 | -------------------------------------------------------------------------------- /Chapter10/SysMon/FastMutex.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class FastMutex { 4 | public: 5 | void Init(); 6 | 7 | void Lock(); 8 | void Unlock(); 9 | 10 | private: 11 | FAST_MUTEX m_mutex; 12 | }; 13 | 14 | -------------------------------------------------------------------------------- /Chapter10/SysMon/Globals.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "Globals.h" 3 | #include "Locker.h" 4 | #include "SysMon.h" 5 | 6 | void Globals::Init(ULONG maxCount) { 7 | InitializeListHead(&m_ItemsHead); 8 | m_Lock.Init(); 9 | m_Count = 0; 10 | m_MaxCount = maxCount; 11 | } 12 | 13 | void Globals::AddItem(LIST_ENTRY* entry) { 14 | Locker locker(m_Lock); 15 | if (m_Count == m_MaxCount) { 16 | auto head = RemoveHeadList(&m_ItemsHead); 17 | ExFreePool(CONTAINING_RECORD(head, FullItem, Entry)); 18 | m_Count--; 19 | } 20 | 21 | InsertTailList(&m_ItemsHead, entry); 22 | m_Count++; 23 | } 24 | 25 | void Globals::AddHeadItem(LIST_ENTRY* entry) { 26 | Locker locker(m_Lock); 27 | InsertHeadList(&m_ItemsHead, entry); 28 | m_Count++; 29 | } 30 | 31 | LIST_ENTRY* Globals::RemoveItem() { 32 | Locker locker(m_Lock); 33 | auto item = RemoveHeadList(&m_ItemsHead); 34 | if (item == &m_ItemsHead) 35 | return nullptr; 36 | 37 | m_Count--; 38 | return item; 39 | } 40 | -------------------------------------------------------------------------------- /Chapter10/SysMon/Globals.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "FastMutex.h" 4 | 5 | struct Globals { 6 | void Init(ULONG maxItems); 7 | 8 | void AddItem(LIST_ENTRY* entry); 9 | void AddHeadItem(LIST_ENTRY* entry); 10 | LIST_ENTRY* RemoveItem(); 11 | 12 | private: 13 | LIST_ENTRY m_ItemsHead; 14 | ULONG m_Count; 15 | ULONG m_MaxCount; 16 | FastMutex m_Lock; 17 | }; 18 | 19 | -------------------------------------------------------------------------------- /Chapter10/SysMon/Locker.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | template 4 | struct Locker { 5 | Locker(TLock& lock) : m_Lock(lock) { 6 | lock.Lock(); 7 | } 8 | ~Locker() { 9 | m_Lock.Unlock(); 10 | } 11 | 12 | private: 13 | TLock& m_Lock; 14 | }; 15 | -------------------------------------------------------------------------------- /Chapter10/SysMon/SysMon.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "SysMonPublic.h" 4 | 5 | #define DRIVER_PREFIX "SysMon: " 6 | #define DRIVER_TAG 'nmys' 7 | 8 | template 9 | struct FullItem { 10 | LIST_ENTRY Entry; 11 | T Data; 12 | }; 13 | 14 | NTSTATUS CompleteRequest(PIRP Irp, NTSTATUS status = STATUS_SUCCESS, ULONG_PTR info = 0); 15 | -------------------------------------------------------------------------------- /Chapter10/SysMon/SysMon.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 | Source Files 24 | 25 | 26 | Source Files 27 | 28 | 29 | Source Files 30 | 31 | 32 | Source Files 33 | 34 | 35 | 36 | 37 | Header Files 38 | 39 | 40 | Header Files 41 | 42 | 43 | Header Files 44 | 45 | 46 | Header Files 47 | 48 | 49 | Header Files 50 | 51 | 52 | Header Files 53 | 54 | 55 | -------------------------------------------------------------------------------- /Chapter10/SysMon/SysMonPublic.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | enum class ItemType : short { 4 | None, 5 | ProcessCreate, 6 | ProcessExit, 7 | ThreadCreate, 8 | ThreadExit, 9 | ImageLoad, 10 | RegistrySetValue, 11 | }; 12 | 13 | struct ItemHeader { 14 | ItemType Type; 15 | USHORT Size; 16 | LARGE_INTEGER Time; 17 | }; 18 | 19 | struct ProcessExitInfo : ItemHeader { 20 | ULONG ProcessId; 21 | ULONG ExitCode; 22 | }; 23 | 24 | struct ProcessCreateInfo : ItemHeader { 25 | ULONG ProcessId; 26 | ULONG ParentProcessId; 27 | ULONG CreatingThreadId; 28 | ULONG CreatingProcessId; 29 | USHORT CommandLineLength; 30 | WCHAR CommandLine[1]; 31 | }; 32 | 33 | struct ThreadCreateInfo : ItemHeader { 34 | ULONG ThreadId; 35 | ULONG ProcessId; 36 | }; 37 | 38 | struct ThreadExitInfo : ThreadCreateInfo { 39 | ULONG ExitCode; 40 | }; 41 | 42 | const int MaxImageFileSize = 300; 43 | 44 | struct ImageLoadInfo : ItemHeader { 45 | ULONG ProcessId; 46 | ULONG ImageSize; 47 | ULONG64 LoadAddress; 48 | WCHAR ImageFileName[MaxImageFileSize + 1]; 49 | }; 50 | 51 | struct RegistrySetValueInfo : ItemHeader { 52 | ULONG ProcessId; 53 | ULONG ThreadId; 54 | USHORT KeyNameOffset; 55 | USHORT ValueNameOffset; 56 | ULONG DataType; 57 | ULONG DataSize; 58 | USHORT DataOffset; 59 | USHORT ProvidedDataSize; 60 | }; 61 | -------------------------------------------------------------------------------- /Chapter10/SysMon/pch.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | -------------------------------------------------------------------------------- /Chapter10/SysMon/pch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | -------------------------------------------------------------------------------- /Chapter10/SysMonClient/SysMonClient.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;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 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Chapter11/Callbacks/Callbacks.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void SystemTimeChanged(PVOID context, PVOID arg1, PVOID arg2); 4 | void OnUnload(PDRIVER_OBJECT); 5 | 6 | PVOID g_RegCookie; 7 | 8 | extern "C" NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING) { 9 | OBJECT_ATTRIBUTES attr; 10 | UNICODE_STRING name = RTL_CONSTANT_STRING(L"\\Callback\\SetSystemTime"); 11 | InitializeObjectAttributes(&attr, &name, OBJ_CASE_INSENSITIVE, nullptr, nullptr); 12 | PCALLBACK_OBJECT callback; 13 | auto status = ExCreateCallback(&callback, &attr, FALSE, TRUE); 14 | if (!NT_SUCCESS(status)) { 15 | KdPrint(("Failed to create callback object (0x%X)\n", status)); 16 | return status; 17 | } 18 | 19 | g_RegCookie = ExRegisterCallback(callback, SystemTimeChanged, nullptr); 20 | if (g_RegCookie == nullptr) { 21 | ObDereferenceObject(callback); 22 | KdPrint(("Failed to register callback\n")); 23 | return STATUS_UNSUCCESSFUL; 24 | } 25 | // 26 | // callback object no longer needed 27 | // 28 | ObDereferenceObject(callback); 29 | 30 | DriverObject->DriverUnload = OnUnload; 31 | 32 | return STATUS_SUCCESS; 33 | } 34 | 35 | void SystemTimeChanged(PVOID context, PVOID arg1, PVOID arg2) { 36 | UNREFERENCED_PARAMETER(context); 37 | 38 | DbgPrint("System time changed 0x%p 0x%p!\n", arg1, arg2); 39 | } 40 | 41 | void OnUnload(PDRIVER_OBJECT) { 42 | ExUnregisterCallback(g_RegCookie); 43 | } 44 | -------------------------------------------------------------------------------- /Chapter11/Callbacks/Callbacks.inf: -------------------------------------------------------------------------------- 1 | ; 2 | ; Callbacks.inf 3 | ; 4 | 5 | [Version] 6 | Signature="$WINDOWS NT$" 7 | Class=System 8 | ClassGuid={4d36e97d-e325-11ce-bfc1-08002be10318} 9 | Provider=%ManufacturerName% 10 | DriverVer= 11 | CatalogFile=Callbacks.cat 12 | PnpLockdown=1 13 | 14 | ;This template is supported for OS version 17763 (Windows 10 version 1809) and after. 15 | ;For Windows OS prior to Windows 10 1809 set DefaultDestDir = 12 16 | [DestinationDirs] 17 | DefaultDestDir = 13 18 | 19 | 20 | [SourceDisksNames] 21 | 1 = %DiskName%,,,"" 22 | 23 | [SourceDisksFiles] 24 | 25 | 26 | [Manufacturer] 27 | %ManufacturerName%=Standard,NT$ARCH$ 28 | 29 | [Standard.NT$ARCH$] 30 | 31 | 32 | [Strings] 33 | ManufacturerName="" ;TODO: Replace with your manufacturer name 34 | DiskName="Callbacks Source Disk" 35 | -------------------------------------------------------------------------------- /Chapter11/Callbacks/Callbacks.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 | Source Files 24 | 25 | 26 | -------------------------------------------------------------------------------- /Chapter11/Tables/FastMutex.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "FastMutex.h" 3 | 4 | void FastMutex::Init() { 5 | ExInitializeFastMutex(&m_mutex); 6 | } 7 | 8 | void FastMutex::Lock() { 9 | ExAcquireFastMutex(&m_mutex); 10 | } 11 | 12 | void FastMutex::Unlock() { 13 | ExReleaseFastMutex(&m_mutex); 14 | } 15 | 16 | -------------------------------------------------------------------------------- /Chapter11/Tables/FastMutex.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct FastMutex { 4 | void Init(); 5 | void Lock(); 6 | void Unlock(); 7 | 8 | private: 9 | FAST_MUTEX m_mutex; 10 | }; 11 | 12 | -------------------------------------------------------------------------------- /Chapter11/Tables/Locker.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | template 4 | struct Locker { 5 | Locker(TLock& lock) : m_lock(lock) { 6 | lock.Lock(); 7 | } 8 | ~Locker() { 9 | m_lock.Unlock(); 10 | } 11 | 12 | private: 13 | TLock& m_lock; 14 | }; 15 | -------------------------------------------------------------------------------- /Chapter11/Tables/Processes.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "Locker.h" 3 | #include "Tables.h" 4 | 5 | void OnProcessNotify(PEPROCESS process, HANDLE pid, PPS_CREATE_NOTIFY_INFO createInfo) { 6 | UNREFERENCED_PARAMETER(process); 7 | if(!createInfo) { 8 | // 9 | // process dead, remove from table 10 | // 11 | Locker locker(g_Globals.Lock); 12 | ProcessData data; 13 | data.Id = HandleToULong(pid); 14 | auto deleted = RtlDeleteElementGenericTable(&g_Globals.ProcessTable, &data); 15 | if (!deleted) { 16 | KdPrint((DRIVER_PREFIX "Failed to delete process with ID %u\n", data.Id)); 17 | } 18 | } 19 | } 20 | 21 | NTSTATUS OnRegistryNotify(PVOID, PVOID Argument1, PVOID Argument2) { 22 | UNREFERENCED_PARAMETER(Argument2); 23 | 24 | auto type = (REG_NOTIFY_CLASS)(ULONG_PTR)Argument1; 25 | switch (type) { 26 | case RegNtPostSetValueKey: 27 | case RegNtPostCreateKey: 28 | case RegNtPostCreateKeyEx: 29 | case RegNtPostRenameKey: 30 | case RegNtPostDeleteValueKey: 31 | case RegNtPostDeleteKey: 32 | PVOID buffer; 33 | auto pid = HandleToULong(PsGetCurrentProcessId()); 34 | { 35 | Locker locker(g_Globals.Lock); 36 | buffer = RtlLookupElementGenericTable(&g_Globals.ProcessTable, &pid); 37 | if (buffer == nullptr) { 38 | // 39 | // process does not exist, create a new entry 40 | // 41 | ProcessData data{}; 42 | data.Id = pid; 43 | buffer = RtlInsertElementGenericTable(&g_Globals.ProcessTable, &data, sizeof(data), nullptr); 44 | if (buffer) { 45 | KdPrint((DRIVER_PREFIX "Added process %u from Registry callback\n", pid)); 46 | } 47 | } 48 | } 49 | if (buffer) { 50 | auto data = (ProcessData*)buffer; 51 | switch (type) { 52 | case RegNtPostSetValueKey: 53 | InterlockedIncrement64(&data->RegistrySetValueOperations); 54 | break; 55 | case RegNtPostCreateKey: 56 | case RegNtPostCreateKeyEx: 57 | InterlockedIncrement64(&data->RegistryCreateKeyOperations); 58 | break; 59 | case RegNtPostRenameKey: 60 | InterlockedIncrement64(&data->RegistryRenameOperations); 61 | break; 62 | case RegNtPostDeleteKey: 63 | case RegNtPostDeleteValueKey: 64 | InterlockedIncrement64(&data->RegistryDeleteOperations); 65 | break; 66 | } 67 | } 68 | } 69 | return STATUS_SUCCESS; 70 | } 71 | 72 | void DeleteAllProcesses() { 73 | Locker locker(g_Globals.Lock); 74 | // 75 | // deallocate all objects still stored in the table 76 | // 77 | PVOID p; 78 | auto t = &g_Globals.ProcessTable; 79 | while ((p = RtlGetElementGenericTable(t, 0)) != nullptr) { 80 | RtlDeleteElementGenericTable(t, p); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /Chapter11/Tables/Tables.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "FastMutex.h" 4 | #include "TablesPublic.h" 5 | 6 | #define DRIVER_PREFIX "Tables: " 7 | #define DRIVER_TAG 'lbaT' 8 | 9 | struct Globals { 10 | void Init(); 11 | 12 | RTL_GENERIC_TABLE ProcessTable; 13 | FastMutex Lock; 14 | LARGE_INTEGER RegCookie; 15 | }; 16 | 17 | extern Globals g_Globals; 18 | 19 | void DeleteAllProcesses(); -------------------------------------------------------------------------------- /Chapter11/Tables/Tables.inf: -------------------------------------------------------------------------------- 1 | ; 2 | ; Tables.inf 3 | ; 4 | 5 | [Version] 6 | Signature="$WINDOWS NT$" 7 | Class=System 8 | ClassGuid={4d36e97d-e325-11ce-bfc1-08002be10318} 9 | Provider=%ManufacturerName% 10 | DriverVer= 11 | CatalogFile=Tables.cat 12 | PnpLockdown=1 13 | 14 | ;This template is supported for OS version 17763 (Windows 10 version 1809) and after. 15 | ;For Windows OS prior to Windows 10 1809 set DefaultDestDir = 12 16 | [DestinationDirs] 17 | DefaultDestDir = 13 18 | 19 | 20 | [SourceDisksNames] 21 | 1 = %DiskName%,,,"" 22 | 23 | [SourceDisksFiles] 24 | 25 | 26 | [Manufacturer] 27 | %ManufacturerName%=Standard,NT$ARCH$ 28 | 29 | [Standard.NT$ARCH$] 30 | 31 | 32 | [Strings] 33 | ManufacturerName="" ;TODO: Replace with your manufacturer name 34 | DiskName="Tables Source Disk" 35 | -------------------------------------------------------------------------------- /Chapter11/Tables/Tables.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 | Source Files 24 | 25 | 26 | Source Files 27 | 28 | 29 | Source Files 30 | 31 | 32 | Source Files 33 | 34 | 35 | 36 | 37 | Header Files 38 | 39 | 40 | Header Files 41 | 42 | 43 | Header Files 44 | 45 | 46 | -------------------------------------------------------------------------------- /Chapter11/Tables/TablesPublic.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define TABLES_DEVICE 0x8003 4 | 5 | #define IOCTL_TABLES_GET_PROCESS_COUNT CTL_CODE(TABLES_DEVICE, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS) 6 | #define IOCTL_TABLES_GET_PROCESS_BY_ID CTL_CODE(TABLES_DEVICE, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS) 7 | #define IOCTL_TABLES_GET_PROCESS_BY_INDEX CTL_CODE(TABLES_DEVICE, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS) 8 | #define IOCTL_TABLES_DELETE_ALL CTL_CODE(TABLES_DEVICE, 0x803, METHOD_NEITHER, FILE_ANY_ACCESS) 9 | #define IOCTL_TABLES_START CTL_CODE(TABLES_DEVICE, 0x804, METHOD_NEITHER, FILE_ANY_ACCESS) 10 | #define IOCTL_TABLES_STOP CTL_CODE(TABLES_DEVICE, 0x805, METHOD_NEITHER, FILE_ANY_ACCESS) 11 | #define IOCTL_TABLES_GET_ALL CTL_CODE(TABLES_DEVICE, 0x806, METHOD_OUT_DIRECT, FILE_ANY_ACCESS) 12 | 13 | struct ProcessData { 14 | ULONG Id; 15 | LONG64 RegistrySetValueOperations; 16 | LONG64 RegistryCreateKeyOperations; 17 | LONG64 RegistryRenameOperations; 18 | LONG64 RegistryDeleteOperations; 19 | }; 20 | -------------------------------------------------------------------------------- /Chapter11/Tables/pch.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | -------------------------------------------------------------------------------- /Chapter11/Tables/pch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define RTL_USE_AVL_TABLES 4 | 5 | #include 6 | -------------------------------------------------------------------------------- /Chapter11/TablesTest/TablesTest.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;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 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Chapter11/Timers/Timers.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 | Source Files 24 | 25 | 26 | 27 | 28 | Header Files 29 | 30 | 31 | -------------------------------------------------------------------------------- /Chapter11/Timers/TimersPublic.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define TIMERS_DEVICE 0x8001 4 | 5 | #define IOCTL_TIMERS_SET_ONESHOT CTL_CODE(TIMERS_DEVICE, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS) 6 | #define IOCTL_TIMERS_SET_PERIODIC CTL_CODE(TIMERS_DEVICE, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS) 7 | #define IOCTL_TIMERS_GET_RESOLUTION CTL_CODE(TIMERS_DEVICE, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS) 8 | #define IOCTL_TIMERS_SET_HIRES CTL_CODE(TIMERS_DEVICE, 0x803, METHOD_BUFFERED, FILE_ANY_ACCESS) 9 | #define IOCTL_TIMERS_STOP CTL_CODE(TIMERS_DEVICE, 0x804, METHOD_NEITHER, FILE_ANY_ACCESS) 10 | 11 | struct TimerResolution { 12 | ULONG Maximum; 13 | ULONG Minimum; 14 | ULONG Current; 15 | ULONG Increment; 16 | }; 17 | 18 | struct PeriodicTimer { 19 | ULONG Interval; 20 | ULONG Period; 21 | }; 22 | -------------------------------------------------------------------------------- /Chapter11/TimersTest/TimersTest.cpp: -------------------------------------------------------------------------------- 1 | // TimersTest.cpp : This file contains the 'main' function. Program execution begins and ends there. 2 | // 3 | 4 | #include 5 | #include 6 | #include "..\Timers\TimersPublic.h" 7 | 8 | int main(int argc, const char* argv[]) { 9 | if (argc < 2) { 10 | printf("Usage: TimersTest [query | stop | set [hires] [interval(ms)] [period(ms)]]\n"); 11 | } 12 | 13 | HANDLE hDevice = CreateFile(L"\\\\.\\Timers", GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, 0, nullptr); 14 | if (hDevice == INVALID_HANDLE_VALUE) { 15 | printf("Error opening device (%u)\n", GetLastError()); 16 | return 1; 17 | } 18 | 19 | DWORD bytes; 20 | if (argc < 2 || _stricmp(argv[1], "query") == 0) { 21 | TimerResolution res; 22 | if (DeviceIoControl(hDevice, IOCTL_TIMERS_GET_RESOLUTION, nullptr, 0, &res, sizeof(res), &bytes, nullptr)) { 23 | printf("Timer resolution (100nsec): Max: %u Min: %u Current: %u Inc: %u\n", 24 | res.Maximum, res.Minimum, res.Current, res.Increment); 25 | float factor = 10000.0f; 26 | printf("Timer resolution (msec): Max: %.3f Min: %.3f Current: %.3f Inc: %.3f\n", 27 | res.Maximum / factor, res.Minimum / factor, res.Current / factor, res.Increment / factor); 28 | } 29 | } 30 | else if (_stricmp(argv[1], "set") == 0 && argc > 2) { 31 | int arg = 2; 32 | bool hires = false; 33 | if (_stricmp(argv[2], "hires") == 0) { 34 | hires = true; 35 | arg++; 36 | } 37 | PeriodicTimer data{}; 38 | if (argc > arg) { 39 | data.Interval = atoi(argv[arg]); 40 | arg++; 41 | if (argc > arg) { 42 | data.Period = atoi(argv[arg]); 43 | } 44 | if (!DeviceIoControl(hDevice, hires ? IOCTL_TIMERS_SET_HIRES : IOCTL_TIMERS_SET_PERIODIC, &data, sizeof(data), nullptr, 0, &bytes, nullptr)) 45 | printf("Error setting timer (%u)\n", GetLastError()); 46 | } 47 | } 48 | else if (_stricmp(argv[1], "stop") == 0) { 49 | DeviceIoControl(hDevice, IOCTL_TIMERS_STOP, nullptr, 0, nullptr, 0, &bytes, nullptr); 50 | } 51 | else { 52 | printf("Unknown option.\n"); 53 | } 54 | CloseHandle(hDevice); 55 | 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /Chapter11/TimersTest/TimersTest.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;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 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Chapter12/BackupMon/BackupMon.cpp: -------------------------------------------------------------------------------- 1 | // FileBackupMon.cpp : This file contains the 'main' function. Program execution begins and ends there. 2 | // 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "..\KBackup2\BackupCommon.h" 9 | 10 | #pragma comment(lib, "fltlib") 11 | 12 | void HandleMessage(const BYTE* buffer) { 13 | auto msg = (FileBackupPortMessage*)buffer; 14 | std::wstring filename(msg->FileName, msg->FileNameLength); 15 | 16 | printf("file backed up: %ws\n", filename.c_str()); 17 | } 18 | 19 | int main() { 20 | HANDLE hPort; 21 | auto hr = FilterConnectCommunicationPort(L"\\BackupPort", 0, nullptr, 0, nullptr, &hPort); 22 | if (FAILED(hr)) { 23 | printf("Error connecting to port (HR=0x%08X)\n", hr); 24 | return 1; 25 | } 26 | 27 | BYTE buffer[1 << 12]; // 4 KB 28 | auto message = (FILTER_MESSAGE_HEADER*)buffer; 29 | 30 | for (;;) { 31 | hr = FilterGetMessage(hPort, message, sizeof(buffer), nullptr); 32 | if (FAILED(hr)) { 33 | printf("Error receiving message (0x%08X)\n", hr); 34 | break; 35 | } 36 | HandleMessage(buffer + sizeof(FILTER_MESSAGE_HEADER)); 37 | } 38 | 39 | CloseHandle(hPort); 40 | 41 | return 0; 42 | } 43 | 44 | -------------------------------------------------------------------------------- /Chapter12/BackupMon/BackupMon.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;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 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Chapter12/BackupMon/BackupMon.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter12/DelProtect/DelProtect.cpp: -------------------------------------------------------------------------------- 1 | // DelProtect.cpp : This file contains the 'main' function. Program execution begins and ends there. 2 | // 3 | 4 | #include 5 | #include 6 | #include "..\kdelprotect\kdelprotectPublic.h" 7 | #include 8 | 9 | int wmain(int argc, const wchar_t* argv[]) { 10 | if (argc < 2) { 11 | printf("Usage: delprotect \n"); 12 | return 0; 13 | } 14 | 15 | auto hDevice = CreateFile(L"\\\\.\\DelProtect", GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, 0, nullptr); 16 | if (hDevice == INVALID_HANDLE_VALUE) { 17 | printf("Error opening device (%u)\n", GetLastError()); 18 | return 1; 19 | } 20 | 21 | DWORD returned; 22 | std::wstring exts = argv[1]; 23 | if (exts.back() != L';') 24 | exts += L";"; 25 | auto ok = DeviceIoControl(hDevice, IOCTL_DELPROTECT_SET_EXTENSIONS, 26 | exts.data(), (DWORD)(1 + exts.length()) * sizeof(WCHAR), nullptr, 0, &returned, nullptr); 27 | printf("Extensions set: %s\n", ok ? "OK" : "Error"); 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /Chapter12/DelProtect/DelProtect.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;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 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Chapter12/DelTest/DelTest.cpp: -------------------------------------------------------------------------------- 1 | // DelTest.cpp : This file contains the 'main' function. Program execution begins and ends there. 2 | // 3 | 4 | #include 5 | #include 6 | 7 | void HandleResult(BOOL success) { 8 | if (success) 9 | printf("Success!\n"); 10 | else 11 | printf("Error: %d\n", GetLastError()); 12 | } 13 | 14 | int wmain(int argc, const wchar_t* argv[]) { 15 | if (argc < 3) { 16 | printf("Usage: deltest.exe \n"); 17 | printf("\tMethod: 1=DeleteFile, 2=delete on close, 3=SetFileInformation.\n"); 18 | return 0; 19 | } 20 | 21 | auto method = _wtoi(argv[1]); 22 | auto filename = argv[2]; 23 | HANDLE hFile; 24 | BOOL success; 25 | 26 | switch (method) { 27 | case 1: 28 | printf("Using DeleteFile:\n"); 29 | success = DeleteFile(filename); 30 | HandleResult(success); 31 | break; 32 | 33 | case 2: 34 | printf("Using CreateFile with FILE_FLAG_DELETE_ON_CLOSE:\n"); 35 | hFile = CreateFile(filename, DELETE, 0, nullptr, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, nullptr); 36 | HandleResult(hFile != INVALID_HANDLE_VALUE); 37 | CloseHandle(hFile); 38 | break; 39 | 40 | case 3: 41 | printf("Using SetFileInformationByHandle:\n"); 42 | FILE_DISPOSITION_INFO info; 43 | info.DeleteFile = TRUE; 44 | hFile = CreateFile(filename, DELETE, 0, nullptr, OPEN_EXISTING, 0, nullptr); 45 | success = SetFileInformationByHandle(hFile, FileDispositionInfo, &info, sizeof(info)); 46 | HandleResult(success); 47 | CloseHandle(hFile); 48 | break; 49 | } 50 | 51 | return 0; 52 | } 53 | 54 | -------------------------------------------------------------------------------- /Chapter12/DelTest/DelTest.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;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 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Chapter12/Hide/Hide.cpp: -------------------------------------------------------------------------------- 1 | // Hide.cpp : This file contains the 'main' function. Program execution begins and ends there. 2 | // 3 | 4 | #include 5 | #include 6 | #include "..\KHide\HidePublic.h" 7 | 8 | int wmain(int argc, const wchar_t* argv[]) { 9 | if (argc < 2) { 10 | printf("Usage: hide 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;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 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Chapter12/KBackup/Driver.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "Driver.h" 3 | 4 | PFLT_FILTER g_Filter; 5 | 6 | extern "C" 7 | NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) { 8 | auto status = InitMiniFilter(DriverObject, RegistryPath); 9 | if (!NT_SUCCESS(status)) { 10 | KdPrint((DRIVER_PREFIX "Failed to init mini-filter (0x%X)\n", status)); 11 | return status; 12 | } 13 | 14 | status = FltStartFiltering(g_Filter); 15 | if (!NT_SUCCESS(status)) { 16 | FltUnregisterFilter(g_Filter); 17 | } 18 | return status; 19 | } 20 | -------------------------------------------------------------------------------- /Chapter12/KBackup/Driver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | extern PFLT_FILTER g_Filter; 4 | 5 | #define DRIVER_TAG 'pukb' 6 | #define DRIVER_PREFIX "Backup: " 7 | 8 | NTSTATUS InitMiniFilter(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath); 9 | 10 | -------------------------------------------------------------------------------- /Chapter12/KBackup/KBackup.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 | Header Files 24 | 25 | 26 | Header Files 27 | 28 | 29 | 30 | 31 | Source Files 32 | 33 | 34 | Source Files 35 | 36 | 37 | Source Files 38 | 39 | 40 | -------------------------------------------------------------------------------- /Chapter12/KBackup/pch.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | -------------------------------------------------------------------------------- /Chapter12/KBackup/pch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | -------------------------------------------------------------------------------- /Chapter12/KBackup2/BackupCommon.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct FileBackupPortMessage { 4 | USHORT FileNameLength; 5 | WCHAR FileName[1]; 6 | }; 7 | -------------------------------------------------------------------------------- /Chapter12/KBackup2/Driver.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "Driver.h" 3 | 4 | PFLT_FILTER g_Filter; 5 | PFLT_PORT g_Port; 6 | PFLT_PORT g_ClientPort; 7 | 8 | extern "C" 9 | NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) { 10 | auto status = InitMiniFilter(DriverObject, RegistryPath); 11 | if (!NT_SUCCESS(status)) { 12 | KdPrint((DRIVER_PREFIX "Failed to init mini-filter (0x%X)\n", status)); 13 | return status; 14 | } 15 | 16 | do { 17 | UNICODE_STRING name = RTL_CONSTANT_STRING(L"\\BackupPort"); 18 | PSECURITY_DESCRIPTOR sd; 19 | 20 | status = FltBuildDefaultSecurityDescriptor(&sd, FLT_PORT_ALL_ACCESS); 21 | if (!NT_SUCCESS(status)) 22 | break; 23 | 24 | OBJECT_ATTRIBUTES attr; 25 | InitializeObjectAttributes(&attr, &name, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, nullptr, sd); 26 | 27 | status = FltCreateCommunicationPort(g_Filter, &g_Port, &attr, nullptr, 28 | PortConnectNotify, PortDisconnectNotify, PortMessageNotify, 1); 29 | 30 | FltFreeSecurityDescriptor(sd); 31 | if (!NT_SUCCESS(status)) 32 | break; 33 | 34 | // 35 | // Start filtering i/o 36 | // 37 | status = FltStartFiltering(g_Filter); 38 | } while (false); 39 | 40 | if (!NT_SUCCESS(status)) { 41 | FltUnregisterFilter(g_Filter); 42 | } 43 | 44 | return status; 45 | } 46 | -------------------------------------------------------------------------------- /Chapter12/KBackup2/Driver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "BackupCommon.h" 4 | 5 | extern PFLT_FILTER g_Filter; 6 | extern PFLT_PORT g_Port; 7 | extern PFLT_PORT g_ClientPort; 8 | 9 | #define DRIVER_TAG 'pukb' 10 | #define DRIVER_PREFIX "Backup: " 11 | 12 | NTSTATUS InitMiniFilter(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath); 13 | 14 | NTSTATUS PortConnectNotify( 15 | _In_ PFLT_PORT ClientPort, 16 | _In_opt_ PVOID ServerPortCookie, 17 | _In_reads_bytes_opt_(SizeOfContext) PVOID ConnectionContext, 18 | _In_ ULONG SizeOfContext, 19 | _Outptr_result_maybenull_ PVOID* ConnectionPortCookie); 20 | 21 | void PortDisconnectNotify(_In_opt_ PVOID ConnectionCookie); 22 | 23 | NTSTATUS PortMessageNotify( 24 | _In_opt_ PVOID PortCookie, 25 | _In_reads_bytes_opt_(InputBufferLength) PVOID InputBuffer, 26 | _In_ ULONG InputBufferLength, 27 | _Out_writes_bytes_to_opt_(OutputBufferLength, *ReturnOutputBufferLength) PVOID OutputBuffer, 28 | _In_ ULONG OutputBufferLength, 29 | _Out_ PULONG ReturnOutputBufferLength); 30 | -------------------------------------------------------------------------------- /Chapter12/KBackup2/KBackup2.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 | Source Files 24 | 25 | 26 | Source Files 27 | 28 | 29 | Source Files 30 | 31 | 32 | 33 | 34 | Header Files 35 | 36 | 37 | Header Files 38 | 39 | 40 | Header Files 41 | 42 | 43 | -------------------------------------------------------------------------------- /Chapter12/KBackup2/pch.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | -------------------------------------------------------------------------------- /Chapter12/KBackup2/pch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | -------------------------------------------------------------------------------- /Chapter12/KDelprotect/Driver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define DRIVER_PREFIX "DelProtect: " 4 | #define DRIVER_TAG 'trpD' 5 | 6 | NTSTATUS CompleteRequest(PIRP Irp, NTSTATUS status = STATUS_SUCCESS, ULONG_PTR information = 0); 7 | -------------------------------------------------------------------------------- /Chapter12/KDelprotect/ExecutiveResource.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "ExecutiveResource.h" 3 | 4 | NTSTATUS ExecutiveResource::Init() { 5 | return ExInitializeResourceLite(&m_res); 6 | } 7 | 8 | void ExecutiveResource::Delete() { 9 | ExDeleteResourceLite(&m_res); 10 | } 11 | 12 | void ExecutiveResource::Lock() { 13 | ExEnterCriticalRegionAndAcquireResourceExclusive(&m_res); 14 | } 15 | 16 | void ExecutiveResource::Unlock() { 17 | ExReleaseResourceAndLeaveCriticalRegion(&m_res); 18 | } 19 | 20 | void ExecutiveResource::LockShared() { 21 | ExEnterCriticalRegionAndAcquireResourceShared(&m_res); 22 | } 23 | 24 | void ExecutiveResource::UnlockShared() { 25 | Unlock(); 26 | } 27 | -------------------------------------------------------------------------------- /Chapter12/KDelprotect/ExecutiveResource.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct ExecutiveResource { 4 | NTSTATUS Init(); 5 | void Delete(); 6 | 7 | void Lock(); 8 | void Unlock(); 9 | 10 | void LockShared(); 11 | void UnlockShared(); 12 | 13 | private: 14 | ERESOURCE m_res; 15 | }; 16 | 17 | -------------------------------------------------------------------------------- /Chapter12/KDelprotect/Locker.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | template 4 | struct Locker { 5 | Locker(TLock& lock) : m_lock(lock) { 6 | lock.Lock(); 7 | } 8 | ~Locker() { 9 | m_lock.Unlock(); 10 | } 11 | 12 | private: 13 | TLock& m_lock; 14 | }; 15 | 16 | template 17 | struct SharedLocker { 18 | SharedLocker(TLock& lock) : m_lock(lock) { 19 | lock.LockShared(); 20 | } 21 | ~SharedLocker() { 22 | m_lock.UnlockShared(); 23 | } 24 | 25 | private: 26 | TLock& m_lock; 27 | }; 28 | 29 | -------------------------------------------------------------------------------- /Chapter12/KDelprotect/MiniFilter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ExecutiveResource.h" 4 | 5 | struct FilterState { 6 | PFLT_FILTER Filter; 7 | UNICODE_STRING Extentions; 8 | ExecutiveResource Lock; 9 | PDRIVER_OBJECT DriverObject; 10 | }; 11 | 12 | extern FilterState g_State; 13 | -------------------------------------------------------------------------------- /Chapter12/KDelprotect/kdelprotect.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 | Source Files 24 | 25 | 26 | Source Files 27 | 28 | 29 | Source Files 30 | 31 | 32 | Source Files 33 | 34 | 35 | 36 | 37 | Header Files 38 | 39 | 40 | Header Files 41 | 42 | 43 | Header Files 44 | 45 | 46 | Header Files 47 | 48 | 49 | Header Files 50 | 51 | 52 | Header Files 53 | 54 | 55 | -------------------------------------------------------------------------------- /Chapter12/KDelprotect/kdelprotectPublic.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define DEVICE_DELPROTECT 0x8009 4 | 5 | #define IOCTL_DELPROTECT_SET_EXTENSIONS CTL_CODE(DEVICE_DELPROTECT, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS) 6 | -------------------------------------------------------------------------------- /Chapter12/KDelprotect/pch.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | -------------------------------------------------------------------------------- /Chapter12/KDelprotect/pch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | -------------------------------------------------------------------------------- /Chapter12/KHide/Driver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define DRIVER_PREFIX "Hide: " 4 | #define DRIVER_TAG 'edih' 5 | 6 | #include 7 | #include "HidePublic.h" 8 | 9 | -------------------------------------------------------------------------------- /Chapter12/KHide/HidePublic.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define DEVICE_HIDE 0x8001 4 | 5 | #define IOCTL_HIDE_PATH CTL_CODE(DEVICE_HIDE, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS) 6 | #define IOCTL_SHOW_ALL CTL_CODE(DEVICE_HIDE, 0x801, METHOD_NEITHER, FILE_ANY_ACCESS) 7 | -------------------------------------------------------------------------------- /Chapter12/KHide/KHide.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 | Source Files 24 | 25 | 26 | Source Files 27 | 28 | 29 | Source Files 30 | 31 | 32 | 33 | 34 | Header Files 35 | 36 | 37 | Header Files 38 | 39 | 40 | Header Files 41 | 42 | 43 | Header Files 44 | 45 | 46 | -------------------------------------------------------------------------------- /Chapter12/KHide/MiniFilter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Driver.h" 4 | 5 | #include 6 | 7 | struct FilterState { 8 | FilterState(); 9 | ~FilterState(); 10 | 11 | PFLT_FILTER Filter; 12 | PDRIVER_OBJECT DriverObject; 13 | Vector, PoolType::NonPaged, DRIVER_TAG> Files; 14 | ExecutiveResource Lock; 15 | }; 16 | 17 | extern FilterState* g_State; 18 | -------------------------------------------------------------------------------- /Chapter12/KHide/pch.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | -------------------------------------------------------------------------------- /Chapter12/KHide/pch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | -------------------------------------------------------------------------------- /Chapter12/Restore/Restore.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int Error(const char* text) { 6 | printf("%s (%d)\n", text, ::GetLastError()); 7 | return 1; 8 | } 9 | 10 | int wmain(int argc, const wchar_t* argv[]) { 11 | if (argc < 2) { 12 | printf("Usage: Restore \n"); 13 | return 0; 14 | } 15 | 16 | // locate the backup stream 17 | std::wstring stream(argv[1]); 18 | stream += L":backup"; 19 | 20 | HANDLE hSource = CreateFile(stream.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr); 21 | if (hSource == INVALID_HANDLE_VALUE) 22 | return Error("Failed to locate backup"); 23 | 24 | HANDLE hTarget = CreateFile(argv[1], GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, 0, nullptr); 25 | if (hTarget == INVALID_HANDLE_VALUE) 26 | return Error("Failed to locate file"); 27 | 28 | LARGE_INTEGER size; 29 | if (!GetFileSizeEx(hSource, &size)) 30 | return Error("Failed to get file size"); 31 | 32 | ULONG bufferSize = (ULONG)min((LONGLONG)1 << 21, size.QuadPart); 33 | void* buffer = VirtualAlloc(nullptr, bufferSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); 34 | if (!buffer) 35 | return Error("Failed to allocate buffer"); 36 | 37 | DWORD bytes; 38 | while (size.QuadPart > 0) { 39 | if (!ReadFile(hSource, buffer, (DWORD)(min((LONGLONG)bufferSize, size.QuadPart)), &bytes, nullptr)) 40 | return Error("Failed to read data"); 41 | 42 | if (!WriteFile(hTarget, buffer, bytes, &bytes, nullptr)) 43 | return Error("Failed to write data"); 44 | size.QuadPart -= bytes; 45 | } 46 | 47 | printf("Restore successful!\n"); 48 | 49 | CloseHandle(hSource); 50 | CloseHandle(hTarget); 51 | VirtualFree(buffer, 0, MEM_RELEASE); 52 | 53 | return 0; 54 | } 55 | 56 | -------------------------------------------------------------------------------- /Chapter12/Restore/Restore.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;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 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Chapter12/Streams/Streams.cpp: -------------------------------------------------------------------------------- 1 | // Streams.cpp : This file contains the 'main' function. Program execution begins and ends there. 2 | // 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | struct StreamInfo { 10 | std::wstring Name; 11 | LONGLONG Size; 12 | }; 13 | 14 | void PrintStream(PCWSTR path, StreamInfo const& stm, bool contents) { 15 | printf("%ws (%lld bytes)\n", stm.Name.c_str(), stm.Size); 16 | if (contents) { 17 | const int maxSize = 256; 18 | auto size = min((int)stm.Size, maxSize); 19 | auto stmPath = path + stm.Name.substr(0, stm.Name.find(L'$') - 1); 20 | auto hFile = CreateFile(stmPath.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr); 21 | if (hFile == INVALID_HANDLE_VALUE) { 22 | printf("Failed to open stream %ws (%u)\n", stmPath.c_str(), GetLastError()); 23 | return; 24 | } 25 | BYTE buffer[maxSize]; 26 | DWORD read = 0; 27 | ReadFile(hFile, buffer, size, &read, nullptr); 28 | for (DWORD i = 0; i < read; i++) { 29 | int width = 16; 30 | printf("%02X ", buffer[i]); 31 | if ((i + 1) % width == 0 || i == read - 1) { 32 | printf(std::string(3 * (width - i % width), L' ').c_str()); 33 | for (DWORD j = i - i % width; j <= i; j++) { 34 | printf("%c", isprint(buffer[j]) ? buffer[j] : '.'); 35 | } 36 | printf("\n"); 37 | } 38 | } 39 | CloseHandle(hFile); 40 | } 41 | } 42 | 43 | int wmain(int argc, const wchar_t* argv[]) { 44 | if (argc < 2 || argc > 4) { 45 | printf("Usage: streams [-d] [streamname] \n"); 46 | return 0; 47 | } 48 | 49 | auto path = argv[argc - 1]; 50 | bool display = false; 51 | PCWSTR name = nullptr; 52 | for (int i = 1; i < argc - 1; i++) { 53 | if (_wcsicmp(argv[i], L"-d") == 0) 54 | display = true; 55 | else if (argv[i][0] == L'-') 56 | printf("Unknown switch %ws\n", argv[i]); 57 | else 58 | name = argv[i]; 59 | } 60 | 61 | std::vector streams; 62 | WIN32_FIND_STREAM_DATA data; 63 | auto hFind = ::FindFirstStreamW(path, FindStreamInfoStandard, &data, 0); 64 | if (hFind == INVALID_HANDLE_VALUE) { 65 | printf("Error locating streams in file %ws (%u)\n", path, GetLastError()); 66 | return 1; 67 | } 68 | 69 | std::wstring name2; 70 | if(name) 71 | name2 = std::wstring(L":") + name + L":"; 72 | do { 73 | if(_wcsnicmp(data.cStreamName, L"::", 2) != 0 && 74 | (name == nullptr || _wcsnicmp(name2.c_str(), data.cStreamName, name2.length()) == 0)) 75 | streams.push_back(StreamInfo{ data.cStreamName, data.StreamSize.QuadPart }); 76 | } while (FindNextStreamW(hFind, &data)); 77 | FindClose(hFind); 78 | 79 | if (streams.empty()) 80 | printf("No alternate streams found.\n"); 81 | else { 82 | for (auto& stm : streams) 83 | PrintStream(path, stm, display); 84 | } 85 | return 0; 86 | } 87 | -------------------------------------------------------------------------------- /Chapter12/Streams/Streams.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;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 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Chapter13/BlockProcess/BlockProcess.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;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 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | 26 | 27 | Header Files 28 | 29 | 30 | -------------------------------------------------------------------------------- /Chapter13/BlockProcess/pch.cpp: -------------------------------------------------------------------------------- 1 | // pch.cpp: source file corresponding to the pre-compiled header 2 | 3 | #include "pch.h" 4 | 5 | // When you are using pre-compiled headers, this source file is necessary for compilation to succeed. 6 | -------------------------------------------------------------------------------- /Chapter13/BlockProcess/pch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | -------------------------------------------------------------------------------- /Chapter13/ProcessNetFilter/EResource.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "EResource.h" 3 | 4 | #ifdef KTL_NAMESPACE 5 | using namespace ktl; 6 | #endif 7 | 8 | 9 | void ExecutiveResource::Init() { 10 | ExInitializeResourceLite(&m_res); 11 | } 12 | 13 | void ExecutiveResource::Delete() { 14 | ExDeleteResourceLite(&m_res); 15 | } 16 | 17 | void ExecutiveResource::Lock() { 18 | ExEnterCriticalRegionAndAcquireResourceExclusive(&m_res); 19 | } 20 | 21 | void ExecutiveResource::Unlock() { 22 | ExReleaseResourceAndLeaveCriticalRegion(&m_res); 23 | } 24 | 25 | void ExecutiveResource::LockShared() { 26 | ExEnterCriticalRegionAndAcquireResourceShared(&m_res); 27 | } 28 | 29 | void ExecutiveResource::UnlockShared() { 30 | Unlock(); 31 | } 32 | -------------------------------------------------------------------------------- /Chapter13/ProcessNetFilter/EResource.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef KTL_NAMESPACE 4 | namespace ktl { 5 | #endif 6 | 7 | class ExecutiveResource { 8 | public: 9 | void Init(); 10 | void Delete(); 11 | 12 | void Lock(); 13 | void Unlock(); 14 | 15 | void LockShared(); 16 | void UnlockShared(); 17 | 18 | private: 19 | ERESOURCE m_res; 20 | }; 21 | 22 | #ifdef KTL_NAMESPACE 23 | } 24 | #endif 25 | -------------------------------------------------------------------------------- /Chapter13/ProcessNetFilter/Globals.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Vector.h" 4 | #include "SpinLock.h" 5 | 6 | class Globals { 7 | public: 8 | Globals(); 9 | static Globals& Get(); 10 | Globals(Globals const&) = delete; 11 | Globals& operator=(Globals const&) = delete; 12 | ~Globals(); 13 | 14 | NTSTATUS RegisterCallouts(PDEVICE_OBJECT devObj); 15 | NTSTATUS AddProcess(ULONG pid); 16 | NTSTATUS DeleteProcess(ULONG pid); 17 | NTSTATUS ClearProcesses(); 18 | bool IsProcessBlocked(ULONG pid) const; 19 | 20 | NTSTATUS DoCalloutNotify( 21 | _In_ FWPS_CALLOUT_NOTIFY_TYPE notifyType, 22 | _In_ const GUID* filterKey, 23 | _Inout_ FWPS_FILTER* filter); 24 | 25 | void DoCalloutClassify( 26 | _In_ const FWPS_INCOMING_VALUES* inFixedValues, 27 | _In_ const FWPS_INCOMING_METADATA_VALUES* inMetaValues, 28 | _Inout_opt_ void* layerData, 29 | _In_opt_ const void* classifyContext, 30 | _In_ const FWPS_FILTER* filter, 31 | _In_ UINT64 flowContext, 32 | _Inout_ FWPS_CLASSIFY_OUT* classifyOut); 33 | 34 | private: 35 | Vector m_Processes; 36 | mutable SpinLock m_ProcessesLock; 37 | inline static Globals* s_Globals; 38 | }; 39 | 40 | -------------------------------------------------------------------------------- /Chapter13/ProcessNetFilter/Locker.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef KTL_NAMESPACE 4 | namespace ktl { 5 | #endif 6 | template 7 | struct Locker { 8 | Locker(TLock& lock) : m_lock(lock) { 9 | lock.Lock(); 10 | } 11 | ~Locker() { 12 | m_lock.Unlock(); 13 | } 14 | 15 | private: 16 | TLock& m_lock; 17 | }; 18 | 19 | template 20 | struct SharedLocker { 21 | SharedLocker(TLock& lock) : m_lock(lock) { 22 | lock.LockShared(); 23 | } 24 | ~SharedLocker() { 25 | m_lock.UnlockShared(); 26 | } 27 | 28 | private: 29 | TLock& m_lock; 30 | }; 31 | 32 | #ifdef KTL_NAMESPACE 33 | } 34 | #endif 35 | -------------------------------------------------------------------------------- /Chapter13/ProcessNetFilter/Main.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "Main.h" 3 | 4 | // globals 5 | 6 | Globals* g_Data; 7 | 8 | // prototypes 9 | 10 | void ProcNetFilterUnload(PDRIVER_OBJECT DriverObject); 11 | NTSTATUS ProcNetFilterCreateClose(PDEVICE_OBJECT, PIRP Irp); 12 | NTSTATUS ProcNetFilterDeviceControl(PDEVICE_OBJECT, PIRP Irp); 13 | NTSTATUS CompleteRequest(PIRP Irp, NTSTATUS status = STATUS_SUCCESS, ULONG_PTR info = 0); 14 | 15 | // DriverEntry 16 | 17 | extern "C" NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING) { 18 | UNICODE_STRING devName = RTL_CONSTANT_STRING(L"\\Device\\ProcNetFilter"); 19 | PDEVICE_OBJECT devObj; 20 | auto status = IoCreateDevice(DriverObject, 0, &devName, FILE_DEVICE_UNKNOWN, 0, FALSE, &devObj); 21 | if (!NT_SUCCESS(status)) 22 | return status; 23 | 24 | bool symLinkCreated = false; 25 | UNICODE_STRING symLink = RTL_CONSTANT_STRING(L"\\??\\ProcNetFilter"); 26 | do { 27 | g_Data = new (PoolType::NonPaged) Globals; 28 | if (!g_Data) { 29 | status = STATUS_NO_MEMORY; 30 | break; 31 | } 32 | status = IoCreateSymbolicLink(&symLink, &devName); 33 | if (!NT_SUCCESS(status)) 34 | break; 35 | symLinkCreated = true; 36 | 37 | status = g_Data->RegisterCallouts(devObj); 38 | if (!NT_SUCCESS(status)) 39 | break; 40 | } while (false); 41 | 42 | if (!NT_SUCCESS(status)) { 43 | KdPrint((DRIVER_PREFIX "DriverEntry failed (0x%X)\n", status)); 44 | if (symLinkCreated) 45 | IoDeleteSymbolicLink(&symLink); 46 | IoDeleteDevice(devObj); 47 | return status; 48 | } 49 | 50 | DriverObject->DriverUnload = ProcNetFilterUnload; 51 | DriverObject->MajorFunction[IRP_MJ_CREATE] = DriverObject->MajorFunction[IRP_MJ_CLOSE] = ProcNetFilterCreateClose; 52 | DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ProcNetFilterDeviceControl; 53 | 54 | return STATUS_SUCCESS; 55 | } 56 | 57 | void ProcNetFilterUnload(PDRIVER_OBJECT DriverObject) { 58 | delete g_Data; 59 | 60 | UNICODE_STRING symLink = RTL_CONSTANT_STRING(L"\\??\\ProcNetFilter"); 61 | IoDeleteSymbolicLink(&symLink); 62 | IoDeleteDevice(DriverObject->DeviceObject); 63 | } 64 | 65 | NTSTATUS ProcNetFilterCreateClose(PDEVICE_OBJECT, PIRP Irp) { 66 | return CompleteRequest(Irp); 67 | } 68 | 69 | NTSTATUS ProcNetFilterDeviceControl(PDEVICE_OBJECT, PIRP Irp) { 70 | auto irpSp = IoGetCurrentIrpStackLocation(Irp); 71 | auto const& dic = irpSp->Parameters.DeviceIoControl; 72 | auto status = STATUS_INVALID_DEVICE_REQUEST; 73 | ULONG info = 0; 74 | 75 | switch (dic.IoControlCode) { 76 | case IOCTL_PNF_CLEAR: 77 | status = g_Data->ClearProcesses(); 78 | break; 79 | 80 | case IOCTL_PNF_BLOCK_PROCESS: 81 | case IOCTL_PNF_PERMIT_PROCESS: 82 | if (dic.InputBufferLength < sizeof(ULONG)) { 83 | status = STATUS_BUFFER_TOO_SMALL; 84 | break; 85 | } 86 | auto pid = *(ULONG*)Irp->AssociatedIrp.SystemBuffer; 87 | status = dic.IoControlCode == IOCTL_PNF_BLOCK_PROCESS ? g_Data->AddProcess(pid) : g_Data->DeleteProcess(pid); 88 | if (NT_SUCCESS(status)) 89 | info = sizeof(ULONG); 90 | break; 91 | } 92 | 93 | return CompleteRequest(Irp, status, info); 94 | } 95 | 96 | NTSTATUS CompleteRequest(PIRP Irp, NTSTATUS status, ULONG_PTR info) { 97 | Irp->IoStatus.Status = status; 98 | Irp->IoStatus.Information = info; 99 | IoCompleteRequest(Irp, IO_NO_INCREMENT); 100 | return status; 101 | } 102 | -------------------------------------------------------------------------------- /Chapter13/ProcessNetFilter/Main.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define DRIVER_TAG 'rfnp' 4 | #define DRIVER_PREFIX "ProcNetFilter: " 5 | #include "ProcNetFilterPublic.h" 6 | #include "Locker.h" 7 | #include "Memory.h" 8 | #include "Globals.h" 9 | -------------------------------------------------------------------------------- /Chapter13/ProcessNetFilter/Memory.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "Memory.h" 3 | 4 | #ifdef KTL_TRACK_MEMORY 5 | LONGLONG TotalAllocated; 6 | LONG AllocationCount; 7 | #endif 8 | 9 | void* __cdecl operator new(size_t size, PoolType pool, ULONG tag) { 10 | void* p = ExAllocatePool2((POOL_FLAGS)pool, size, tag); 11 | #ifdef KTL_TRACK_MEMORY 12 | DbgPrint(KTL_PREFIX "Allocating %u bytes from pool %d with tag 0x%X: 0x%p\n", size, pool, tag, p); 13 | if (p) { 14 | InterlockedIncrement(&AllocationCount); 15 | InterlockedAdd64(&TotalAllocated, size); 16 | } 17 | #endif 18 | return p; 19 | } 20 | 21 | void* __cdecl operator new[](size_t size, PoolType pool, ULONG tag) { 22 | void* p = ExAllocatePool2((POOL_FLAGS)pool, size, tag); 23 | #ifdef KTL_TRACK_MEMORY 24 | DbgPrint(KTL_PREFIX "Allocating %u bytes from pool %d with tag 0x%X: 0x%p\n", size, pool, tag, p); 25 | if (p) { 26 | InterlockedIncrement(&AllocationCount); 27 | InterlockedAdd64(&TotalAllocated, size); 28 | } 29 | #endif 30 | return p; 31 | } 32 | 33 | void __cdecl operator delete(void* p, size_t) { 34 | NT_ASSERT(p); 35 | ExFreePool(p); 36 | #ifdef KTL_TRACK_MEMORY 37 | DbgPrint(KTL_PREFIX "Freeing 0x%X: 0x%p\n", p); 38 | if (InterlockedDecrement(&AllocationCount) < 0) { 39 | NT_ASSERT(false); 40 | } 41 | #endif 42 | } 43 | 44 | void __cdecl operator delete[](void* p, size_t) { 45 | NT_ASSERT(p); 46 | ExFreePool(p); 47 | #ifdef KTL_TRACK_MEMORY 48 | DbgPrint(KTL_PREFIX "Freeing 0x%X: 0x%p\n", p); 49 | if (InterlockedDecrement(&AllocationCount) < 0) { 50 | NT_ASSERT(false); 51 | } 52 | #endif 53 | } -------------------------------------------------------------------------------- /Chapter13/ProcessNetFilter/Memory.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef DRIVER_TAG 4 | #define DRIVER_TAG 'dltk' 5 | #endif 6 | 7 | enum class PoolType : ULONG64 { 8 | Paged = POOL_FLAG_PAGED, 9 | NonPaged = POOL_FLAG_NON_PAGED, 10 | NonPagedExecute = POOL_FLAG_NON_PAGED_EXECUTE, 11 | CacheAligned = POOL_FLAG_CACHE_ALIGNED, 12 | Uninitialized = POOL_FLAG_CACHE_ALIGNED, 13 | ChargeQuota = POOL_FLAG_USE_QUOTA, 14 | RaiseOnFailure = POOL_FLAG_RAISE_ON_FAILURE, 15 | Session = POOL_FLAG_SESSION, 16 | SpecialPool = POOL_FLAG_SPECIAL_POOL, 17 | }; 18 | DEFINE_ENUM_FLAG_OPERATORS(PoolType); 19 | 20 | void* __cdecl operator new(size_t size, PoolType pool, ULONG tag = DRIVER_TAG); 21 | void* __cdecl operator new[](size_t size, PoolType pool, ULONG tag = DRIVER_TAG); 22 | 23 | void __cdecl operator delete(void* p, size_t); 24 | void __cdecl operator delete[](void* p, size_t); 25 | -------------------------------------------------------------------------------- /Chapter13/ProcessNetFilter/ProcNetFilterPublic.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #define PROCNETFILTER_DEVICE 0x8003 6 | 7 | #define IOCTL_PNF_BLOCK_PROCESS CTL_CODE(PROCNETFILTER_DEVICE, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS) 8 | #define IOCTL_PNF_PERMIT_PROCESS CTL_CODE(PROCNETFILTER_DEVICE, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS) 9 | #define IOCTL_PNF_CLEAR CTL_CODE(PROCNETFILTER_DEVICE, 0x802, METHOD_NEITHER, FILE_ANY_ACCESS) 10 | 11 | // {5027C277-201A-4AAF-B8EC-95C05E857059} 12 | DEFINE_GUID(GUID_CALLOUT_PROCESS_BLOCK_V4, 0x5027c277, 0x201a, 0x4aaf, 0xb8, 0xec, 0x95, 0xc0, 0x5e, 0x85, 0x70, 0x59); 13 | 14 | // {CF51FD24-566F-4C6D-9BC9-8013E9875E7E} 15 | DEFINE_GUID(GUID_CALLOUT_PROCESS_BLOCK_V6, 0xcf51fd24, 0x566f, 0x4c6d, 0x9b, 0xc9, 0x80, 0x13, 0xe9, 0x87, 0x5e, 0x7e); 16 | 17 | // {200E35C6-7182-4F9C-97DF-34028A225BEC} 18 | DEFINE_GUID(GUID_CALLOUT_PROCESS_BLOCK_UDP_V4, 0x200e35c6, 0x7182, 0x4f9c, 0x97, 0xdf, 0x34, 0x02, 0x8a, 0x22, 0x5b, 0xec); 19 | 20 | // {C8AF8E6D-1D0C-4547-A2A1-7593C3396BAF} 21 | DEFINE_GUID(GUID_CALLOUT_PROCESS_BLOCK_UDP_V6, 0xc8af8e6d, 0x1d0c, 0x4547, 0xa2, 0xa1, 0x75, 0x93, 0xc3, 0x39, 0x6b, 0xaf); 22 | -------------------------------------------------------------------------------- /Chapter13/ProcessNetFilter/ProcessNetFilter.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 | Source Files 24 | 25 | 26 | Source Files 27 | 28 | 29 | Source Files 30 | 31 | 32 | Source Files 33 | 34 | 35 | Source Files 36 | 37 | 38 | 39 | 40 | Header Files 41 | 42 | 43 | Header Files 44 | 45 | 46 | Header Files 47 | 48 | 49 | Header Files 50 | 51 | 52 | Header Files 53 | 54 | 55 | Header Files 56 | 57 | 58 | Header Files 59 | 60 | 61 | Header Files 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /Chapter13/ProcessNetFilter/SpinLock.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "SpinLock.h" 3 | 4 | #ifdef KTL_NAMESPACE 5 | using namespace ktl; 6 | #endif 7 | 8 | void SpinLock::Init() { 9 | KeInitializeSpinLock(&m_lock); 10 | } 11 | 12 | void SpinLock::Lock() { 13 | KeAcquireSpinLock(&m_lock, &m_oldIrql); 14 | } 15 | 16 | void SpinLock::Unlock() { 17 | KeReleaseSpinLock(&m_lock, m_oldIrql); 18 | } 19 | 20 | void QueuedSpinLock::Init() { 21 | KeInitializeSpinLock(&m_lock); 22 | } 23 | 24 | void QueuedSpinLock::Lock() { 25 | KeAcquireInStackQueuedSpinLock(&m_lock, &m_handle); 26 | } 27 | 28 | void QueuedSpinLock::Unlock() { 29 | KeReleaseInStackQueuedSpinLock(&m_handle); 30 | } 31 | 32 | -------------------------------------------------------------------------------- /Chapter13/ProcessNetFilter/SpinLock.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef KTL_NAMESPACE 4 | namespace ktl { 5 | #endif 6 | 7 | struct SpinLock { 8 | void Init(); 9 | void Lock(); 10 | void Unlock(); 11 | 12 | private: 13 | KSPIN_LOCK m_lock; 14 | KIRQL m_oldIrql; 15 | }; 16 | 17 | struct QueuedSpinLock { 18 | void Init(); 19 | void Lock(); 20 | void Unlock(); 21 | 22 | private: 23 | KLOCK_QUEUE_HANDLE m_handle; 24 | KSPIN_LOCK m_lock; 25 | }; 26 | #ifdef KTL_NAMESPACE 27 | } 28 | #endif 29 | -------------------------------------------------------------------------------- /Chapter13/ProcessNetFilter/pch.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | -------------------------------------------------------------------------------- /Chapter13/ProcessNetFilter/pch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #define NDIS_MINIPORT_DRIVER 1 5 | #define NDIS630_MINIPORT 1 6 | #include 7 | -------------------------------------------------------------------------------- /Chapter13/wfpfilters/wfpfilters.cpp: -------------------------------------------------------------------------------- 1 | // wfpfilters.cpp : This file contains the 'main' function. Program execution begins and ends there. 2 | // 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #pragma comment(lib, "Fwpuclnt") 10 | 11 | int Error(const char* text, DWORD error) { 12 | printf("%s (%u)\n", text, error); 13 | return 1; 14 | } 15 | 16 | std::wstring GuidToString(GUID const& guid) { 17 | WCHAR sguid[64]; 18 | return ::StringFromGUID2(guid, sguid, _countof(sguid)) ? sguid : L""; 19 | } 20 | 21 | const char* ActionToString(FWPM_ACTION const& action) { 22 | switch (action.type) { 23 | case FWP_ACTION_BLOCK: return "Block"; 24 | case FWP_ACTION_PERMIT: return "Permit"; 25 | case FWP_ACTION_CALLOUT_TERMINATING: return "Callout Terminating"; 26 | case FWP_ACTION_CALLOUT_INSPECTION: return "Callout Inspection"; 27 | case FWP_ACTION_CALLOUT_UNKNOWN: return "Callout Unknown"; 28 | case FWP_ACTION_CONTINUE: return "Continue"; 29 | case FWP_ACTION_NONE: return "None"; 30 | case FWP_ACTION_NONE_NO_MATCH: return "None (No Match)"; 31 | } 32 | return ""; 33 | } 34 | 35 | int main() { 36 | HANDLE hEngine; 37 | DWORD error = FwpmEngineOpen(nullptr, RPC_C_AUTHN_DEFAULT, nullptr, nullptr, &hEngine); 38 | if (error) 39 | return Error("Failed to open engine", error); 40 | 41 | HANDLE hEnum; 42 | error = FwpmFilterCreateEnumHandle(hEngine, nullptr, &hEnum); 43 | if (error) 44 | return Error("Failed to create filter enum handle", error); 45 | 46 | UINT32 count; 47 | FWPM_FILTER** filters; 48 | error = FwpmFilterEnum(hEngine, hEnum, 8192, &filters, &count); 49 | if (error) 50 | return Error("Failed to enumerate filters", error); 51 | 52 | for (UINT32 i = 0; i < count; i++) { 53 | auto f = filters[i]; 54 | printf("%ws Name: %-40ws Id: 0x%016llX Conditions: %2u Action: %s\n", 55 | GuidToString(f->filterKey).c_str(), 56 | f->displayData.name, 57 | f->filterId, 58 | f->numFilterConditions, 59 | ActionToString(f->action)); 60 | } 61 | FwpmFreeMemory((void**)&filters); 62 | FwpmFilterDestroyEnumHandle(hEngine, hEnum); 63 | FwpmEngineClose(hEngine); 64 | 65 | return 0; 66 | } 67 | -------------------------------------------------------------------------------- /Chapter13/wfpfilters/wfpfilters.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;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 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Chapter14/Boost/Boost.cpp: -------------------------------------------------------------------------------- 1 | // Boost.cpp : This file contains the 'main' function. Program execution begins and ends there. 2 | // 3 | 4 | #include 5 | #include 6 | #include 7 | #include "..\Booster\BoosterCommon.h" 8 | #include 9 | 10 | #pragma comment(lib, "setupapi") 11 | 12 | std::wstring FindBoosterDevice() { 13 | HDEVINFO hDevInfo = SetupDiGetClassDevs(&GUID_Booster, nullptr, nullptr, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); 14 | if (!hDevInfo) 15 | return L""; 16 | 17 | std::wstring result; 18 | do { 19 | SP_DEVINFO_DATA data{ sizeof(data) }; 20 | if (!SetupDiEnumDeviceInfo(hDevInfo, 0, &data)) 21 | break; 22 | 23 | SP_DEVICE_INTERFACE_DATA idata{ sizeof(idata) }; 24 | if (!SetupDiEnumDeviceInterfaces(hDevInfo, &data, &GUID_Booster, 0, &idata)) 25 | break; 26 | 27 | BYTE buffer[1024]; 28 | auto detail = (PSP_DEVICE_INTERFACE_DETAIL_DATA)buffer; 29 | detail->cbSize = sizeof(*detail); 30 | if (SetupDiGetDeviceInterfaceDetail(hDevInfo, &idata, detail, sizeof(buffer), nullptr, &data)) 31 | result = detail->DevicePath; 32 | } while (false); 33 | SetupDiDestroyDeviceInfoList(hDevInfo); 34 | return result; 35 | } 36 | 37 | int main(int argc, const char* argv[]) { 38 | if (argc < 3) { 39 | printf("Usage: boost \n"); 40 | return 0; 41 | } 42 | 43 | auto name = FindBoosterDevice(); 44 | if (name.empty()) { 45 | printf("Unable to locate Booster device\n"); 46 | return 1; 47 | } 48 | 49 | HANDLE hDevice = CreateFile(name.c_str(), GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, 0, nullptr); 50 | if (hDevice == INVALID_HANDLE_VALUE) { 51 | printf("Error: %u\n", GetLastError()); 52 | return 1; 53 | } 54 | 55 | ThreadData data; 56 | data.ThreadId = atoi(argv[1]); 57 | data.Priority = atoi(argv[2]); 58 | 59 | DWORD bytes; 60 | if (DeviceIoControl(hDevice, IOCTL_BOOSTER_SET_PRIORITY, 61 | &data, sizeof(data), nullptr, 0, &bytes, nullptr)) 62 | printf("Success!\n"); 63 | else 64 | printf("Error: %u\n", GetLastError()); 65 | 66 | CloseHandle(hDevice); 67 | return 0; 68 | } 69 | 70 | -------------------------------------------------------------------------------- /Chapter14/Boost/Boost.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;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 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Chapter14/Booster/Booster.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "BoosterCommon.h" 4 | 5 | NTSTATUS BoosterDeviceAdd(WDFDRIVER Driver, PWDFDEVICE_INIT DeviceInit); 6 | 7 | VOID BoosterDeviceControl( 8 | _In_ WDFQUEUE Queue, 9 | _In_ WDFREQUEST Request, 10 | _In_ size_t OutputBufferLength, 11 | _In_ size_t InputBufferLength, 12 | _In_ ULONG IoControlCode); 13 | 14 | 15 | extern "C" 16 | NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) { 17 | WDF_DRIVER_CONFIG config; 18 | WDF_DRIVER_CONFIG_INIT(&config, BoosterDeviceAdd); 19 | return WdfDriverCreate(DriverObject, RegistryPath, WDF_NO_OBJECT_ATTRIBUTES, &config, WDF_NO_HANDLE); 20 | } 21 | 22 | NTSTATUS BoosterDeviceAdd(WDFDRIVER Driver, PWDFDEVICE_INIT DeviceInit) { 23 | UNREFERENCED_PARAMETER(Driver); 24 | WDFDEVICE device; 25 | auto status = WdfDeviceCreate(&DeviceInit, WDF_NO_OBJECT_ATTRIBUTES, &device); 26 | if (!NT_SUCCESS(status)) 27 | return status; 28 | 29 | status = WdfDeviceCreateDeviceInterface(device, &GUID_Booster, nullptr); 30 | if (!NT_SUCCESS(status)) 31 | return status; 32 | 33 | WDF_IO_QUEUE_CONFIG config; 34 | WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&config, WdfIoQueueDispatchParallel); 35 | config.EvtIoDeviceControl = BoosterDeviceControl; 36 | 37 | WDFQUEUE queue; 38 | status = WdfIoQueueCreate(device, &config, WDF_NO_OBJECT_ATTRIBUTES, &queue); 39 | 40 | return status; 41 | } 42 | 43 | _Use_decl_annotations_ 44 | VOID BoosterDeviceControl(WDFQUEUE Queue, WDFREQUEST Request, size_t OutputBufferLength, size_t InputBufferLength, ULONG IoControlCode) { 45 | UNREFERENCED_PARAMETER(InputBufferLength); 46 | UNREFERENCED_PARAMETER(OutputBufferLength); 47 | UNREFERENCED_PARAMETER(Queue); 48 | 49 | auto status = STATUS_INVALID_DEVICE_REQUEST; 50 | ULONG info = 0; 51 | 52 | switch (IoControlCode) { 53 | case IOCTL_BOOSTER_SET_PRIORITY: 54 | ThreadData* data; 55 | status = WdfRequestRetrieveInputBuffer(Request, sizeof(ThreadData), (PVOID*)&data, nullptr); 56 | if (!NT_SUCCESS(status)) 57 | break; 58 | 59 | if (data->Priority < 1 || data->Priority > 31) { 60 | status = STATUS_INVALID_PARAMETER; 61 | break; 62 | } 63 | 64 | PKTHREAD thread; 65 | status = PsLookupThreadByThreadId(UlongToHandle(data->ThreadId), &thread); 66 | if (!NT_SUCCESS(status)) 67 | break; 68 | 69 | KeSetPriorityThread(thread, data->Priority); 70 | ObDereferenceObject(thread); 71 | info = sizeof(ThreadData); 72 | break; 73 | } 74 | WdfRequestCompleteWithInformation(Request, status, info); 75 | } 76 | -------------------------------------------------------------------------------- /Chapter14/Booster/Booster.inf: -------------------------------------------------------------------------------- 1 | ; 2 | ; Booster.inf 3 | ; 4 | 5 | [Version] 6 | Signature="$WINDOWS NT$" 7 | Class=System ; TODO: specify appropriate Class 8 | ClassGuid={4d36e97d-e325-11ce-bfc1-08002be10318} ; TODO: specify appropriate ClassGuid 9 | Provider=%ManufacturerName% 10 | CatalogFile=Booster.cat 11 | DriverVer= ; TODO: set DriverVer in stampinf property pages 12 | PnpLockdown=1 13 | 14 | [DestinationDirs] 15 | DefaultDestDir = 12 16 | Booster_Device_CoInstaller_CopyFiles = 11 17 | 18 | [SourceDisksNames] 19 | 1 = %DiskName%,,,"" 20 | 21 | [SourceDisksFiles] 22 | Booster.sys = 1,, 23 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll=1 ; make sure the number matches with SourceDisksNames 24 | 25 | ;***************************************** 26 | ; Install Section 27 | ;***************************************** 28 | 29 | [Manufacturer] 30 | %ManufacturerName%=Standard,NT$ARCH$ 31 | 32 | [Standard.NT$ARCH$] 33 | %Booster.DeviceDesc%=Booster_Device, Root\Booster ; TODO: edit hw-id 34 | 35 | [Booster_Device.NT] 36 | CopyFiles=Drivers_Dir 37 | 38 | [Drivers_Dir] 39 | Booster.sys 40 | 41 | ;-------------- Service installation 42 | [Booster_Device.NT.Services] 43 | AddService = Booster,%SPSVCINST_ASSOCSERVICE%, Booster_Service_Inst 44 | 45 | ; -------------- Booster driver install sections 46 | [Booster_Service_Inst] 47 | DisplayName = %Booster.SVCDESC% 48 | ServiceType = 1 ; SERVICE_KERNEL_DRIVER 49 | StartType = 3 ; SERVICE_DEMAND_START 50 | ErrorControl = 1 ; SERVICE_ERROR_NORMAL 51 | ServiceBinary = %12%\Booster.sys 52 | 53 | ; 54 | ;--- Booster_Device Coinstaller installation ------ 55 | ; 56 | 57 | [Booster_Device.NT.CoInstallers] 58 | AddReg=Booster_Device_CoInstaller_AddReg 59 | CopyFiles=Booster_Device_CoInstaller_CopyFiles 60 | 61 | [Booster_Device_CoInstaller_AddReg] 62 | HKR,,CoInstallers32,0x00010000, "WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll,WdfCoInstaller" 63 | 64 | [Booster_Device_CoInstaller_CopyFiles] 65 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll 66 | 67 | [Booster_Device.NT.Wdf] 68 | KmdfService = Booster, Booster_wdfsect 69 | [Booster_wdfsect] 70 | KmdfLibraryVersion = $KMDFVERSION$ 71 | 72 | [Strings] 73 | SPSVCINST_ASSOCSERVICE= 0x00000002 74 | ManufacturerName="Pavel Yosifovich" ;TODO: Replace with your manufacturer name 75 | DiskName = "Booster Installation Disk" 76 | Booster.DeviceDesc = "Booster Device" 77 | Booster.SVCDESC = "Booster Service" 78 | -------------------------------------------------------------------------------- /Chapter14/Booster/Booster.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 | Driver Files 24 | 25 | 26 | 27 | 28 | Source Files 29 | 30 | 31 | 32 | 33 | Header Files 34 | 35 | 36 | -------------------------------------------------------------------------------- /Chapter14/Booster/BoosterCommon.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #define BOOSTER_DEVICE 0x8001 6 | 7 | #define IOCTL_BOOSTER_SET_PRIORITY CTL_CODE(BOOSTER_DEVICE, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS) 8 | 9 | struct ThreadData { 10 | ULONG ThreadId; 11 | int Priority; 12 | }; 13 | 14 | // {49BDF7E8-8AD1-4852-9FB6-833279A1545F} 15 | DEFINE_GUID(GUID_Booster, 0x49bdf7e8, 0x8ad1, 0x4852, 0x9f, 0xb6, 0x83, 0x32, 0x79, 0xa1, 0x54, 0x5f); 16 | -------------------------------------------------------------------------------- /Chapter14/Booster2/Booster.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "BoosterCommon.h" 4 | 5 | NTSTATUS BoosterDeviceAdd(WDFDRIVER Driver, PWDFDEVICE_INIT DeviceInit); 6 | 7 | VOID BoosterDeviceControl( 8 | _In_ WDFQUEUE Queue, 9 | _In_ WDFREQUEST Request, 10 | _In_ size_t OutputBufferLength, 11 | _In_ size_t InputBufferLength, 12 | _In_ ULONG IoControlCode); 13 | 14 | 15 | extern "C" 16 | NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) { 17 | WDF_DRIVER_CONFIG config; 18 | WDF_DRIVER_CONFIG_INIT(&config, BoosterDeviceAdd); 19 | return WdfDriverCreate(DriverObject, RegistryPath, WDF_NO_OBJECT_ATTRIBUTES, &config, WDF_NO_HANDLE); 20 | } 21 | 22 | NTSTATUS BoosterDeviceAdd(WDFDRIVER Driver, PWDFDEVICE_INIT DeviceInit) { 23 | UNREFERENCED_PARAMETER(Driver); 24 | WDFDEVICE device; 25 | auto status = WdfDeviceCreate(&DeviceInit, WDF_NO_OBJECT_ATTRIBUTES, &device); 26 | if (!NT_SUCCESS(status)) 27 | return status; 28 | 29 | status = WdfDeviceCreateDeviceInterface(device, &GUID_Booster, nullptr); 30 | if (!NT_SUCCESS(status)) 31 | return status; 32 | 33 | WDF_IO_QUEUE_CONFIG config; 34 | WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&config, WdfIoQueueDispatchParallel); 35 | config.EvtIoDeviceControl = BoosterDeviceControl; 36 | 37 | WDFQUEUE queue; 38 | status = WdfIoQueueCreate(device, &config, WDF_NO_OBJECT_ATTRIBUTES, &queue); 39 | 40 | return status; 41 | } 42 | 43 | _Use_decl_annotations_ 44 | VOID BoosterDeviceControl(WDFQUEUE Queue, WDFREQUEST Request, size_t OutputBufferLength, size_t InputBufferLength, ULONG IoControlCode) { 45 | UNREFERENCED_PARAMETER(InputBufferLength); 46 | UNREFERENCED_PARAMETER(OutputBufferLength); 47 | UNREFERENCED_PARAMETER(Queue); 48 | 49 | auto status = STATUS_INVALID_DEVICE_REQUEST; 50 | ULONG info = 0; 51 | 52 | switch (IoControlCode) { 53 | case IOCTL_BOOSTER_SET_PRIORITY: 54 | ThreadData* data; 55 | status = WdfRequestRetrieveInputBuffer(Request, sizeof(ThreadData), (PVOID*)&data, nullptr); 56 | if (!NT_SUCCESS(status)) 57 | break; 58 | 59 | if (data->Priority < 1 || data->Priority > 31) { 60 | status = STATUS_INVALID_PARAMETER; 61 | break; 62 | } 63 | 64 | PKTHREAD thread; 65 | status = PsLookupThreadByThreadId(UlongToHandle(data->ThreadId), &thread); 66 | if (!NT_SUCCESS(status)) 67 | break; 68 | 69 | KeSetPriorityThread(thread, data->Priority); 70 | ObDereferenceObject(thread); 71 | info = sizeof(ThreadData); 72 | break; 73 | } 74 | WdfRequestCompleteWithInformation(Request, status, info); 75 | } 76 | -------------------------------------------------------------------------------- /Chapter14/Booster2/Booster2.inf: -------------------------------------------------------------------------------- 1 | ; 2 | ; Booster2.inf 3 | ; 4 | 5 | [Version] 6 | Signature="$WINDOWS NT$" 7 | Class=BoosterDevice 8 | ClassGuid={AE4151AF-8C29-41C3-BB16-0B3115733333} 9 | Provider=%ManufacturerName% 10 | CatalogFile=Booster2.cat 11 | DriverVer= ; TODO: set DriverVer in stampinf property pages 12 | PnpLockdown=1 13 | 14 | [DestinationDirs] 15 | DefaultDestDir = 12 16 | Booster2_Device_CoInstaller_CopyFiles = 11 17 | 18 | [SourceDisksNames] 19 | 1 = %DiskName%,,,"" 20 | 21 | [SourceDisksFiles] 22 | Booster2.sys = 1,, 23 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll=1 ; make sure the number matches with SourceDisksNames 24 | 25 | ; define new device class 26 | [ClassInstall32] 27 | AddReg=DevClass_AddReg 28 | 29 | [DevClass_AddReg] 30 | HKR,,,,BoosterDevice 31 | HKR,,SilentInstall,,1 32 | 33 | ;***************************************** 34 | ; Install Section 35 | ;***************************************** 36 | 37 | [Manufacturer] 38 | %ManufacturerName%=Standard,NT$ARCH$ 39 | 40 | [Standard.NT$ARCH$] 41 | %Booster2.DeviceDesc%=Booster2_Device, Root\Booster2 ; TODO: edit hw-id 42 | 43 | [Booster2_Device.NT] 44 | CopyFiles=Drivers_Dir 45 | 46 | [Drivers_Dir] 47 | Booster2.sys 48 | 49 | ;-------------- Service installation 50 | [Booster2_Device.NT.Services] 51 | AddService = Booster2,%SPSVCINST_ASSOCSERVICE%, Booster2_Service_Inst 52 | 53 | ; -------------- Booster2 driver install sections 54 | [Booster2_Service_Inst] 55 | DisplayName = %Booster2.SVCDESC% 56 | ServiceType = 1 ; SERVICE_KERNEL_DRIVER 57 | StartType = 3 ; SERVICE_DEMAND_START 58 | ErrorControl = 1 ; SERVICE_ERROR_NORMAL 59 | ServiceBinary = %12%\Booster2.sys 60 | 61 | ; 62 | ;--- Booster2_Device Coinstaller installation ------ 63 | ; 64 | 65 | [Booster2_Device.NT.CoInstallers] 66 | AddReg=Booster2_Device_CoInstaller_AddReg 67 | CopyFiles=Booster2_Device_CoInstaller_CopyFiles 68 | 69 | [Booster2_Device_CoInstaller_AddReg] 70 | HKR,,CoInstallers32,0x00010000, "WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll,WdfCoInstaller" 71 | 72 | [Booster2_Device_CoInstaller_CopyFiles] 73 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll 74 | 75 | [Booster2_Device.NT.Wdf] 76 | KmdfService = Booster2, Booster2_wdfsect 77 | [Booster2_wdfsect] 78 | KmdfLibraryVersion = $KMDFVERSION$ 79 | 80 | [Strings] 81 | SPSVCINST_ASSOCSERVICE= 0x00000002 82 | ManufacturerName="" ;TODO: Replace with your manufacturer name 83 | DiskName = "Booster2 Installation Disk" 84 | Booster2.DeviceDesc = "Booster2 Device" 85 | Booster2.SVCDESC = "Booster2 Service" 86 | -------------------------------------------------------------------------------- /Chapter14/Booster2/Booster2.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 | Driver Files 24 | 25 | 26 | 27 | 28 | Source Files 29 | 30 | 31 | 32 | 33 | Header Files 34 | 35 | 36 | -------------------------------------------------------------------------------- /Chapter14/Booster2/BoosterCommon.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #define BOOSTER_DEVICE 0x8001 6 | 7 | #define IOCTL_BOOSTER_SET_PRIORITY CTL_CODE(BOOSTER_DEVICE, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS) 8 | 9 | struct ThreadData { 10 | ULONG ThreadId; 11 | int Priority; 12 | }; 13 | 14 | // {49BDF7E8-8AD1-4852-9FB6-833279A1545F} 15 | DEFINE_GUID(GUID_Booster, 0x49bdf7e8, 0x8ad1, 0x4852, 0x9f, 0xb6, 0x83, 0x32, 0x79, 0xa1, 0x54, 0x5f); 16 | 17 | -------------------------------------------------------------------------------- /Chapter15/DevMon/DevMon.cpp: -------------------------------------------------------------------------------- 1 | // DevMon.cpp : This file contains the 'main' function. Program execution begins and ends there. 2 | // 3 | 4 | #include "pch.h" 5 | #include "..\KDevMon\KDevMonCommon.h" 6 | 7 | int Usage() { 8 | printf("Devmon.exe [args]\n"); 9 | printf("Commands:\n"); 10 | printf("\tadd (adds a device to monitor)\n"); 11 | printf("\tremove (remove device from monitoring)\n"); 12 | printf("\tclear (remove all devices)\n"); 13 | 14 | return 0; 15 | } 16 | 17 | int Error(const char* text) { 18 | printf("%s (%d)\n", text, GetLastError()); 19 | return 1; 20 | } 21 | 22 | int wmain(int argc, wchar_t* argv[]) { 23 | if (argc < 2) 24 | return Usage(); 25 | 26 | auto const cmd = argv[1]; 27 | 28 | HANDLE hDevice = CreateFile(L"\\\\.\\kdevmon", GENERIC_READ | GENERIC_WRITE, 29 | 0, nullptr, OPEN_EXISTING, 0, nullptr); 30 | if (hDevice == INVALID_HANDLE_VALUE) 31 | return Error("Failed to open device"); 32 | 33 | DWORD bytes; 34 | if (_wcsicmp(cmd, L"add") == 0) { 35 | if (!DeviceIoControl(hDevice, IOCTL_DEVMON_ADD_DEVICE, argv[2], 36 | static_cast(wcslen(argv[2]) + 1) * sizeof(WCHAR), nullptr, 0, &bytes, nullptr)) 37 | return Error("Failed in add device"); 38 | printf("Add device %ws successful.\n", argv[2]); 39 | return 0; 40 | } 41 | else if (_wcsicmp(cmd, L"remove") == 0) { 42 | if (!DeviceIoControl(hDevice, IOCTL_DEVMON_REMOVE_DEVICE, argv[2], 43 | DWORD(wcslen(argv[2]) + 1) * sizeof(WCHAR), nullptr, 0, &bytes, nullptr)) 44 | return Error("Failed in remove device"); 45 | printf("Remove device %ws successful.\n", argv[2]); 46 | return 0; 47 | } 48 | else if (_wcsicmp(cmd, L"clear") == 0) { 49 | if (!DeviceIoControl(hDevice, IOCTL_DEVMON_REMOVE_ALL, 50 | nullptr, 0, nullptr, 0, &bytes, nullptr)) 51 | return Error("Failed in remove all devices"); 52 | printf("Removed all devices successful.\n"); 53 | } 54 | else { 55 | printf("Unknown command.\n"); 56 | return Usage(); 57 | } 58 | 59 | return 0; 60 | } 61 | -------------------------------------------------------------------------------- /Chapter15/DevMon/DevMon.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;hh;hpp;hxx;hm;inl;inc;ipp;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 | 18 | 19 | Header Files 20 | 21 | 22 | 23 | 24 | Source Files 25 | 26 | 27 | Source Files 28 | 29 | 30 | -------------------------------------------------------------------------------- /Chapter15/DevMon/pch.cpp: -------------------------------------------------------------------------------- 1 | // pch.cpp: source file corresponding to pre-compiled header; necessary for compilation to succeed 2 | 3 | #include "pch.h" 4 | 5 | // In general, ignore this file, but keep it around if you are using pre-compiled headers. 6 | -------------------------------------------------------------------------------- /Chapter15/DevMon/pch.h: -------------------------------------------------------------------------------- 1 | // Tips for Getting Started: 2 | // 1. Use the Solution Explorer window to add/manage files 3 | // 2. Use the Team Explorer window to connect to source control 4 | // 3. Use the Output window to see build output and other messages 5 | // 4. Use the Error List window to view errors 6 | // 5. Go to Project > Add New Item to create new code files, or Project > Add Existing Item to add existing code files to the project 7 | // 6. In the future, to open this project again, go to File > Open > Project and select the .sln file 8 | 9 | #ifndef PCH_H 10 | #define PCH_H 11 | 12 | #include 13 | #include 14 | 15 | 16 | #endif //PCH_H 17 | -------------------------------------------------------------------------------- /Chapter15/KDevMon/DevMonManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "FastMutex.h" 4 | 5 | const int MaxMonitoredDevices = 32; 6 | 7 | struct MonitoredDevice { 8 | UNICODE_STRING DeviceName; 9 | PDEVICE_OBJECT DeviceObject; 10 | PDEVICE_OBJECT LowerDeviceObject; 11 | }; 12 | 13 | struct DeviceExtension { 14 | PDEVICE_OBJECT LowerDeviceObject; 15 | }; 16 | 17 | class DevMonManager { 18 | public: 19 | void Init(PDRIVER_OBJECT DriverObject); 20 | NTSTATUS AddDevice(PCWSTR name); 21 | int FindDevice(PCWSTR name) const; 22 | bool RemoveDevice(PCWSTR name); 23 | void RemoveAllDevices(); 24 | 25 | PDEVICE_OBJECT CDO; 26 | 27 | private: 28 | bool RemoveDevice(int index); 29 | 30 | private: 31 | MonitoredDevice Devices[MaxMonitoredDevices]; 32 | int MonitoredDeviceCount; 33 | FastMutex Lock; 34 | PDRIVER_OBJECT DriverObject; 35 | }; 36 | 37 | -------------------------------------------------------------------------------- /Chapter15/KDevMon/ExecutiveResource.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "ExecutiveResource.h" 3 | 4 | ExecutiveResource::~ExecutiveResource() { 5 | ExDeleteResourceLite(&_resource); 6 | } 7 | 8 | void ExecutiveResource::Init() { 9 | ExInitializeResourceLite(&_resource); 10 | } 11 | 12 | void ExecutiveResource::Lock() { 13 | ExAcquireResourceExclusiveLite(&_resource, TRUE); 14 | } 15 | 16 | void ExecutiveResource::Unlock() { 17 | ExReleaseResourceLite(&_resource); 18 | } 19 | 20 | void ExecutiveResource::LockShared() { 21 | ExAcquireResourceSharedLite(&_resource, TRUE); 22 | } 23 | 24 | void ExecutiveResource::UnlockShared() { 25 | ExAcquireResourceSharedLite(&_resource, TRUE); 26 | } 27 | -------------------------------------------------------------------------------- /Chapter15/KDevMon/ExecutiveResource.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class ExecutiveResource { 4 | public: 5 | ~ExecutiveResource(); 6 | 7 | void Init(); 8 | void Lock(); 9 | void Unlock(); 10 | void LockShared(); 11 | void UnlockShared(); 12 | 13 | private: 14 | ERESOURCE _resource; 15 | }; 16 | 17 | -------------------------------------------------------------------------------- /Chapter15/KDevMon/FastMutex.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "FastMutex.h" 3 | 4 | 5 | void FastMutex::Init() { 6 | ExInitializeFastMutex(&_mutex); 7 | } 8 | 9 | void FastMutex::Lock() { 10 | ExAcquireFastMutex(&_mutex); 11 | } 12 | 13 | void FastMutex::Unlock() { 14 | ExReleaseFastMutex(&_mutex); 15 | } 16 | -------------------------------------------------------------------------------- /Chapter15/KDevMon/FastMutex.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | class FastMutex { 6 | public: 7 | void Init(); 8 | 9 | void Lock(); 10 | void Unlock(); 11 | 12 | private: 13 | FAST_MUTEX _mutex; 14 | }; 15 | 16 | -------------------------------------------------------------------------------- /Chapter15/KDevMon/KDevMon.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define DRIVER_TAG 'nmvD' 4 | -------------------------------------------------------------------------------- /Chapter15/KDevMon/KDevMon.inf: -------------------------------------------------------------------------------- 1 | ; 2 | ; KDevMon.inf 3 | ; 4 | 5 | [Version] 6 | Signature="$WINDOWS NT$" 7 | Class=System 8 | ClassGuid={4d36e97d-e325-11ce-bfc1-08002be10318} 9 | Provider=%ManufacturerName% 10 | DriverVer= 11 | CatalogFile=KDevMon.cat 12 | 13 | [DestinationDirs] 14 | DefaultDestDir = 12 15 | 16 | 17 | [SourceDisksNames] 18 | 1 = %DiskName%,,,"" 19 | 20 | [SourceDisksFiles] 21 | 22 | 23 | [Manufacturer] 24 | %ManufacturerName%=Standard,NT$ARCH$ 25 | 26 | [Standard.NT$ARCH$] 27 | 28 | 29 | [Strings] 30 | ManufacturerName="" ;TODO: Replace with your manufacturer name 31 | ClassName="" 32 | DiskName="KDevMon Source Disk" 33 | -------------------------------------------------------------------------------- /Chapter15/KDevMon/KDevMon.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 | Header Files 24 | 25 | 26 | Header Files 27 | 28 | 29 | Header Files 30 | 31 | 32 | Header Files 33 | 34 | 35 | Header Files 36 | 37 | 38 | Header Files 39 | 40 | 41 | 42 | 43 | Source Files 44 | 45 | 46 | Source Files 47 | 48 | 49 | Source Files 50 | 51 | 52 | Source Files 53 | 54 | 55 | Source Files 56 | 57 | 58 | -------------------------------------------------------------------------------- /Chapter15/KDevMon/KDevMonCommon.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define DEVMON_DEVICE 0x8004 4 | 5 | #define IOCTL_DEVMON_ADD_DEVICE CTL_CODE(DEVMON_DEVICE, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS) 6 | #define IOCTL_DEVMON_REMOVE_DEVICE CTL_CODE(DEVMON_DEVICE, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS) 7 | #define IOCTL_DEVMON_REMOVE_ALL CTL_CODE(DEVMON_DEVICE, 0x802, METHOD_NEITHER, FILE_ANY_ACCESS) 8 | #define IOCTL_DEVMON_START_MONITOR CTL_CODE(DEVMON_DEVICE, 0x803, METHOD_NEITHER, FILE_ANY_ACCESS) 9 | #define IOCTL_DEVMON_STOP_MONITOR CTL_CODE(DEVMON_DEVICE, 0x804, METHOD_NEITHER, FILE_ANY_ACCESS) 10 | #define IOCTL_DEVMON_ADD_DRIVER CTL_CODE(DEVMON_DEVICE, 0x805, METHOD_BUFFERED, FILE_ANY_ACCESS) 11 | #define IOCTL_DEVMON_REMOVE_DRIVER CTL_CODE(DEVMON_DEVICE, 0x806, METHOD_BUFFERED, FILE_ANY_ACCESS) 12 | -------------------------------------------------------------------------------- /Chapter15/KDevMon/Locker.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | template 4 | struct Locker { 5 | Locker(TLock& lock) : m_lock(lock) { 6 | m_lock.Lock(); 7 | } 8 | 9 | ~Locker() { 10 | m_lock.Unlock(); 11 | } 12 | 13 | private: 14 | TLock& m_lock; 15 | }; 16 | -------------------------------------------------------------------------------- /Chapter15/KDevMon/pch.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | 3 | -------------------------------------------------------------------------------- /Chapter15/KDevMon/pch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021-2022 Pavel Yosifovich 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Windows Kernel Programming second edition book samples 2 | 3 | See book at https://leanpub.com/windowskernelprogrammingsecondedition 4 | 5 | -------------------------------------------------------------------------------- /Tools/dbgkflt.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zodiacon/windowskernelprogrammingbook2e/94c3bbd049b6d79c7f02a699418a55a29aeab588/Tools/dbgkflt.exe -------------------------------------------------------------------------------- /ktl/ktl/EResource.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "EResource.h" 3 | 4 | #ifdef KTL_NAMESPACE 5 | using namespace ktl; 6 | #endif 7 | 8 | 9 | void ExecutiveResource::Init() { 10 | ExInitializeResourceLite(&m_Res); 11 | } 12 | 13 | void ExecutiveResource::Delete() { 14 | ExDeleteResourceLite(&m_Res); 15 | } 16 | 17 | void ExecutiveResource::Lock() { 18 | ExEnterCriticalRegionAndAcquireResourceExclusive(&m_Res); 19 | } 20 | 21 | void ExecutiveResource::Unlock() { 22 | ExReleaseResourceAndLeaveCriticalRegion(&m_Res); 23 | } 24 | 25 | void ExecutiveResource::LockShared() { 26 | ExEnterCriticalRegionAndAcquireResourceShared(&m_Res); 27 | } 28 | 29 | void ExecutiveResource::UnlockShared() { 30 | Unlock(); 31 | } 32 | -------------------------------------------------------------------------------- /ktl/ktl/EResource.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef KTL_NAMESPACE 4 | namespace ktl { 5 | #endif 6 | 7 | class ExecutiveResource { 8 | public: 9 | void Init(); 10 | void Delete(); 11 | 12 | void Lock(); 13 | void Unlock(); 14 | 15 | void LockShared(); 16 | void UnlockShared(); 17 | 18 | private: 19 | ERESOURCE m_Res; 20 | }; 21 | 22 | #ifdef KTL_NAMESPACE 23 | } 24 | #endif 25 | -------------------------------------------------------------------------------- /ktl/ktl/FastMutex.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "FastMutex.h" 3 | 4 | #ifdef KTL_NAMESPACE 5 | using namespace ktl; 6 | #endif 7 | 8 | void FastMutex::Init() { 9 | ExInitializeFastMutex(&m_Mutex); 10 | } 11 | 12 | void FastMutex::Lock() { 13 | ExAcquireFastMutex(&m_Mutex); 14 | } 15 | 16 | void FastMutex::Unlock() { 17 | ExReleaseFastMutex(&m_Mutex); 18 | } 19 | 20 | -------------------------------------------------------------------------------- /ktl/ktl/FastMutex.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef KTL_NAMESPACE 4 | namespace ktl { 5 | #endif 6 | 7 | struct FastMutex { 8 | void Init(); 9 | void Lock(); 10 | void Unlock(); 11 | 12 | private: 13 | FAST_MUTEX m_Mutex; 14 | }; 15 | 16 | #ifdef KTL_NAMESPACE 17 | } 18 | #endif 19 | 20 | -------------------------------------------------------------------------------- /ktl/ktl/FilterFileNameInformation.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "FilterFileNameInformation.h" 3 | 4 | #ifdef KTL_NAMESPACE 5 | using namespace ktl; 6 | #endif 7 | 8 | FilterFileNameInformation::FilterFileNameInformation(PFLT_CALLBACK_DATA data, FileNameOptions options) { 9 | auto status = FltGetFileNameInformation(data, (FLT_FILE_NAME_OPTIONS)options, &m_info); 10 | if (!NT_SUCCESS(status)) 11 | m_info = nullptr; 12 | } 13 | 14 | FilterFileNameInformation::~FilterFileNameInformation() { 15 | if (m_info) 16 | FltReleaseFileNameInformation(m_info); 17 | } 18 | 19 | NTSTATUS FilterFileNameInformation::Parse() { 20 | return FltParseFileNameInformation(m_info); 21 | } 22 | -------------------------------------------------------------------------------- /ktl/ktl/FilterFileNameInformation.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef KTL_NAMESPACE 4 | using namespace ktl; 5 | #endif 6 | 7 | enum class FileNameOptions { 8 | Normalized = FLT_FILE_NAME_NORMALIZED, 9 | Opened = FLT_FILE_NAME_OPENED, 10 | Short = FLT_FILE_NAME_SHORT, 11 | 12 | QueryDefault = FLT_FILE_NAME_QUERY_DEFAULT, 13 | QueryCacheOnly = FLT_FILE_NAME_QUERY_CACHE_ONLY, 14 | QueryFileSystemOnly = FLT_FILE_NAME_QUERY_FILESYSTEM_ONLY, 15 | 16 | RequestFromCurrentProvider = FLT_FILE_NAME_REQUEST_FROM_CURRENT_PROVIDER, 17 | DoNotCache = FLT_FILE_NAME_DO_NOT_CACHE, 18 | AllowQueryOnReparse = FLT_FILE_NAME_ALLOW_QUERY_ON_REPARSE 19 | }; 20 | DEFINE_ENUM_FLAG_OPERATORS(FileNameOptions); 21 | 22 | struct FilterFileNameInformation { 23 | FilterFileNameInformation(PFLT_CALLBACK_DATA data, FileNameOptions options = FileNameOptions::QueryDefault | FileNameOptions::Normalized); 24 | ~FilterFileNameInformation(); 25 | 26 | operator bool() const { 27 | return m_info != nullptr; 28 | } 29 | 30 | PFLT_FILE_NAME_INFORMATION Get() const { 31 | return m_info; 32 | } 33 | 34 | operator PFLT_FILE_NAME_INFORMATION() const { 35 | return Get(); 36 | } 37 | 38 | PFLT_FILE_NAME_INFORMATION operator->() { 39 | return m_info; 40 | } 41 | 42 | NTSTATUS Parse(); 43 | 44 | private: 45 | PFLT_FILE_NAME_INFORMATION m_info; 46 | }; 47 | 48 | #ifdef KTL_NAMESPACE 49 | } 50 | #endif 51 | 52 | -------------------------------------------------------------------------------- /ktl/ktl/KernelHandle.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "KernelHandle.h" 3 | 4 | -------------------------------------------------------------------------------- /ktl/ktl/KernelHandle.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct KernelHandleTraits { 4 | static void Close(HANDLE h) { 5 | ZwClose(h); 6 | } 7 | 8 | static constexpr HANDLE Invalid = nullptr; 9 | }; 10 | 11 | template 12 | struct Handle { 13 | explicit Handle(THandle h = Traits::Invalid) : m_Handle(h) {} 14 | 15 | ~Handle() { 16 | Close(); 17 | } 18 | 19 | Handle(Handle const&) = delete; 20 | Handle& operator=(Handle const&) = delete; 21 | Handle(Handle&&) = default; 22 | Handle& operator = (Handle&&) = default; 23 | 24 | bool IsValid() const { 25 | return m_Handle != Traits::Invalid; 26 | } 27 | 28 | operator THandle() const { 29 | return m_Handle; 30 | } 31 | 32 | THandle* operator&() { 33 | return &m_Handle; 34 | } 35 | 36 | THandle const* operator&() const { 37 | return &m_Handle; 38 | } 39 | 40 | void Close() { 41 | if (IsValid()) { 42 | Traits::Close(m_Handle); 43 | m_Handle = Traits::Invalid; 44 | } 45 | } 46 | 47 | private: 48 | THandle m_Handle; 49 | }; 50 | 51 | using KernelHandle = Handle; 52 | -------------------------------------------------------------------------------- /ktl/ktl/LinkedList.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "LinkedList.h" 3 | -------------------------------------------------------------------------------- /ktl/ktl/LinkedList.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Locker.h" 4 | 5 | #ifdef KTL_NAMESPACE 6 | namespace ktl { 7 | #endif 8 | 9 | template 10 | struct LinkedList { 11 | void Init() { 12 | InitializeListHead(&m_Head); 13 | m_Lock.Init(); 14 | m_Count = 0; 15 | } 16 | 17 | bool IsEmpty() const { 18 | return m_Count == 0; 19 | } 20 | 21 | ULONG GetCount() const { 22 | return m_Count; 23 | } 24 | 25 | void Clear() { 26 | Locker locker(m_Lock); 27 | InitializeListHead(&m_Head); 28 | m_Count = 0; 29 | } 30 | 31 | void AddHead(T* item) { 32 | Locker locker(m_Lock); 33 | InsertHeadList(&m_Head, &item->Link); 34 | m_Count++; 35 | } 36 | 37 | void AddTail(T* item) { 38 | Locker locker(m_Lock); 39 | InsertTailList(&m_Head, &item->Link); 40 | m_Count++; 41 | } 42 | 43 | T* RemoveHead() { 44 | Locker locker(m_Lock); 45 | if (m_Count == 0) 46 | return nullptr; 47 | 48 | m_Count--; 49 | auto link = RemoveHeadList(&m_Head); 50 | return link == &m_Head ? nullptr : CONTAINING_RECORD(link, T, Link); 51 | } 52 | 53 | T* RemoveTail() { 54 | Locker locker(m_Lock); 55 | if (m_Count == 0) 56 | return nullptr; 57 | m_Count--; 58 | auto link = RemoveTailList(&m_Head); 59 | return link == &m_Head ? nullptr : CONTAINING_RECORD(link, T, Link); 60 | } 61 | 62 | T const* GetHead() const { 63 | Locker locker(m_Lock); 64 | if (m_Count == 0) 65 | return nullptr; 66 | return CONTAINING_RECORD(m_Head.Flink, T, Link); 67 | } 68 | 69 | T const* GetTail() const { 70 | Locker locker(m_Lock); 71 | if (m_Count == 0) 72 | return nullptr; 73 | return CONTAINING_RECORD(m_Head.Blink, T, Link); 74 | } 75 | 76 | bool RemoveItem(T* item) { 77 | Locker locker(m_Lock); 78 | m_Count--; 79 | return RemoveEntryList(&item->Link); 80 | } 81 | 82 | template 83 | T* Find(F predicate) { 84 | Locker locker(m_Lock); 85 | for (auto node = m_Head.Flink; node != &m_Head; node = node->Flink) { 86 | auto item = CONTAINING_RECORD(node, T, Link); 87 | if (predicate(item)) 88 | return item; 89 | } 90 | return nullptr; 91 | } 92 | 93 | template 94 | T* ForEach(F action) { 95 | Locker locker(m_Lock); 96 | for (auto node = m_Head.Flink; node != &m_Head; node = node->Flink) { 97 | auto item = CONTAINING_RECORD(node, T, Link); 98 | action(item); 99 | } 100 | return nullptr; 101 | } 102 | 103 | private: 104 | LIST_ENTRY m_Head; 105 | mutable TLock m_Lock; 106 | ULONG m_Count; 107 | }; 108 | 109 | #ifdef KTL_NAMESPACE 110 | } 111 | #endif 112 | -------------------------------------------------------------------------------- /ktl/ktl/Locker.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef KTL_NAMESPACE 4 | namespace ktl { 5 | #endif 6 | template 7 | struct Locker { 8 | Locker(TLock& lock) : m_Lock(lock) { 9 | lock.Lock(); 10 | } 11 | ~Locker() { 12 | m_Lock.Unlock(); 13 | } 14 | 15 | private: 16 | TLock& m_Lock; 17 | }; 18 | 19 | template 20 | struct SharedLocker { 21 | SharedLocker(TLock& lock) : m_Lock(lock) { 22 | lock.LockShared(); 23 | } 24 | ~SharedLocker() { 25 | m_Lock.UnlockShared(); 26 | } 27 | 28 | private: 29 | TLock& m_Lock; 30 | }; 31 | 32 | #ifdef KTL_NAMESPACE 33 | } 34 | #endif 35 | -------------------------------------------------------------------------------- /ktl/ktl/LookasideList.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef KTL_NAMESPACE 4 | namespace ktl { 5 | #endif 6 | 7 | template 8 | struct LookasideList { 9 | NTSTATUS Init(POOL_TYPE pool, ULONG tag) { 10 | return ExInitializeLookasideListEx(&m_Lookaside, nullptr, nullptr, pool, 0, sizeof(T), tag, 0); 11 | } 12 | 13 | void Delete() { 14 | ExDeleteLookasideListEx(&m_Lookaside); 15 | } 16 | 17 | T* Alloc() { 18 | return (T*)ExAllocateFromLookasideListEx(&m_Lookaside); 19 | } 20 | 21 | void Free(T* p) { 22 | ExFreeToLookasideListEx(&m_Lookaside, p); 23 | } 24 | 25 | private: 26 | LOOKASIDE_LIST_EX m_Lookaside; 27 | }; 28 | 29 | #ifdef KTL_NAMESPACE 30 | } 31 | #endif 32 | -------------------------------------------------------------------------------- /ktl/ktl/Memory.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "Memory.h" 3 | 4 | #ifdef KTL_TRACK_MEMORY 5 | LONGLONG TotalAllocated; 6 | LONG AllocationCount; 7 | #endif 8 | 9 | void* __cdecl operator new(size_t size, PoolType pool, ULONG tag) { 10 | void* p = ExAllocatePool2(static_cast(pool), size, tag); 11 | #ifdef KTL_TRACK_MEMORY 12 | DbgPrint(KTL_PREFIX "Allocating %u bytes from pool %d with tag 0x%X: 0x%p\n", size, pool, tag, p); 13 | if (p) { 14 | InterlockedIncrement(&AllocationCount); 15 | InterlockedAdd64(&TotalAllocated, size); 16 | } 17 | #endif 18 | return p; 19 | } 20 | 21 | void* __cdecl operator new[](size_t size, PoolType pool, ULONG tag) { 22 | void* p = ExAllocatePool2((POOL_FLAGS)pool, size, tag); 23 | #ifdef KTL_TRACK_MEMORY 24 | DbgPrint(KTL_PREFIX "Allocating %u bytes from pool %d with tag 0x%X: 0x%p\n", size, pool, tag, p); 25 | if (p) { 26 | InterlockedIncrement(&AllocationCount); 27 | InterlockedAdd64(&TotalAllocated, size); 28 | } 29 | #endif 30 | return p; 31 | } 32 | 33 | void* __cdecl operator new(size_t size, void* address) { 34 | UNREFERENCED_PARAMETER(size); 35 | return address; 36 | } 37 | 38 | void __cdecl operator delete(void* p, size_t) { 39 | NT_ASSERT(p); 40 | ExFreePool(p); 41 | #ifdef KTL_TRACK_MEMORY 42 | DbgPrint(KTL_PREFIX "Freeing 0x%X: 0x%p\n", p); 43 | if (InterlockedDecrement(&AllocationCount) < 0) { 44 | NT_ASSERT(false); 45 | } 46 | #endif 47 | } 48 | 49 | void __cdecl operator delete[](void* p, size_t) { 50 | NT_ASSERT(p); 51 | ExFreePool(p); 52 | #ifdef KTL_TRACK_MEMORY 53 | DbgPrint(KTL_PREFIX "Freeing 0x%X: 0x%p\n", p); 54 | if (InterlockedDecrement(&AllocationCount) < 0) { 55 | NT_ASSERT(false); 56 | } 57 | #endif 58 | } -------------------------------------------------------------------------------- /ktl/ktl/Memory.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | enum class PoolType : ULONG64 { 4 | Paged = POOL_FLAG_PAGED, 5 | NonPaged = POOL_FLAG_NON_PAGED, 6 | NonPagedExecute = POOL_FLAG_NON_PAGED_EXECUTE, 7 | CacheAligned = POOL_FLAG_CACHE_ALIGNED, 8 | Uninitialized = POOL_FLAG_CACHE_ALIGNED, 9 | ChargeQuota = POOL_FLAG_USE_QUOTA, 10 | RaiseOnFailure = POOL_FLAG_RAISE_ON_FAILURE, 11 | Session = POOL_FLAG_SESSION, 12 | SpecialPool = POOL_FLAG_SPECIAL_POOL, 13 | }; 14 | DEFINE_ENUM_FLAG_OPERATORS(PoolType); 15 | 16 | void* __cdecl operator new(size_t size, PoolType pool, ULONG tag); 17 | void* __cdecl operator new[](size_t size, PoolType pool, ULONG tag); 18 | void* __cdecl operator new(size_t size, void* address); 19 | 20 | void __cdecl operator delete(void* p, size_t); 21 | void __cdecl operator delete[](void* p, size_t); 22 | 23 | template 24 | struct MemoryBuffer { 25 | MemoryBuffer(ULONG size, ULONG tag) : m_Size(size) { 26 | m_Buffer = (T*)ExAllocatePool2((POOL_FLAGS)Pool, size * sizeof(T), tag); 27 | } 28 | MemoryBuffer(MemoryBuffer const&) = delete; 29 | MemoryBuffer& operator=(MemoryBuffer const&) = delete; 30 | 31 | MemoryBuffer(MemoryBuffer const&& other) : m_Buffer(other.m_Buffer), m_Size(other.m_Size) { 32 | other.m_Buffer = nullptr; 33 | } 34 | MemoryBuffer& operator=(MemoryBuffer const&& other) { 35 | if (&other != this) { 36 | Free(); 37 | m_Buffer = other.m_Buffer; 38 | m_Size = other.m_Size; 39 | other.m_Buffer = nullptr; 40 | } 41 | return *this; 42 | } 43 | 44 | void Free() { 45 | if (m_Buffer) { 46 | ExFreePool(m_Buffer); 47 | m_Buffer = nullptr; 48 | } 49 | } 50 | 51 | ~MemoryBuffer() { 52 | Free(); 53 | } 54 | 55 | ULONG Size() const { 56 | return m_Size; 57 | } 58 | 59 | ULONG SizeInBytes() const { 60 | return m_Size * sizeof(T); 61 | } 62 | 63 | operator bool() const { 64 | return m_Buffer != nullptr; 65 | } 66 | 67 | T* Get() const { 68 | return m_Buffer; 69 | } 70 | 71 | T* m_Buffer; 72 | ULONG m_Size; 73 | }; 74 | -------------------------------------------------------------------------------- /ktl/ktl/Mutex.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "Mutex.h" 3 | 4 | #ifdef KTL_NAMESPACE 5 | using namespace ktl; 6 | #endif 7 | 8 | void Mutex::Init() { 9 | KeInitializeMutex(&m_Mutex, 0); 10 | } 11 | 12 | void Mutex::Lock() { 13 | KeWaitForSingleObject(&m_Mutex, Executive, KernelMode, FALSE, nullptr); 14 | } 15 | 16 | void Mutex::Unlock() { 17 | KeReleaseMutex(&m_Mutex, FALSE); 18 | } 19 | 20 | -------------------------------------------------------------------------------- /ktl/ktl/Mutex.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef KTL_NAMESPACE 4 | namespace ktl { 5 | #endif 6 | 7 | struct Mutex { 8 | void Init(); 9 | void Lock(); 10 | void Unlock(); 11 | 12 | private: 13 | KMUTEX m_Mutex; 14 | }; 15 | 16 | #ifdef KTL_NAMESPACE 17 | } 18 | #endif 19 | -------------------------------------------------------------------------------- /ktl/ktl/SpinLock.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "SpinLock.h" 3 | 4 | #ifdef KTL_NAMESPACE 5 | using namespace ktl; 6 | #endif 7 | 8 | void SpinLock::Init() { 9 | KeInitializeSpinLock(&m_Lock); 10 | } 11 | 12 | void SpinLock::Lock() { 13 | KeAcquireSpinLock(&m_Lock, &m_OldIrql); 14 | } 15 | 16 | void SpinLock::Unlock() { 17 | KeReleaseSpinLock(&m_Lock, m_OldIrql); 18 | } 19 | 20 | void QueuedSpinLock::Init() { 21 | KeInitializeSpinLock(&m_Lock); 22 | } 23 | 24 | void QueuedSpinLock::Lock(PKLOCK_QUEUE_HANDLE handle) { 25 | KeAcquireInStackQueuedSpinLock(&m_Lock, handle); 26 | } 27 | 28 | void QueuedSpinLock::Unlock(PKLOCK_QUEUE_HANDLE handle) { 29 | KeReleaseInStackQueuedSpinLock(handle); 30 | } 31 | 32 | -------------------------------------------------------------------------------- /ktl/ktl/SpinLock.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef KTL_NAMESPACE 4 | namespace ktl { 5 | #endif 6 | 7 | struct SpinLock { 8 | void Init(); 9 | void Lock(); 10 | void Unlock(); 11 | 12 | private: 13 | KSPIN_LOCK m_Lock; 14 | KIRQL m_OldIrql; 15 | }; 16 | 17 | struct QueuedSpinLock { 18 | void Init(); 19 | void Lock(PKLOCK_QUEUE_HANDLE handle); 20 | void Unlock(PKLOCK_QUEUE_HANDLE handle); 21 | 22 | private: 23 | KSPIN_LOCK m_Lock; 24 | }; 25 | 26 | #ifdef KTL_NAMESPACE 27 | } 28 | #endif 29 | -------------------------------------------------------------------------------- /ktl/ktl/ktl.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | 3 | NTSTATUS CompleteRequest(PIRP Irp, NTSTATUS status, ULONG_PTR info, CCHAR boost) { 4 | Irp->IoStatus.Status = status; 5 | Irp->IoStatus.Information = info; 6 | IoCompleteRequest(Irp, boost); 7 | return status; 8 | } 9 | 10 | #define va_start __va_start 11 | #define va_end(x) 12 | 13 | #ifdef DBG 14 | void __cdecl Error(PCSTR format, ...) { 15 | va_list args; 16 | va_start(&args, format); 17 | vDbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, format, args); 18 | va_end(args); 19 | } 20 | 21 | void __cdecl Warning(PCSTR format, ...) { 22 | va_list args; 23 | va_start(&args, format); 24 | vDbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_WARNING_LEVEL, format, args); 25 | va_end(args); 26 | } 27 | void __cdecl Info(PCSTR format, ...) { 28 | va_list args; 29 | va_start(&args, format); 30 | vDbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, format, args); 31 | va_end(args); 32 | } 33 | void __cdecl Trace(PCSTR format, ...) { 34 | va_list args; 35 | va_start(&args, format); 36 | vDbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL, format, args); 37 | va_end(args); 38 | } 39 | #else 40 | void Error(PCSTR, ...) {} 41 | void Warning(PCSTR, ...) {} 42 | void Info(PCSTR, ...) {} 43 | void Trace(PCSTR, ...) {} 44 | #endif 45 | -------------------------------------------------------------------------------- /ktl/ktl/ktl.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define KTL_PREFIX "KTL: " 4 | 5 | #ifndef KTL_TRACK_MEMORY 6 | #if DBG 7 | #define KTL_TRACK_MEMORY 8 | #endif 9 | #endif 10 | 11 | #ifndef KTL_TRACK_BASIC_STRING 12 | #if DBG 13 | #define KTL_TRACK_BASIC_STRING 14 | #endif 15 | #endif 16 | 17 | #include "std.h" 18 | #include "BasicString.h" 19 | #include "Memory.h" 20 | #include "EResource.h" 21 | #include "Vector.h" 22 | #include "Mutex.h" 23 | #include "FastMutex.h" 24 | #ifdef __FLTKERNEL__ 25 | #include "FilterFileNameInformation.h" 26 | #endif 27 | 28 | NTSTATUS CompleteRequest(PIRP Irp, NTSTATUS status = STATUS_SUCCESS, ULONG_PTR info = 0, CCHAR boost = IO_NO_INCREMENT); 29 | 30 | void __cdecl Error(PCSTR format, ...); 31 | void __cdecl Warning(PCSTR format, ...); 32 | void __cdecl Trace(PCSTR format, ...); 33 | void __cdecl Info(PCSTR format, ...); 34 | -------------------------------------------------------------------------------- /ktl/ktl/pch.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | -------------------------------------------------------------------------------- /ktl/ktl/pch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | -------------------------------------------------------------------------------- /ktl/ktl/std.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace std { 4 | // 5 | // support move semantics 6 | // 7 | 8 | template 9 | struct remove_reference { 10 | using type = _Ty; 11 | using _Const_thru_ref_type = const _Ty; 12 | }; 13 | 14 | template 15 | struct remove_reference<_Ty&> { 16 | using type = _Ty; 17 | using _Const_thru_ref_type = const _Ty&; 18 | }; 19 | 20 | template 21 | struct remove_reference<_Ty&&> { 22 | using type = _Ty; 23 | using _Const_thru_ref_type = const _Ty&&; 24 | }; 25 | 26 | template 27 | using remove_reference_t = typename remove_reference<_Ty>::type; 28 | 29 | template 30 | constexpr remove_reference_t<_Ty>&& move(_Ty&& _Arg) noexcept { // forward _Arg as movable 31 | return static_cast&&>(_Arg); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /ktl/ktl_test/Main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #define DRIVER_TAG 'ltkt' 4 | #include "..\ktl\ktl.h" 5 | 6 | using String = PWString; 7 | 8 | String* g_RegPath; 9 | 10 | void TestUnload(PDRIVER_OBJECT); 11 | NTSTATUS TestCreateClose(PDEVICE_OBJECT, PIRP Irp); 12 | NTSTATUS TestDeviceControl(PDEVICE_OBJECT, PIRP Irp); 13 | 14 | extern "C" NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) { 15 | g_RegPath = new (PoolType::Paged, DRIVER_TAG) String(RegistryPath); 16 | 17 | DriverObject->DriverUnload = TestUnload; 18 | 19 | DriverObject->MajorFunction[IRP_MJ_CREATE] = DriverObject->MajorFunction[IRP_MJ_CLOSE] = TestCreateClose; 20 | DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = TestDeviceControl; 21 | 22 | return STATUS_SUCCESS; 23 | } 24 | 25 | void TestUnload(PDRIVER_OBJECT DriverObject) { 26 | delete g_RegPath; 27 | IoDeleteDevice(DriverObject->DeviceObject); 28 | } 29 | 30 | NTSTATUS TestCreateClose(PDEVICE_OBJECT, PIRP Irp) { 31 | Irp->IoStatus.Status = STATUS_SUCCESS; 32 | Irp->IoStatus.Information = 0; 33 | IoCompleteRequest(Irp, 0); 34 | return STATUS_SUCCESS; 35 | } 36 | 37 | NTSTATUS TestDeviceControl(PDEVICE_OBJECT, PIRP Irp) { 38 | Irp->IoStatus.Status = STATUS_SUCCESS; 39 | Irp->IoStatus.Information = 0; 40 | IoCompleteRequest(Irp, 0); 41 | return STATUS_SUCCESS; 42 | } 43 | 44 | -------------------------------------------------------------------------------- /ktl/ktl_test/ktl_test.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 | Source Files 24 | 25 | 26 | --------------------------------------------------------------------------------