├── .gitattributes ├── .gitignore ├── BookSamples.sln ├── LICENSE ├── README.md ├── chapter02 └── Sample │ ├── Sample.cpp │ ├── Sample.inf │ ├── Sample.vcxproj │ └── Sample.vcxproj.filters ├── chapter04 ├── Booster │ ├── Booster.cpp │ ├── Booster.vcxproj │ └── Booster.vcxproj.filters └── PriorityBooster │ ├── PriorityBooster.cpp │ ├── PriorityBooster.vcxproj │ ├── PriorityBooster.vcxproj.filters │ └── PriorityBoosterCommon.h ├── chapter06 ├── Booster │ ├── Booster.cpp │ ├── Booster.vcxproj │ └── Booster.vcxproj.filters └── PriorityBooster │ ├── PriorityBooster.cpp │ ├── PriorityBooster.vcxproj │ ├── PriorityBooster.vcxproj.filters │ └── PriorityBoosterCommon.h ├── chapter07 ├── Zero │ ├── Zero.cpp │ ├── Zero.inf │ ├── Zero.vcxproj │ ├── Zero.vcxproj.filters │ ├── ZeroCommon.h │ ├── pch.cpp │ └── pch.h └── ZeroTest │ ├── ZeroTest.cpp │ ├── ZeroTest.vcxproj │ ├── ZeroTest.vcxproj.filters │ ├── pch.cpp │ └── pch.h ├── chapter08 ├── SysMon │ ├── AutoLock.h │ ├── FastMutex.cpp │ ├── FastMutex.h │ ├── SysMon.cpp │ ├── SysMon.h │ ├── SysMon.inf │ ├── SysMon.vcxproj │ ├── SysMon.vcxproj.filters │ ├── SysMonCommon.h │ ├── pch.cpp │ └── pch.h └── SysMonClient │ ├── SysMonClient.cpp │ ├── SysMonClient.vcxproj │ ├── SysMonClient.vcxproj.filters │ ├── pch.cpp │ └── pch.h ├── chapter09 ├── ProcessProtect │ ├── AutoLock.h │ ├── FastMutex.cpp │ ├── FastMutex.h │ ├── ProcessProtect.cpp │ ├── ProcessProtect.h │ ├── ProcessProtect.vcxproj │ ├── ProcessProtect.vcxproj.filters │ ├── ProcessProtectCommon.h │ ├── pch.cpp │ └── pch.h ├── Protect │ ├── Protect.cpp │ ├── Protect.vcxproj │ ├── Protect.vcxproj.filters │ ├── pch.cpp │ └── pch.h ├── SysMon │ ├── AutoLock.h │ ├── FastMutex.cpp │ ├── FastMutex.h │ ├── SysMon.cpp │ ├── SysMon.h │ ├── SysMon.inf │ ├── SysMon.vcxproj │ ├── SysMon.vcxproj.filters │ ├── SysMonCommon.h │ ├── pch.cpp │ └── pch.h └── SysMonClient │ ├── SysMonClient.cpp │ ├── SysMonClient.vcxproj │ ├── SysMonClient.vcxproj.filters │ ├── pch.cpp │ └── pch.h ├── chapter10 ├── DelProtect │ ├── DelProtect.cpp │ ├── DelProtect.inf │ ├── DelProtect.rc │ ├── DelProtect.vcxproj │ └── DelProtect.vcxproj.filters ├── DelProtect2 │ ├── AutoLock.h │ ├── DelProtect.cpp │ ├── DelProtect.rc │ ├── DelProtect2.inf │ ├── DelProtect2.vcxproj │ ├── DelProtect2.vcxproj.filters │ ├── DelProtectCommon.h │ ├── FastMutex.cpp │ └── FastMutex.h ├── DelProtect3 │ ├── AutoLock.h │ ├── DelProtect.cpp │ ├── DelProtect.rc │ ├── DelProtect3.inf │ ├── DelProtect3.vcxproj │ ├── DelProtect3.vcxproj.filters │ ├── DelProtectCommon.h │ ├── FastMutex.cpp │ ├── FastMutex.h │ ├── kstring.cpp │ └── kstring.h ├── DelProtectConfig │ ├── DelProtectConfig.cpp │ ├── DelProtectConfig.vcxproj │ ├── DelProtectConfig.vcxproj.filters │ ├── pch.cpp │ └── pch.h ├── DelProtectConfig3 │ ├── DelProtectConfig.cpp │ ├── DelProtectConfig3.vcxproj │ ├── DelProtectConfig3.vcxproj.filters │ ├── pch.cpp │ └── pch.h ├── DelTest │ ├── DelTest.cpp │ ├── DelTest.vcxproj │ ├── DelTest.vcxproj.filters │ ├── pch.cpp │ └── pch.h ├── FileBackup │ ├── AutoLock.h │ ├── FileBackup.cpp │ ├── FileBackup.inf │ ├── FileBackup.rc │ ├── FileBackup.vcxproj │ ├── FileBackup.vcxproj.filters │ ├── FileBackupCommon.h │ ├── FileNameInformation.cpp │ ├── FileNameInformation.h │ ├── Mutex.cpp │ └── Mutex.h ├── FileBackupMon │ ├── FileBackupMon.cpp │ ├── FileBackupMon.vcxproj │ ├── FileBackupMon.vcxproj.filters │ ├── pch.cpp │ └── pch.h └── FileRestore │ ├── FileRestore.cpp │ ├── FileRestore.vcxproj │ ├── FileRestore.vcxproj.filters │ ├── pch.cpp │ └── pch.h └── chapter11 ├── DevMon ├── DevMon.cpp ├── DevMon.vcxproj ├── DevMon.vcxproj.filters ├── pch.cpp └── pch.h └── KDevMon ├── AutoLock.h ├── 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 ├── pch.cpp └── pch.h /.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 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Build results 17 | [Dd]ebug/ 18 | [Dd]ebugPublic/ 19 | [Rr]elease/ 20 | [Rr]eleases/ 21 | x64/ 22 | x86/ 23 | [Aa][Rr][Mm]/ 24 | [Aa][Rr][Mm]64/ 25 | bld/ 26 | [Bb]in/ 27 | [Oo]bj/ 28 | [Ll]og/ 29 | 30 | # Visual Studio 2015/2017 cache/options directory 31 | .vs/ 32 | # Uncomment if you have tasks that create the project's static files in wwwroot 33 | #wwwroot/ 34 | 35 | # Visual Studio 2017 auto generated files 36 | Generated\ Files/ 37 | 38 | # MSTest test Results 39 | [Tt]est[Rr]esult*/ 40 | [Bb]uild[Ll]og.* 41 | 42 | # NUNIT 43 | *.VisualState.xml 44 | TestResult.xml 45 | 46 | # Build Results of an ATL Project 47 | [Dd]ebugPS/ 48 | [Rr]eleasePS/ 49 | dlldata.c 50 | 51 | # Benchmark Results 52 | BenchmarkDotNet.Artifacts/ 53 | 54 | # .NET Core 55 | project.lock.json 56 | project.fragment.lock.json 57 | artifacts/ 58 | 59 | # StyleCop 60 | StyleCopReport.xml 61 | 62 | # Files built by Visual Studio 63 | *_i.c 64 | *_p.c 65 | *_h.h 66 | *.ilk 67 | *.meta 68 | *.obj 69 | *.iobj 70 | *.pch 71 | *.pdb 72 | *.ipdb 73 | *.pgc 74 | *.pgd 75 | *.rsp 76 | *.sbr 77 | *.tlb 78 | *.tli 79 | *.tlh 80 | *.tmp 81 | *.tmp_proj 82 | *_wpftmp.csproj 83 | *.log 84 | *.vspscc 85 | *.vssscc 86 | .builds 87 | *.pidb 88 | *.svclog 89 | *.scc 90 | 91 | # Chutzpah Test files 92 | _Chutzpah* 93 | 94 | # Visual C++ cache files 95 | ipch/ 96 | *.aps 97 | *.ncb 98 | *.opendb 99 | *.opensdf 100 | *.sdf 101 | *.cachefile 102 | *.VC.db 103 | *.VC.VC.opendb 104 | 105 | # Visual Studio profiler 106 | *.psess 107 | *.vsp 108 | *.vspx 109 | *.sap 110 | 111 | # Visual Studio Trace Files 112 | *.e2e 113 | 114 | # TFS 2012 Local Workspace 115 | $tf/ 116 | 117 | # Guidance Automation Toolkit 118 | *.gpState 119 | 120 | # ReSharper is a .NET coding add-in 121 | _ReSharper*/ 122 | *.[Rr]e[Ss]harper 123 | *.DotSettings.user 124 | 125 | # JustCode is a .NET coding add-in 126 | .JustCode 127 | 128 | # TeamCity is a build add-in 129 | _TeamCity* 130 | 131 | # DotCover is a Code Coverage Tool 132 | *.dotCover 133 | 134 | # AxoCover is a Code Coverage Tool 135 | .axoCover/* 136 | !.axoCover/settings.json 137 | 138 | # Visual Studio code coverage results 139 | *.coverage 140 | *.coveragexml 141 | 142 | # NCrunch 143 | _NCrunch_* 144 | .*crunch*.local.xml 145 | nCrunchTemp_* 146 | 147 | # MightyMoose 148 | *.mm.* 149 | AutoTest.Net/ 150 | 151 | # Web workbench (sass) 152 | .sass-cache/ 153 | 154 | # Installshield output folder 155 | [Ee]xpress/ 156 | 157 | # DocProject is a documentation generator add-in 158 | DocProject/buildhelp/ 159 | DocProject/Help/*.HxT 160 | DocProject/Help/*.HxC 161 | DocProject/Help/*.hhc 162 | DocProject/Help/*.hhk 163 | DocProject/Help/*.hhp 164 | DocProject/Help/Html2 165 | DocProject/Help/html 166 | 167 | # Click-Once directory 168 | publish/ 169 | 170 | # Publish Web Output 171 | *.[Pp]ublish.xml 172 | *.azurePubxml 173 | # Note: Comment the next line if you want to checkin your web deploy settings, 174 | # but database connection strings (with potential passwords) will be unencrypted 175 | *.pubxml 176 | *.publishproj 177 | 178 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 179 | # checkin your Azure Web App publish settings, but sensitive information contained 180 | # in these scripts will be unencrypted 181 | PublishScripts/ 182 | 183 | # NuGet Packages 184 | *.nupkg 185 | # The packages folder can be ignored because of Package Restore 186 | **/[Pp]ackages/* 187 | # except build/, which is used as an MSBuild target. 188 | !**/[Pp]ackages/build/ 189 | # Uncomment if necessary however generally it will be regenerated when needed 190 | #!**/[Pp]ackages/repositories.config 191 | # NuGet v3's project.json files produces more ignorable files 192 | *.nuget.props 193 | *.nuget.targets 194 | 195 | # Microsoft Azure Build Output 196 | csx/ 197 | *.build.csdef 198 | 199 | # Microsoft Azure Emulator 200 | ecf/ 201 | rcf/ 202 | 203 | # Windows Store app package directories and files 204 | AppPackages/ 205 | BundleArtifacts/ 206 | Package.StoreAssociation.xml 207 | _pkginfo.txt 208 | *.appx 209 | 210 | # Visual Studio cache files 211 | # files ending in .cache can be ignored 212 | *.[Cc]ache 213 | # but keep track of directories ending in .cache 214 | !?*.[Cc]ache/ 215 | 216 | # Others 217 | ClientBin/ 218 | ~$* 219 | *~ 220 | *.dbmdl 221 | *.dbproj.schemaview 222 | *.jfm 223 | *.pfx 224 | *.publishsettings 225 | orleans.codegen.cs 226 | 227 | # Including strong name files can present a security risk 228 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 229 | #*.snk 230 | 231 | # Since there are multiple workflows, uncomment next line to ignore bower_components 232 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 233 | #bower_components/ 234 | 235 | # RIA/Silverlight projects 236 | Generated_Code/ 237 | 238 | # Backup & report files from converting an old project file 239 | # to a newer Visual Studio version. Backup files are not needed, 240 | # because we have git ;-) 241 | _UpgradeReport_Files/ 242 | Backup*/ 243 | UpgradeLog*.XML 244 | UpgradeLog*.htm 245 | ServiceFabricBackup/ 246 | *.rptproj.bak 247 | 248 | # SQL Server files 249 | *.mdf 250 | *.ldf 251 | *.ndf 252 | 253 | # Business Intelligence projects 254 | *.rdl.data 255 | *.bim.layout 256 | *.bim_*.settings 257 | *.rptproj.rsuser 258 | *- Backup*.rdl 259 | 260 | # Microsoft Fakes 261 | FakesAssemblies/ 262 | 263 | # GhostDoc plugin setting file 264 | *.GhostDoc.xml 265 | 266 | # Node.js Tools for Visual Studio 267 | .ntvs_analysis.dat 268 | node_modules/ 269 | 270 | # Visual Studio 6 build log 271 | *.plg 272 | 273 | # Visual Studio 6 workspace options file 274 | *.opt 275 | 276 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 277 | *.vbw 278 | 279 | # Visual Studio LightSwitch build output 280 | **/*.HTMLClient/GeneratedArtifacts 281 | **/*.DesktopClient/GeneratedArtifacts 282 | **/*.DesktopClient/ModelManifest.xml 283 | **/*.Server/GeneratedArtifacts 284 | **/*.Server/ModelManifest.xml 285 | _Pvt_Extensions 286 | 287 | # Paket dependency manager 288 | .paket/paket.exe 289 | paket-files/ 290 | 291 | # FAKE - F# Make 292 | .fake/ 293 | 294 | # JetBrains Rider 295 | .idea/ 296 | *.sln.iml 297 | 298 | # CodeRush personal settings 299 | .cr/personal 300 | 301 | # Python Tools for Visual Studio (PTVS) 302 | __pycache__/ 303 | *.pyc 304 | 305 | # Cake - Uncomment if you are using it 306 | # tools/** 307 | # !tools/packages.config 308 | 309 | # Tabs Studio 310 | *.tss 311 | 312 | # Telerik's JustMock configuration file 313 | *.jmconfig 314 | 315 | # BizTalk build output 316 | *.btp.cs 317 | *.btm.cs 318 | *.odx.cs 319 | *.xsd.cs 320 | 321 | # OpenCover UI analysis results 322 | OpenCover/ 323 | 324 | # Azure Stream Analytics local run output 325 | ASALocalRun/ 326 | 327 | # MSBuild Binary and Structured Log 328 | *.binlog 329 | 330 | # NVidia Nsight GPU debugger configuration file 331 | *.nvuser 332 | 333 | # MFractors (Xamarin productivity tool) working folder 334 | .mfractor/ 335 | 336 | # Local History for Visual Studio 337 | .localhistory/ 338 | 339 | # BeatPulse healthcheck temp database 340 | healthchecksdb -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 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 | # The Windows Kernel Programming book samples 2 | 3 | This repo holds the samples from my book: https://leanpub.com/windowskernelprogramming, also available from Amazon at https://www.amazon.com/gp/product/1977593372/ 4 | 5 | 6 | -------------------------------------------------------------------------------- /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(("Copied registry path: %wZ\n", &g_RegistryPath)); 26 | 27 | DriverObject->DriverUnload = SampleUnload; 28 | 29 | RTL_OSVERSIONINFOW info = { sizeof(info) }; 30 | RtlGetVersion(&info); 31 | KdPrint(("Windows Version: %d.%d.%d\n", info.dwMajorVersion, info.dwMinorVersion, info.dwBuildNumber)); 32 | 33 | KdPrint(("Sample driver initialized successfully\n")); 34 | 35 | return STATUS_SUCCESS; 36 | } 37 | -------------------------------------------------------------------------------- /chapter02/Sample/Sample.inf: -------------------------------------------------------------------------------- 1 | ; 2 | ; Sample.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=Sample.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="Sample Source Disk" 33 | -------------------------------------------------------------------------------- /chapter02/Sample/Sample.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | Debug 22 | ARM 23 | 24 | 25 | Release 26 | ARM 27 | 28 | 29 | Debug 30 | ARM64 31 | 32 | 33 | Release 34 | ARM64 35 | 36 | 37 | 38 | {F8D30EB9-947A-4ECE-BC91-FFBB4B43F284} 39 | {dd38f7fc-d7bd-488b-9242-7d8754cde80d} 40 | v4.5 41 | 12.0 42 | Debug 43 | Win32 44 | Sample 45 | 10.0.19041.0 46 | 47 | 48 | 49 | Windows7 50 | true 51 | WindowsKernelModeDriver10.0 52 | Driver 53 | WDM 54 | 55 | 56 | Windows7 57 | false 58 | WindowsKernelModeDriver10.0 59 | Driver 60 | WDM 61 | 62 | 63 | Windows7 64 | true 65 | WindowsKernelModeDriver10.0 66 | Driver 67 | WDM 68 | 69 | 70 | Windows7 71 | false 72 | WindowsKernelModeDriver10.0 73 | Driver 74 | WDM 75 | 76 | 77 | Windows7 78 | true 79 | WindowsKernelModeDriver10.0 80 | Driver 81 | WDM 82 | 83 | 84 | Windows7 85 | false 86 | WindowsKernelModeDriver10.0 87 | Driver 88 | WDM 89 | 90 | 91 | Windows7 92 | true 93 | WindowsKernelModeDriver10.0 94 | Driver 95 | WDM 96 | 97 | 98 | Windows7 99 | false 100 | WindowsKernelModeDriver10.0 101 | Driver 102 | WDM 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | DbgengKernelDebugger 114 | 115 | 116 | DbgengKernelDebugger 117 | 118 | 119 | DbgengKernelDebugger 120 | 121 | 122 | DbgengKernelDebugger 123 | 124 | 125 | DbgengKernelDebugger 126 | 127 | 128 | DbgengKernelDebugger 129 | 130 | 131 | DbgengKernelDebugger 132 | 133 | 134 | DbgengKernelDebugger 135 | 136 | 137 | 138 | stdcpp17 139 | 140 | 141 | 142 | 143 | stdcpp17 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /chapter04/Booster/Booster.cpp: -------------------------------------------------------------------------------- 1 | // Booster.cpp : This file contains the 'main' function. Program execution begins and ends there. 2 | // 3 | 4 | #include 5 | #include 6 | #include "..\PriorityBooster\PriorityBoosterCommon.h" 7 | 8 | int Error(const char* message) { 9 | printf("%s (error=%d)\n", message, GetLastError()); 10 | return 1; 11 | } 12 | 13 | int main(int argc, const char* argv[]) { 14 | if (argc < 3) { 15 | printf("Usage: Booster \n"); 16 | return 0; 17 | } 18 | 19 | HANDLE hDevice = CreateFile(L"\\\\.\\PriorityBooster", GENERIC_WRITE, FILE_SHARE_WRITE, 20 | nullptr, OPEN_EXISTING, 0, nullptr); 21 | if (hDevice == INVALID_HANDLE_VALUE) 22 | return Error("Failed to open device"); 23 | 24 | ThreadData data; 25 | data.ThreadId = atoi(argv[1]); 26 | data.Priority = atoi(argv[2]); 27 | 28 | DWORD returned; 29 | BOOL success = DeviceIoControl(hDevice, IOCTL_PRIORITY_BOOSTER_SET_PRIORITY, &data, sizeof(data), nullptr, 0, &returned, nullptr); 30 | if (success) 31 | printf("Priority change succeeded!\n"); 32 | else 33 | Error("Priority change failed!"); 34 | 35 | CloseHandle(hDevice); 36 | } 37 | 38 | -------------------------------------------------------------------------------- /chapter04/Booster/Booster.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 16.0 23 | {6A95359E-D88B-441E-AA9B-CBEFD1560638} 24 | Win32Proj 25 | Booster 26 | 10.0 27 | 28 | 29 | 30 | Application 31 | true 32 | v142 33 | Unicode 34 | 35 | 36 | Application 37 | false 38 | v142 39 | true 40 | Unicode 41 | 42 | 43 | Application 44 | true 45 | v142 46 | Unicode 47 | 48 | 49 | Application 50 | false 51 | v142 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | 76 | 77 | true 78 | 79 | 80 | false 81 | 82 | 83 | false 84 | 85 | 86 | 87 | 88 | 89 | Level3 90 | Disabled 91 | true 92 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 93 | true 94 | MultiThreadedDebug 95 | stdcpp17 96 | 97 | 98 | Console 99 | true 100 | 101 | 102 | 103 | 104 | 105 | 106 | Level3 107 | Disabled 108 | true 109 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 110 | true 111 | 112 | 113 | Console 114 | true 115 | 116 | 117 | 118 | 119 | 120 | 121 | Level3 122 | MaxSpeed 123 | true 124 | true 125 | true 126 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 127 | true 128 | 129 | 130 | Console 131 | true 132 | true 133 | true 134 | 135 | 136 | 137 | 138 | 139 | 140 | Level3 141 | MaxSpeed 142 | true 143 | true 144 | true 145 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 146 | true 147 | stdcpp17 148 | 149 | 150 | Console 151 | true 152 | true 153 | true 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | -------------------------------------------------------------------------------- /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;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 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /chapter04/PriorityBooster/PriorityBooster.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "PriorityBoosterCommon.h" 4 | 5 | // prototypes 6 | 7 | void PriorityBoosterUnload(_In_ PDRIVER_OBJECT DriverObject); 8 | NTSTATUS PriorityBoosterCreateClose(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp); 9 | NTSTATUS PriorityBoosterDeviceControl(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp); 10 | 11 | // DriverEntry 12 | 13 | extern "C" NTSTATUS 14 | DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath) { 15 | UNREFERENCED_PARAMETER(RegistryPath); 16 | 17 | KdPrint(("PriorityBooster DriverEntry started\n")); 18 | 19 | DriverObject->DriverUnload = PriorityBoosterUnload; 20 | 21 | DriverObject->MajorFunction[IRP_MJ_CREATE] = PriorityBoosterCreateClose; 22 | DriverObject->MajorFunction[IRP_MJ_CLOSE] = PriorityBoosterCreateClose; 23 | DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = PriorityBoosterDeviceControl; 24 | 25 | UNICODE_STRING devName = RTL_CONSTANT_STRING(L"\\Device\\PriorityBooster"); 26 | //RtlInitUnicodeString(&devName, L"\\Device\\ThreadBoost"); 27 | PDEVICE_OBJECT DeviceObject; 28 | NTSTATUS status = IoCreateDevice(DriverObject, 0, &devName, FILE_DEVICE_UNKNOWN, 0, FALSE, &DeviceObject); 29 | if (!NT_SUCCESS(status)) { 30 | KdPrint(("Failed to create device (0x%08X)\n", status)); 31 | return status; 32 | } 33 | 34 | UNICODE_STRING symLink = RTL_CONSTANT_STRING(L"\\??\\PriorityBooster"); 35 | status = IoCreateSymbolicLink(&symLink, &devName); 36 | if (!NT_SUCCESS(status)) { 37 | KdPrint(("Failed to create symbolic link (0x%08X)\n", status)); 38 | IoDeleteDevice(DeviceObject); 39 | return status; 40 | } 41 | 42 | KdPrint(("PriorityBooster DriverEntry completed successfully\n")); 43 | 44 | return STATUS_SUCCESS; 45 | } 46 | 47 | void PriorityBoosterUnload(_In_ PDRIVER_OBJECT DriverObject) { 48 | UNICODE_STRING symLink = RTL_CONSTANT_STRING(L"\\??\\PriorityBooster"); 49 | // delete symbolic link 50 | IoDeleteSymbolicLink(&symLink); 51 | 52 | // delete device object 53 | IoDeleteDevice(DriverObject->DeviceObject); 54 | 55 | KdPrint(("PriorityBooster unloaded\n")); 56 | } 57 | 58 | _Use_decl_annotations_ 59 | NTSTATUS PriorityBoosterCreateClose(PDEVICE_OBJECT DeviceObject, PIRP Irp) { 60 | UNREFERENCED_PARAMETER(DeviceObject); 61 | 62 | Irp->IoStatus.Status = STATUS_SUCCESS; 63 | Irp->IoStatus.Information = 0; 64 | IoCompleteRequest(Irp, IO_NO_INCREMENT); 65 | return STATUS_SUCCESS; 66 | } 67 | 68 | _Use_decl_annotations_ 69 | NTSTATUS PriorityBoosterDeviceControl(PDEVICE_OBJECT, PIRP Irp) { 70 | // get our IO_STACK_LOCATION 71 | auto stack = IoGetCurrentIrpStackLocation(Irp); 72 | auto status = STATUS_SUCCESS; 73 | 74 | switch (stack->Parameters.DeviceIoControl.IoControlCode) { 75 | case IOCTL_PRIORITY_BOOSTER_SET_PRIORITY: 76 | { 77 | // do the work 78 | if (stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(ThreadData)) { 79 | status = STATUS_BUFFER_TOO_SMALL; 80 | break; 81 | } 82 | 83 | auto data = (ThreadData*)stack->Parameters.DeviceIoControl.Type3InputBuffer; 84 | if (data == nullptr) { 85 | status = STATUS_INVALID_PARAMETER; 86 | break; 87 | } 88 | 89 | if (data->Priority < 1 || data->Priority > 31) { 90 | status = STATUS_INVALID_PARAMETER; 91 | break; 92 | } 93 | 94 | PETHREAD Thread; 95 | status = PsLookupThreadByThreadId(ULongToHandle(data->ThreadId), &Thread); 96 | if (!NT_SUCCESS(status)) 97 | break; 98 | 99 | KeSetPriorityThread((PKTHREAD)Thread, data->Priority); 100 | ObDereferenceObject(Thread); 101 | KdPrint(("Thread Priority change for %d to %d succeeded!\n", 102 | data->ThreadId, data->Priority)); 103 | break; 104 | } 105 | 106 | default: 107 | status = STATUS_INVALID_DEVICE_REQUEST; 108 | break; 109 | } 110 | 111 | Irp->IoStatus.Status = status; 112 | Irp->IoStatus.Information = 0; 113 | IoCompleteRequest(Irp, IO_NO_INCREMENT); 114 | return status; 115 | } 116 | -------------------------------------------------------------------------------- /chapter04/PriorityBooster/PriorityBooster.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | Debug 22 | ARM 23 | 24 | 25 | Release 26 | ARM 27 | 28 | 29 | Debug 30 | ARM64 31 | 32 | 33 | Release 34 | ARM64 35 | 36 | 37 | 38 | {96DF1253-074B-4E47-BFBF-A7F8E68384E1} 39 | {dd38f7fc-d7bd-488b-9242-7d8754cde80d} 40 | v4.5 41 | 12.0 42 | Debug 43 | Win32 44 | PriorityBooster 45 | $(LatestTargetPlatformVersion) 46 | 47 | 48 | 49 | Windows10 50 | true 51 | WindowsKernelModeDriver10.0 52 | Driver 53 | WDM 54 | 55 | 56 | Windows10 57 | false 58 | WindowsKernelModeDriver10.0 59 | Driver 60 | WDM 61 | 62 | 63 | Windows10 64 | true 65 | WindowsKernelModeDriver10.0 66 | Driver 67 | WDM 68 | 69 | 70 | Windows10 71 | false 72 | WindowsKernelModeDriver10.0 73 | Driver 74 | WDM 75 | 76 | 77 | Windows10 78 | true 79 | WindowsKernelModeDriver10.0 80 | Driver 81 | WDM 82 | 83 | 84 | Windows10 85 | false 86 | WindowsKernelModeDriver10.0 87 | Driver 88 | WDM 89 | 90 | 91 | Windows10 92 | true 93 | WindowsKernelModeDriver10.0 94 | Driver 95 | WDM 96 | 97 | 98 | Windows10 99 | false 100 | WindowsKernelModeDriver10.0 101 | Driver 102 | WDM 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | DbgengKernelDebugger 114 | 115 | 116 | DbgengKernelDebugger 117 | 118 | 119 | DbgengKernelDebugger 120 | $(SolutionDir)$(Platform)\Chapter04\$(ConfigurationName)\ 121 | 122 | 123 | DbgengKernelDebugger 124 | $(SolutionDir)$(Platform)\Chapter04\$(ConfigurationName)\ 125 | 126 | 127 | DbgengKernelDebugger 128 | 129 | 130 | DbgengKernelDebugger 131 | 132 | 133 | DbgengKernelDebugger 134 | 135 | 136 | DbgengKernelDebugger 137 | 138 | 139 | 140 | stdcpp17 141 | 142 | 143 | sha256 144 | 145 | 146 | 147 | 148 | stdcpp17 149 | 150 | 151 | sha256 152 | 153 | 154 | 155 | 156 | sha256 157 | 158 | 159 | 160 | 161 | sha256 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | -------------------------------------------------------------------------------- /chapter04/PriorityBooster/PriorityBooster.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/PriorityBooster/PriorityBoosterCommon.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct ThreadData { 4 | ULONG ThreadId; 5 | int Priority; 6 | }; 7 | 8 | #define PRIORITY_BOOSTER_DEVICE 0x8000 9 | 10 | #define IOCTL_PRIORITY_BOOSTER_SET_PRIORITY CTL_CODE(PRIORITY_BOOSTER_DEVICE, \ 11 | 0x800, METHOD_NEITHER, FILE_ANY_ACCESS) 12 | -------------------------------------------------------------------------------- /chapter06/Booster/Booster.cpp: -------------------------------------------------------------------------------- 1 | // Booster.cpp : This file contains the 'main' function. Program execution begins and ends there. 2 | // 3 | 4 | #include 5 | #include 6 | #include "..\PriorityBooster\PriorityBoosterCommon.h" 7 | 8 | int Error(const char* message) { 9 | printf("%s (error=%d)\n", message, GetLastError()); 10 | return 1; 11 | } 12 | 13 | int main(int argc, const char* argv[]) { 14 | if (argc < 3) { 15 | printf("Usage: Booster \n"); 16 | return 0; 17 | } 18 | 19 | HANDLE hDevice = CreateFile(L"\\\\.\\PriorityBooster", GENERIC_WRITE, FILE_SHARE_WRITE, 20 | nullptr, OPEN_EXISTING, 0, nullptr); 21 | if (hDevice == INVALID_HANDLE_VALUE) 22 | return Error("Failed to open device"); 23 | 24 | ThreadData data; 25 | data.ThreadId = atoi(argv[1]); 26 | data.Priority = atoi(argv[2]); 27 | 28 | DWORD returned; 29 | BOOL success = DeviceIoControl(hDevice, IOCTL_PRIORITY_BOOSTER_SET_PRIORITY, &data, sizeof(data), nullptr, 0, &returned, nullptr); 30 | if (success) 31 | printf("Priority change succeeded!\n"); 32 | else 33 | Error("Priority change failed!"); 34 | 35 | CloseHandle(hDevice); 36 | } 37 | 38 | -------------------------------------------------------------------------------- /chapter06/Booster/Booster.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 16.0 23 | {309C56E6-BB5E-4B48-9327-F16BF887D353} 24 | Win32Proj 25 | Booster 26 | 10.0.17763.0 27 | 28 | 29 | 30 | Application 31 | true 32 | v142 33 | Unicode 34 | 35 | 36 | Application 37 | false 38 | v142 39 | true 40 | Unicode 41 | 42 | 43 | Application 44 | true 45 | v142 46 | Unicode 47 | 48 | 49 | Application 50 | false 51 | v142 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | 76 | 77 | true 78 | 79 | 80 | false 81 | 82 | 83 | false 84 | 85 | 86 | 87 | 88 | 89 | Level3 90 | Disabled 91 | true 92 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 93 | true 94 | MultiThreadedDebug 95 | 96 | 97 | Console 98 | true 99 | 100 | 101 | 102 | 103 | 104 | 105 | Level3 106 | Disabled 107 | true 108 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 109 | true 110 | 111 | 112 | Console 113 | true 114 | 115 | 116 | 117 | 118 | 119 | 120 | Level3 121 | MaxSpeed 122 | true 123 | true 124 | true 125 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 126 | true 127 | 128 | 129 | Console 130 | true 131 | true 132 | true 133 | 134 | 135 | 136 | 137 | 138 | 139 | Level3 140 | MaxSpeed 141 | true 142 | true 143 | true 144 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 145 | true 146 | 147 | 148 | Console 149 | true 150 | true 151 | true 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | -------------------------------------------------------------------------------- /chapter06/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;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 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /chapter06/PriorityBooster/PriorityBooster.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "PriorityBoosterCommon.h" 4 | 5 | // prototypes 6 | 7 | void PriorityBoosterUnload(_In_ PDRIVER_OBJECT DriverObject); 8 | NTSTATUS PriorityBoosterCreateClose(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp); 9 | NTSTATUS PriorityBoosterDeviceControl(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp); 10 | 11 | // DriverEntry 12 | 13 | extern "C" NTSTATUS 14 | DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath) { 15 | UNREFERENCED_PARAMETER(RegistryPath); 16 | 17 | DriverObject->DriverUnload = PriorityBoosterUnload; 18 | 19 | DriverObject->MajorFunction[IRP_MJ_CREATE] = PriorityBoosterCreateClose; 20 | DriverObject->MajorFunction[IRP_MJ_CLOSE] = PriorityBoosterCreateClose; 21 | DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = PriorityBoosterDeviceControl; 22 | 23 | UNICODE_STRING devName = RTL_CONSTANT_STRING(L"\\Device\\PriorityBooster"); 24 | //RtlInitUnicodeString(&devName, L"\\Device\\ThreadBoost"); 25 | PDEVICE_OBJECT DeviceObject; 26 | NTSTATUS status = IoCreateDevice(DriverObject, 0, &devName, FILE_DEVICE_UNKNOWN, 0, FALSE, &DeviceObject); 27 | if (!NT_SUCCESS(status)) { 28 | KdPrint(("Failed to create device (0x%08X)\n", status)); 29 | return status; 30 | } 31 | 32 | UNICODE_STRING symLink = RTL_CONSTANT_STRING(L"\\??\\PriorityBooster"); 33 | status = IoCreateSymbolicLink(&symLink, &devName); 34 | if (!NT_SUCCESS(status)) { 35 | KdPrint(("Failed to create symbolic link (0x%08X)\n", status)); 36 | IoDeleteDevice(DeviceObject); 37 | return status; 38 | } 39 | 40 | return STATUS_SUCCESS; 41 | } 42 | 43 | void PriorityBoosterUnload(_In_ PDRIVER_OBJECT DriverObject) { 44 | UNICODE_STRING symLink = RTL_CONSTANT_STRING(L"\\??\\PriorityBooster"); 45 | // delete symbolic link 46 | IoDeleteSymbolicLink(&symLink); 47 | 48 | // delete device object 49 | IoDeleteDevice(DriverObject->DeviceObject); 50 | } 51 | 52 | _Use_decl_annotations_ 53 | NTSTATUS PriorityBoosterCreateClose(PDEVICE_OBJECT DeviceObject, PIRP Irp) { 54 | UNREFERENCED_PARAMETER(DeviceObject); 55 | 56 | Irp->IoStatus.Status = STATUS_SUCCESS; 57 | Irp->IoStatus.Information = 0; 58 | IoCompleteRequest(Irp, IO_NO_INCREMENT); 59 | return STATUS_SUCCESS; 60 | } 61 | 62 | _Use_decl_annotations_ 63 | NTSTATUS PriorityBoosterDeviceControl(PDEVICE_OBJECT, PIRP Irp) { 64 | // get our IO_STACK_LOCATION 65 | auto stack = IoGetCurrentIrpStackLocation(Irp); 66 | auto status = STATUS_SUCCESS; 67 | 68 | switch (stack->Parameters.DeviceIoControl.IoControlCode) { 69 | case IOCTL_PRIORITY_BOOSTER_SET_PRIORITY: 70 | { 71 | // do the work 72 | if (stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(ThreadData)) { 73 | status = STATUS_BUFFER_TOO_SMALL; 74 | break; 75 | } 76 | 77 | auto data = (ThreadData*)stack->Parameters.DeviceIoControl.Type3InputBuffer; 78 | if (data == nullptr) { 79 | status = STATUS_INVALID_PARAMETER; 80 | break; 81 | } 82 | 83 | __try { 84 | if (data->Priority < 1 || data->Priority > 31) { 85 | status = STATUS_INVALID_PARAMETER; 86 | break; 87 | } 88 | 89 | PETHREAD Thread; 90 | status = PsLookupThreadByThreadId(ULongToHandle(data->ThreadId), &Thread); 91 | if (!NT_SUCCESS(status)) 92 | break; 93 | 94 | KeSetPriorityThread((PKTHREAD)Thread, data->Priority); 95 | ObDereferenceObject(Thread); 96 | KdPrint(("Thread Priority change for %d to %d succeeded!\n", 97 | data->ThreadId, data->Priority)); 98 | } 99 | __except (EXCEPTION_EXECUTE_HANDLER) { 100 | // something wrong with the buffer 101 | status = STATUS_ACCESS_VIOLATION; 102 | } 103 | break; 104 | } 105 | 106 | default: 107 | status = STATUS_INVALID_DEVICE_REQUEST; 108 | break; 109 | } 110 | 111 | Irp->IoStatus.Status = status; 112 | Irp->IoStatus.Information = 0; 113 | IoCompleteRequest(Irp, IO_NO_INCREMENT); 114 | return status; 115 | } 116 | -------------------------------------------------------------------------------- /chapter06/PriorityBooster/PriorityBooster.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | Debug 22 | ARM 23 | 24 | 25 | Release 26 | ARM 27 | 28 | 29 | Debug 30 | ARM64 31 | 32 | 33 | Release 34 | ARM64 35 | 36 | 37 | 38 | {5FCA7533-3FD9-44DA-8BF5-528CAC34910F} 39 | {dd38f7fc-d7bd-488b-9242-7d8754cde80d} 40 | v4.5 41 | 12.0 42 | Debug 43 | Win32 44 | PriorityBooster 45 | 46 | 47 | 48 | Windows10 49 | true 50 | WindowsKernelModeDriver10.0 51 | Driver 52 | WDM 53 | 54 | 55 | Windows10 56 | false 57 | WindowsKernelModeDriver10.0 58 | Driver 59 | WDM 60 | 61 | 62 | Windows10 63 | true 64 | WindowsKernelModeDriver10.0 65 | Driver 66 | WDM 67 | 68 | 69 | Windows10 70 | false 71 | WindowsKernelModeDriver10.0 72 | Driver 73 | WDM 74 | 75 | 76 | Windows10 77 | true 78 | WindowsKernelModeDriver10.0 79 | Driver 80 | WDM 81 | 82 | 83 | Windows10 84 | false 85 | WindowsKernelModeDriver10.0 86 | Driver 87 | WDM 88 | 89 | 90 | Windows10 91 | true 92 | WindowsKernelModeDriver10.0 93 | Driver 94 | WDM 95 | 96 | 97 | Windows10 98 | false 99 | WindowsKernelModeDriver10.0 100 | Driver 101 | WDM 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | DbgengKernelDebugger 113 | 114 | 115 | DbgengKernelDebugger 116 | 117 | 118 | DbgengKernelDebugger 119 | 120 | 121 | DbgengKernelDebugger 122 | 123 | 124 | DbgengKernelDebugger 125 | 126 | 127 | DbgengKernelDebugger 128 | 129 | 130 | DbgengKernelDebugger 131 | 132 | 133 | DbgengKernelDebugger 134 | 135 | 136 | 137 | stdcpp17 138 | 139 | 140 | sha256 141 | 142 | 143 | 144 | 145 | stdcpp17 146 | 147 | 148 | sha256 149 | 150 | 151 | 152 | 153 | sha256 154 | 155 | 156 | 157 | 158 | sha256 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | -------------------------------------------------------------------------------- /chapter06/PriorityBooster/PriorityBooster.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 | -------------------------------------------------------------------------------- /chapter06/PriorityBooster/PriorityBoosterCommon.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct ThreadData { 4 | ULONG ThreadId; 5 | int Priority; 6 | }; 7 | 8 | #define PRIORITY_BOOSTER_DEVICE 0x8000 9 | 10 | #define IOCTL_PRIORITY_BOOSTER_SET_PRIORITY CTL_CODE(PRIORITY_BOOSTER_DEVICE, \ 11 | 0x800, METHOD_NEITHER, FILE_ANY_ACCESS) 12 | -------------------------------------------------------------------------------- /chapter07/Zero/Zero.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "ZeroCommon.h" 3 | 4 | #define DRIVER_PREFIX "Zero: " 5 | 6 | // prototypes 7 | 8 | void ZeroUnload(PDRIVER_OBJECT DriverObject); 9 | DRIVER_DISPATCH ZeroCreateClose, ZeroRead, ZeroWrite, ZeroDeviceControl; 10 | 11 | // globals 12 | 13 | long long g_TotalRead, g_TotalWritten; 14 | 15 | // DriverEntry 16 | 17 | extern "C" NTSTATUS 18 | DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) { 19 | UNREFERENCED_PARAMETER(RegistryPath); 20 | 21 | DriverObject->DriverUnload = ZeroUnload; 22 | DriverObject->MajorFunction[IRP_MJ_CREATE] = DriverObject->MajorFunction[IRP_MJ_CLOSE] = ZeroCreateClose; 23 | DriverObject->MajorFunction[IRP_MJ_READ] = ZeroRead; 24 | DriverObject->MajorFunction[IRP_MJ_WRITE] = ZeroWrite; 25 | DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ZeroDeviceControl; 26 | 27 | UNICODE_STRING devName = RTL_CONSTANT_STRING(L"\\Device\\Zero"); 28 | UNICODE_STRING symLink = RTL_CONSTANT_STRING(L"\\??\\Zero"); 29 | PDEVICE_OBJECT DeviceObject = nullptr; 30 | auto status = STATUS_SUCCESS; 31 | auto symLinkCreated = false; 32 | 33 | do { 34 | status = IoCreateDevice(DriverObject, 0, &devName, FILE_DEVICE_UNKNOWN, 0, FALSE, &DeviceObject); 35 | if (!NT_SUCCESS(status)) { 36 | KdPrint((DRIVER_PREFIX "failed to create device (0x%08X)\n", status)); 37 | break; 38 | } 39 | DeviceObject->Flags |= DO_DIRECT_IO; 40 | 41 | status = IoCreateSymbolicLink(&symLink, &devName); 42 | if (!NT_SUCCESS(status)) { 43 | KdPrint((DRIVER_PREFIX "failed to create symbolic link (0x%08X)\n", status)); 44 | break; 45 | } 46 | symLinkCreated = true; 47 | 48 | } while (false); 49 | 50 | if (!NT_SUCCESS(status)) { 51 | if (symLinkCreated) 52 | IoDeleteSymbolicLink(&symLink); 53 | if (DeviceObject) 54 | IoDeleteDevice(DeviceObject); 55 | } 56 | 57 | return status; 58 | } 59 | 60 | // implementation 61 | 62 | NTSTATUS CompleteIrp(PIRP Irp, NTSTATUS status = STATUS_SUCCESS, ULONG_PTR info = 0) { 63 | Irp->IoStatus.Status = status; 64 | Irp->IoStatus.Information = info; 65 | IoCompleteRequest(Irp, 0); 66 | return status; 67 | } 68 | 69 | void ZeroUnload(PDRIVER_OBJECT DriverObject) { 70 | UNICODE_STRING symLink = RTL_CONSTANT_STRING(L"\\??\\Zero"); 71 | IoDeleteSymbolicLink(&symLink); 72 | IoDeleteDevice(DriverObject->DeviceObject); 73 | } 74 | 75 | NTSTATUS ZeroCreateClose(PDEVICE_OBJECT, PIRP Irp) { 76 | return CompleteIrp(Irp); 77 | } 78 | 79 | NTSTATUS ZeroRead(PDEVICE_OBJECT, PIRP Irp) { 80 | auto stack = IoGetCurrentIrpStackLocation(Irp); 81 | auto len = stack->Parameters.Read.Length; 82 | if (len == 0) 83 | return CompleteIrp(Irp, STATUS_INVALID_BUFFER_SIZE); 84 | 85 | auto buffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority); 86 | if (!buffer) 87 | return CompleteIrp(Irp, STATUS_INSUFFICIENT_RESOURCES); 88 | 89 | memset(buffer, 0, len); 90 | //g_TotalRead += len; 91 | InterlockedAdd64(&g_TotalRead, len); 92 | 93 | return CompleteIrp(Irp, STATUS_SUCCESS, len); 94 | } 95 | 96 | NTSTATUS ZeroWrite(PDEVICE_OBJECT, PIRP Irp) { 97 | auto stack = IoGetCurrentIrpStackLocation(Irp); 98 | auto len = stack->Parameters.Write.Length; 99 | //g_TotalWritten += len; 100 | InterlockedAdd64(&g_TotalWritten, len); 101 | return CompleteIrp(Irp, STATUS_SUCCESS, len); 102 | } 103 | 104 | NTSTATUS ZeroDeviceControl(PDEVICE_OBJECT, PIRP Irp) { 105 | auto stack = IoGetCurrentIrpStackLocation(Irp); 106 | auto& dic = stack->Parameters.DeviceIoControl; 107 | 108 | if (dic.IoControlCode != IOCTL_ZERO_GET_STATS) 109 | return CompleteIrp(Irp, STATUS_INVALID_DEVICE_REQUEST); 110 | 111 | if (dic.OutputBufferLength < sizeof(ZeroStats)) 112 | return CompleteIrp(Irp, STATUS_BUFFER_TOO_SMALL); 113 | 114 | auto stats = (ZeroStats*)Irp->AssociatedIrp.SystemBuffer; 115 | stats->TotalRead = g_TotalRead; 116 | stats->TotalWritten = g_TotalWritten; 117 | 118 | return CompleteIrp(Irp, STATUS_SUCCESS, sizeof(ZeroStats)); 119 | } 120 | -------------------------------------------------------------------------------- /chapter07/Zero/Zero.inf: -------------------------------------------------------------------------------- 1 | ; 2 | ; Zero.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=Zero.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="Zero Source Disk" 33 | -------------------------------------------------------------------------------- /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 IOCTL_ZERO_GET_STATS CTL_CODE(0x8000, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS) 4 | 5 | struct ZeroStats { 6 | long long TotalRead; 7 | long long TotalWritten; 8 | }; 9 | -------------------------------------------------------------------------------- /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 | 6 | int Error(const char* msg) { 7 | printf("%s: error=%d\n", msg, ::GetLastError()); 8 | return 1; 9 | } 10 | 11 | int main() { 12 | HANDLE hDevice = ::CreateFile(L"\\\\.\\Zero", GENERIC_READ | GENERIC_WRITE, 0, nullptr, 13 | OPEN_EXISTING, 0, nullptr); 14 | if (hDevice == INVALID_HANDLE_VALUE) { 15 | return Error("failed to open device"); 16 | } 17 | 18 | // test read 19 | printf("Test read\n"); 20 | BYTE buffer[64]; 21 | for (int i = 0; i < sizeof(buffer); ++i) 22 | buffer[i] = i + 1; 23 | 24 | DWORD bytes; 25 | BOOL ok = ::ReadFile(hDevice, buffer, sizeof(buffer), &bytes, nullptr); 26 | if (!ok) 27 | return Error("failed to read"); 28 | 29 | if (bytes != sizeof(buffer)) 30 | printf("Wrong number of bytes\n"); 31 | 32 | long total = 0; 33 | for (auto n : buffer) 34 | total += n; 35 | if (total != 0) 36 | printf("Wrong data\n"); 37 | 38 | // test write 39 | printf("Test write\n"); 40 | BYTE buffer2[1024]; // contains junk 41 | 42 | ok = ::WriteFile(hDevice, buffer2, sizeof(buffer2), &bytes, nullptr); 43 | if (!ok) 44 | return Error("failed to write"); 45 | 46 | if (bytes != sizeof(buffer2)) 47 | printf("Wrong byte count\n"); 48 | 49 | ::CloseHandle(hDevice); 50 | } 51 | 52 | -------------------------------------------------------------------------------- /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/SysMon/AutoLock.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | template 4 | struct AutoLock { 5 | AutoLock(TLock& lock) : _lock(lock) { 6 | _lock.Lock(); 7 | } 8 | 9 | ~AutoLock() { 10 | _lock.Unlock(); 11 | } 12 | 13 | private: 14 | TLock& _lock; 15 | }; 16 | -------------------------------------------------------------------------------- /chapter08/SysMon/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 | -------------------------------------------------------------------------------- /chapter08/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 _mutex; 12 | }; 13 | 14 | -------------------------------------------------------------------------------- /chapter08/SysMon/SysMon.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "FastMutex.h" 4 | 5 | #define DRIVER_PREFIX "SysMon: " 6 | #define DRIVER_TAG 'nmys' 7 | 8 | struct Globals { 9 | LIST_ENTRY ItemsHead; 10 | int ItemCount; 11 | FastMutex Mutex; 12 | }; 13 | 14 | template 15 | struct FullItem { 16 | LIST_ENTRY Entry; 17 | T Data; 18 | }; 19 | 20 | -------------------------------------------------------------------------------- /chapter08/SysMon/SysMon.inf: -------------------------------------------------------------------------------- 1 | ; 2 | ; SysMon.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=SysMon.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="SysMon Source Disk" 33 | -------------------------------------------------------------------------------- /chapter08/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 | 33 | 34 | Header Files 35 | 36 | 37 | Header Files 38 | 39 | 40 | Header Files 41 | 42 | 43 | Header Files 44 | 45 | 46 | Header Files 47 | 48 | 49 | -------------------------------------------------------------------------------- /chapter08/SysMon/SysMonCommon.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 | }; 21 | 22 | struct ProcessCreateInfo : ItemHeader { 23 | ULONG ProcessId; 24 | ULONG ParentProcessId; 25 | USHORT CommandLineLength; 26 | USHORT CommandLineOffset; 27 | }; 28 | 29 | struct ThreadCreateExitInfo : ItemHeader { 30 | ULONG ThreadId; 31 | ULONG ProcessId; 32 | }; 33 | 34 | const int MaxImageFileSize = 300; 35 | 36 | struct ImageLoadInfo : ItemHeader { 37 | ULONG ProcessId; 38 | void* LoadAddress; 39 | ULONG_PTR ImageSize; 40 | WCHAR ImageFileName[MaxImageFileSize + 1]; 41 | }; 42 | -------------------------------------------------------------------------------- /chapter08/SysMon/pch.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | -------------------------------------------------------------------------------- /chapter08/SysMon/pch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | -------------------------------------------------------------------------------- /chapter08/SysMonClient/SysMonClient.cpp: -------------------------------------------------------------------------------- 1 | // SysMonClient.cpp : This file contains the 'main' function. Program execution begins and ends there. 2 | // 3 | 4 | #include "pch.h" 5 | #include "..\SysMon\SysMonCommon.h" 6 | #include 7 | 8 | int Error(const char* text) { 9 | printf("%s (%d)\n", text, ::GetLastError()); 10 | return 1; 11 | } 12 | 13 | void DisplayTime(const LARGE_INTEGER& time) { 14 | SYSTEMTIME st; 15 | ::FileTimeToSystemTime((FILETIME*)&time, &st); 16 | printf("%02d:%02d:%02d.%03d: ", st.wHour, st.wMinute, st.wSecond, st.wMilliseconds); 17 | } 18 | 19 | void DisplayInfo(BYTE* buffer, DWORD size) { 20 | auto count = size; 21 | while (count > 0) { 22 | auto header = (ItemHeader*)buffer; 23 | switch (header->Type) { 24 | case ItemType::ProcessExit: 25 | { 26 | DisplayTime(header->Time); 27 | auto info = (ProcessExitInfo*)buffer; 28 | printf("Process %d Exited\n", info->ProcessId); 29 | break; 30 | } 31 | 32 | case ItemType::ProcessCreate: 33 | { 34 | DisplayTime(header->Time); 35 | auto info = (ProcessCreateInfo*)buffer; 36 | std::wstring commandline((WCHAR*)(buffer + info->CommandLineOffset), info->CommandLineLength); 37 | printf("Process %d Created. Command line: %ws\n", info->ProcessId, commandline.c_str()); 38 | break; 39 | } 40 | 41 | case ItemType::ThreadCreate: 42 | { 43 | DisplayTime(header->Time); 44 | auto info = (ThreadCreateExitInfo*)buffer; 45 | printf("Thread %d Created in process %d\n", info->ThreadId, info->ProcessId); 46 | break; 47 | } 48 | 49 | case ItemType::ThreadExit: 50 | { 51 | DisplayTime(header->Time); 52 | auto info = (ThreadCreateExitInfo*)buffer; 53 | printf("Thread %d Exited from process %d\n", info->ThreadId, info->ProcessId); 54 | break; 55 | } 56 | 57 | case ItemType::ImageLoad: 58 | { 59 | DisplayTime(header->Time); 60 | auto info = (ImageLoadInfo*)buffer; 61 | printf("Image loaded into process %d at address 0x%p (%ws)\n", info->ProcessId, info->LoadAddress, info->ImageFileName); 62 | break; 63 | } 64 | 65 | default: 66 | break; 67 | } 68 | buffer += header->Size; 69 | count -= header->Size; 70 | } 71 | 72 | } 73 | 74 | int main() { 75 | auto hFile = ::CreateFile(L"\\\\.\\SysMon", GENERIC_READ, 0, nullptr, OPEN_EXISTING, 0, nullptr); 76 | if (hFile == INVALID_HANDLE_VALUE) 77 | return Error("Failed to open file"); 78 | 79 | BYTE buffer[1 << 16]; 80 | 81 | while (true) { 82 | DWORD bytes; 83 | if (!::ReadFile(hFile, buffer, sizeof(buffer), &bytes, nullptr)) 84 | return Error("Failed to read"); 85 | 86 | if (bytes != 0) 87 | DisplayInfo(buffer, bytes); 88 | 89 | ::Sleep(200); 90 | } 91 | } 92 | 93 | -------------------------------------------------------------------------------- /chapter08/SysMonClient/SysMonClient.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 | -------------------------------------------------------------------------------- /chapter08/SysMonClient/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 | -------------------------------------------------------------------------------- /chapter08/SysMonClient/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 | -------------------------------------------------------------------------------- /chapter09/ProcessProtect/AutoLock.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | template 4 | struct AutoLock { 5 | AutoLock(TLock& lock) : _lock(lock) { 6 | _lock.Lock(); 7 | } 8 | 9 | ~AutoLock() { 10 | _lock.Unlock(); 11 | } 12 | 13 | private: 14 | TLock& _lock; 15 | }; 16 | -------------------------------------------------------------------------------- /chapter09/ProcessProtect/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 | -------------------------------------------------------------------------------- /chapter09/ProcessProtect/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 _mutex; 12 | }; 13 | 14 | -------------------------------------------------------------------------------- /chapter09/ProcessProtect/ProcessProtect.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | 3 | #include "ProcessProtectCommon.h" 4 | #include "ProcessProtect.h" 5 | #include "AutoLock.h" 6 | 7 | // PROTOTYPES 8 | 9 | DRIVER_UNLOAD ProcessProtectUnload; 10 | DRIVER_DISPATCH ProcessProtectCreateClose, ProcessProtectDeviceControl; 11 | 12 | OB_PREOP_CALLBACK_STATUS OnPreOpenProcess(PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION Info); 13 | 14 | bool FindProcess(ULONG pid); 15 | bool AddProcess(ULONG pid); 16 | bool RemoveProcess(ULONG pid); 17 | 18 | // GLOBALS 19 | 20 | Globals g_Data; 21 | 22 | // DriverEntry 23 | 24 | extern "C" 25 | NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING) { 26 | KdPrint((DRIVER_PREFIX "DriverEntry entered\n")); 27 | 28 | g_Data.Init(); 29 | 30 | OB_OPERATION_REGISTRATION operations[] = { 31 | { 32 | PsProcessType, // object type 33 | OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE, 34 | OnPreOpenProcess, nullptr // pre, post 35 | } 36 | }; 37 | OB_CALLBACK_REGISTRATION reg = { 38 | OB_FLT_REGISTRATION_VERSION, 39 | 1, // operation count 40 | RTL_CONSTANT_STRING(L"12345.6171"), // altitude 41 | nullptr, // context 42 | operations 43 | }; 44 | 45 | auto status = STATUS_SUCCESS; 46 | UNICODE_STRING deviceName = RTL_CONSTANT_STRING(L"\\Device\\" PROCESS_PROTECT_NAME); 47 | UNICODE_STRING symName = RTL_CONSTANT_STRING(L"\\??\\" PROCESS_PROTECT_NAME); 48 | PDEVICE_OBJECT DeviceObject = nullptr; 49 | 50 | do { 51 | status = ObRegisterCallbacks(®, &g_Data.RegHandle); 52 | if (!NT_SUCCESS(status)) { 53 | KdPrint((DRIVER_PREFIX "failed to register callbacks (status=%08X)\n", status)); 54 | break; 55 | } 56 | 57 | status = IoCreateDevice(DriverObject, 0, &deviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, &DeviceObject); 58 | if (!NT_SUCCESS(status)) { 59 | KdPrint((DRIVER_PREFIX "failed to create device object (status=%08X)\n", status)); 60 | break; 61 | } 62 | 63 | status = IoCreateSymbolicLink(&symName, &deviceName); 64 | if (!NT_SUCCESS(status)) { 65 | KdPrint((DRIVER_PREFIX "failed to create symbolic link (status=%08X)\n", status)); 66 | break; 67 | } 68 | } while (false); 69 | 70 | if (!NT_SUCCESS(status)) { 71 | if (DeviceObject) 72 | IoDeleteDevice(DeviceObject); 73 | if(g_Data.RegHandle) 74 | ObUnRegisterCallbacks(g_Data.RegHandle); 75 | return status; 76 | } 77 | 78 | DriverObject->DriverUnload = ProcessProtectUnload; 79 | DriverObject->MajorFunction[IRP_MJ_CREATE] = DriverObject->MajorFunction[IRP_MJ_CLOSE] = ProcessProtectCreateClose; 80 | DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ProcessProtectDeviceControl; 81 | 82 | KdPrint((DRIVER_PREFIX "DriverEntry completed successfully\n")); 83 | 84 | return status; 85 | } 86 | 87 | void ProcessProtectUnload(PDRIVER_OBJECT DriverObject) { 88 | ObUnRegisterCallbacks(g_Data.RegHandle); 89 | 90 | UNICODE_STRING symName = RTL_CONSTANT_STRING(L"\\??\\" PROCESS_PROTECT_NAME); 91 | IoDeleteSymbolicLink(&symName); 92 | IoDeleteDevice(DriverObject->DeviceObject); 93 | } 94 | 95 | NTSTATUS ProcessProtectCreateClose(PDEVICE_OBJECT, PIRP Irp) { 96 | Irp->IoStatus.Status = STATUS_SUCCESS; 97 | Irp->IoStatus.Information = 0; 98 | IoCompleteRequest(Irp, IO_NO_INCREMENT); 99 | return STATUS_SUCCESS; 100 | } 101 | 102 | NTSTATUS ProcessProtectDeviceControl(PDEVICE_OBJECT, PIRP Irp) { 103 | auto stack = IoGetCurrentIrpStackLocation(Irp); 104 | auto status = STATUS_SUCCESS; 105 | auto len = 0; 106 | 107 | switch (stack->Parameters.DeviceIoControl.IoControlCode) { 108 | case IOCTL_PROCESS_PROTECT_BY_PID: 109 | { 110 | auto size = stack->Parameters.DeviceIoControl.InputBufferLength; 111 | if (size % sizeof(ULONG) != 0) { 112 | status = STATUS_INVALID_BUFFER_SIZE; 113 | break; 114 | } 115 | 116 | auto data = (ULONG*)Irp->AssociatedIrp.SystemBuffer; 117 | 118 | AutoLock locker(g_Data.Lock); 119 | 120 | for (int i = 0; i < size / sizeof(ULONG); i++) { 121 | auto pid = data[i]; 122 | if (pid == 0) { 123 | status = STATUS_INVALID_PARAMETER; 124 | break; 125 | } 126 | if (FindProcess(pid)) 127 | continue; 128 | 129 | if (g_Data.PidsCount == MaxPids) { 130 | status = STATUS_TOO_MANY_CONTEXT_IDS; 131 | break; 132 | } 133 | 134 | if (!AddProcess(pid)) { 135 | status = STATUS_UNSUCCESSFUL; 136 | break; 137 | } 138 | 139 | len += sizeof(ULONG); 140 | } 141 | 142 | break; 143 | } 144 | 145 | case IOCTL_PROCESS_UNPROTECT_BY_PID: 146 | { 147 | auto size = stack->Parameters.DeviceIoControl.InputBufferLength; 148 | if (size % sizeof(ULONG) != 0) { 149 | status = STATUS_INVALID_BUFFER_SIZE; 150 | break; 151 | } 152 | 153 | auto data = (ULONG*)Irp->AssociatedIrp.SystemBuffer; 154 | 155 | AutoLock locker(g_Data.Lock); 156 | 157 | for (int i = 0; i < size / sizeof(ULONG); i++) { 158 | auto pid = data[i]; 159 | if (pid == 0) { 160 | status = STATUS_INVALID_PARAMETER; 161 | break; 162 | } 163 | if (!RemoveProcess(pid)) 164 | continue; 165 | 166 | len += sizeof(ULONG); 167 | 168 | if (g_Data.PidsCount == 0) 169 | break; 170 | } 171 | 172 | break; 173 | } 174 | 175 | case IOCTL_PROCESS_PROTECT_CLEAR: 176 | { 177 | AutoLock locker(g_Data.Lock); 178 | ::memset(&g_Data.Pids, 0, sizeof(g_Data.Pids)); 179 | g_Data.PidsCount = 0; 180 | break; 181 | } 182 | 183 | default: 184 | status = STATUS_INVALID_DEVICE_REQUEST; 185 | break; 186 | } 187 | 188 | Irp->IoStatus.Status = status; 189 | Irp->IoStatus.Information = len; 190 | IoCompleteRequest(Irp, IO_NO_INCREMENT); 191 | return status; 192 | } 193 | 194 | OB_PREOP_CALLBACK_STATUS OnPreOpenProcess(PVOID /* RegistrationContext */, POB_PRE_OPERATION_INFORMATION Info) { 195 | if(Info->KernelHandle) 196 | return OB_PREOP_SUCCESS; 197 | 198 | auto process = (PEPROCESS)Info->Object; 199 | auto pid = HandleToULong(PsGetProcessId(process)); 200 | 201 | AutoLock locker(g_Data.Lock); 202 | if (FindProcess(pid)) { 203 | // found in list, remove terminate access 204 | Info->Parameters->CreateHandleInformation.DesiredAccess &= ~PROCESS_TERMINATE; 205 | } 206 | 207 | return OB_PREOP_SUCCESS; 208 | } 209 | 210 | bool FindProcess(ULONG pid) { 211 | for (int i = 0; i < MaxPids; i++) 212 | if (g_Data.Pids[i] == pid) 213 | return true; 214 | return false; 215 | } 216 | 217 | bool AddProcess(ULONG pid) { 218 | for(int i = 0; i < MaxPids; i++) 219 | if (g_Data.Pids[i] == 0) { 220 | // empty slot 221 | g_Data.Pids[i] = pid; 222 | g_Data.PidsCount++; 223 | return true; 224 | } 225 | return false; 226 | } 227 | 228 | bool RemoveProcess(ULONG pid) { 229 | for (int i = 0; i < MaxPids; i++) 230 | if (g_Data.Pids[i] == pid) { 231 | g_Data.Pids[i] = 0; 232 | g_Data.PidsCount--; 233 | return true; 234 | } 235 | return false; 236 | } 237 | 238 | -------------------------------------------------------------------------------- /chapter09/ProcessProtect/ProcessProtect.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define DRIVER_PREFIX "ProcessProtect: " 4 | 5 | #define PROCESS_TERMINATE 1 6 | 7 | #include "FastMutex.h" 8 | 9 | const int MaxPids = 256; 10 | 11 | struct Globals { 12 | int PidsCount; // currently protected process count 13 | ULONG Pids[MaxPids]; // protected PIDs 14 | FastMutex Lock; 15 | PVOID RegHandle; 16 | 17 | void Init() { 18 | Lock.Init(); 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /chapter09/ProcessProtect/ProcessProtect.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 | Header Files 47 | 48 | 49 | -------------------------------------------------------------------------------- /chapter09/ProcessProtect/ProcessProtectCommon.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define PROCESS_PROTECT_NAME L"ProcessProtect" 4 | 5 | #define IOCTL_PROCESS_PROTECT_BY_PID CTL_CODE(0x8000, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS) 6 | #define IOCTL_PROCESS_UNPROTECT_BY_PID CTL_CODE(0x8000, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS) 7 | #define IOCTL_PROCESS_PROTECT_CLEAR CTL_CODE(0x8000, 0x802, METHOD_NEITHER, FILE_ANY_ACCESS) 8 | -------------------------------------------------------------------------------- /chapter09/ProcessProtect/pch.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | -------------------------------------------------------------------------------- /chapter09/ProcessProtect/pch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | -------------------------------------------------------------------------------- /chapter09/Protect/Protect.cpp: -------------------------------------------------------------------------------- 1 | // ProcessProtectClient.cpp : This file contains the 'main' function. Program execution begins and ends there. 2 | // 3 | 4 | #include "pch.h" 5 | 6 | #include "..\ProcessProtect\ProcessProtectCommon.h" 7 | 8 | int Error(const char* msg) { 9 | printf("%s (Error: %d)\n", msg, ::GetLastError()); 10 | return 1; 11 | } 12 | 13 | int PrintUsage() { 14 | printf("Protect [add | remove | clear] [pid] ...\n"); 15 | return 0; 16 | } 17 | 18 | std::vector ParsePids(const wchar_t* buffer[], int count) { 19 | std::vector pids; 20 | for (int i = 0; i < count; i++) 21 | pids.push_back(::_wtoi(buffer[i])); 22 | return pids; 23 | } 24 | 25 | int wmain(int argc, const wchar_t* argv[]) { 26 | if(argc < 2) 27 | return PrintUsage(); 28 | 29 | enum class Options { 30 | Unknown, 31 | Add, Remove, Clear 32 | }; 33 | Options option; 34 | if (::_wcsicmp(argv[1], L"add") == 0) 35 | option = Options::Add; 36 | else if (::_wcsicmp(argv[1], L"remove") == 0) 37 | option = Options::Remove; 38 | else if (::_wcsicmp(argv[1], L"clear") == 0) 39 | option = Options::Clear; 40 | else { 41 | printf("Unknown option.\n"); 42 | return PrintUsage(); 43 | } 44 | 45 | HANDLE hFile = ::CreateFile(L"\\\\.\\" PROCESS_PROTECT_NAME, GENERIC_WRITE | GENERIC_READ, 0, nullptr, OPEN_EXISTING, 0, nullptr); 46 | if (hFile == INVALID_HANDLE_VALUE) 47 | return Error("Failed to open device"); 48 | 49 | std::vector pids; 50 | BOOL success = FALSE; 51 | DWORD bytes; 52 | switch (option) { 53 | case Options::Add: 54 | pids = ParsePids(argv + 2, argc - 2); 55 | success = ::DeviceIoControl(hFile, IOCTL_PROCESS_PROTECT_BY_PID, 56 | pids.data(), static_cast(pids.size()) * sizeof(DWORD), 57 | nullptr, 0, &bytes, nullptr); 58 | break; 59 | 60 | case Options::Remove: 61 | pids = ParsePids(argv + 2, argc - 2); 62 | success = ::DeviceIoControl(hFile, IOCTL_PROCESS_UNPROTECT_BY_PID, 63 | pids.data(), static_cast(pids.size()) * sizeof(DWORD), 64 | nullptr, 0, &bytes, nullptr); 65 | break; 66 | 67 | case Options::Clear: 68 | success = ::DeviceIoControl(hFile, IOCTL_PROCESS_PROTECT_CLEAR, 69 | nullptr, 0, nullptr, 0, &bytes, nullptr); 70 | break; 71 | 72 | } 73 | 74 | if (!success) 75 | return Error("Failed in DeviceIoControl"); 76 | 77 | printf("Operation succeeded.\n"); 78 | 79 | ::CloseHandle(hFile); 80 | 81 | return 0; 82 | } 83 | -------------------------------------------------------------------------------- /chapter09/Protect/Protect.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 | -------------------------------------------------------------------------------- /chapter09/Protect/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 | -------------------------------------------------------------------------------- /chapter09/Protect/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 | #include 15 | 16 | #endif //PCH_H 17 | -------------------------------------------------------------------------------- /chapter09/SysMon/AutoLock.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | template 4 | struct AutoLock { 5 | AutoLock(TLock& lock) : _lock(lock) { 6 | _lock.Lock(); 7 | } 8 | 9 | ~AutoLock() { 10 | _lock.Unlock(); 11 | } 12 | 13 | private: 14 | TLock& _lock; 15 | }; 16 | -------------------------------------------------------------------------------- /chapter09/SysMon/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 | -------------------------------------------------------------------------------- /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 _mutex; 12 | }; 13 | 14 | -------------------------------------------------------------------------------- /chapter09/SysMon/SysMon.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "FastMutex.h" 4 | 5 | #define DRIVER_PREFIX "SysMon: " 6 | #define DRIVER_TAG 'nmys' 7 | 8 | struct Globals { 9 | LIST_ENTRY ItemsHead; 10 | int ItemCount; 11 | FastMutex Mutex; 12 | LARGE_INTEGER RegCookie; 13 | }; 14 | 15 | template 16 | struct FullItem { 17 | LIST_ENTRY Entry; 18 | T Data; 19 | }; 20 | 21 | -------------------------------------------------------------------------------- /chapter09/SysMon/SysMon.inf: -------------------------------------------------------------------------------- 1 | ; 2 | ; SysMon.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=SysMon.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="SysMon Source Disk" 33 | -------------------------------------------------------------------------------- /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 | 33 | 34 | Header Files 35 | 36 | 37 | Header Files 38 | 39 | 40 | Header Files 41 | 42 | 43 | Header Files 44 | 45 | 46 | Header Files 47 | 48 | 49 | -------------------------------------------------------------------------------- /chapter09/SysMon/SysMonCommon.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 | }; 22 | 23 | struct ProcessCreateInfo : ItemHeader { 24 | ULONG ProcessId; 25 | ULONG ParentProcessId; 26 | USHORT CommandLineLength; 27 | USHORT CommandLineOffset; 28 | }; 29 | 30 | struct ThreadCreateExitInfo : ItemHeader { 31 | ULONG ThreadId; 32 | ULONG ProcessId; 33 | }; 34 | 35 | const int MaxImageFileSize = 300; 36 | 37 | struct ImageLoadInfo : ItemHeader { 38 | ULONG ProcessId; 39 | void* LoadAddress; 40 | ULONG_PTR ImageSize; 41 | WCHAR ImageFileName[MaxImageFileSize + 1]; 42 | }; 43 | 44 | struct RegistrySetValueInfo : ItemHeader { 45 | ULONG ProcessId; 46 | ULONG ThreadId; 47 | WCHAR KeyName[256]; // full key name 48 | WCHAR ValueName[64]; // value name 49 | ULONG DataType; // REG_xxx 50 | UCHAR Data[128]; // data 51 | ULONG DataSize; // size of data 52 | }; 53 | -------------------------------------------------------------------------------- /chapter09/SysMon/pch.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | -------------------------------------------------------------------------------- /chapter09/SysMon/pch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | -------------------------------------------------------------------------------- /chapter09/SysMonClient/SysMonClient.cpp: -------------------------------------------------------------------------------- 1 | // SysMonClient.cpp : This file contains the 'main' function. Program execution begins and ends there. 2 | // 3 | 4 | #include "pch.h" 5 | #include "..\SysMon\SysMonCommon.h" 6 | #include 7 | 8 | int Error(const char* text) { 9 | printf("%s (%d)\n", text, ::GetLastError()); 10 | return 1; 11 | } 12 | 13 | void DisplayTime(const LARGE_INTEGER& time) { 14 | SYSTEMTIME st; 15 | ::FileTimeToSystemTime((FILETIME*)&time, &st); 16 | printf("%02d:%02d:%02d.%03d: ", st.wHour, st.wMinute, st.wSecond, st.wMilliseconds); 17 | } 18 | 19 | void DisplayBinary(const UCHAR* buffer, DWORD size) { 20 | for (DWORD i = 0; i < size; i++) 21 | printf("%02X ", buffer[i]); 22 | printf("\n"); 23 | } 24 | 25 | void DisplayInfo(BYTE* buffer, DWORD size) { 26 | auto count = size; 27 | while (count > 0) { 28 | auto header = (ItemHeader*)buffer; 29 | switch (header->Type) { 30 | case ItemType::ProcessExit: 31 | { 32 | DisplayTime(header->Time); 33 | auto info = (ProcessExitInfo*)buffer; 34 | printf("Process %d Exited\n", info->ProcessId); 35 | break; 36 | } 37 | 38 | case ItemType::ProcessCreate: 39 | { 40 | DisplayTime(header->Time); 41 | auto info = (ProcessCreateInfo*)buffer; 42 | std::wstring commandline((WCHAR*)(buffer + info->CommandLineOffset), info->CommandLineLength); 43 | printf("Process %d Created. Command line: %ws\n", info->ProcessId, commandline.c_str()); 44 | break; 45 | } 46 | 47 | case ItemType::ThreadCreate: 48 | { 49 | DisplayTime(header->Time); 50 | auto info = (ThreadCreateExitInfo*)buffer; 51 | printf("Thread %d Created in process %d\n", info->ThreadId, info->ProcessId); 52 | break; 53 | } 54 | 55 | case ItemType::ThreadExit: 56 | { 57 | DisplayTime(header->Time); 58 | auto info = (ThreadCreateExitInfo*)buffer; 59 | printf("Thread %d Exited from process %d\n", info->ThreadId, info->ProcessId); 60 | break; 61 | } 62 | 63 | case ItemType::ImageLoad: 64 | { 65 | DisplayTime(header->Time); 66 | auto info = (ImageLoadInfo*)buffer; 67 | printf("Image loaded into process %d at address 0x%p (%ws)\n", info->ProcessId, info->LoadAddress, info->ImageFileName); 68 | break; 69 | } 70 | 71 | case ItemType::RegistrySetValue: 72 | { 73 | DisplayTime(header->Time); 74 | auto info = (RegistrySetValueInfo*)buffer; 75 | printf("Registry write PID=%d: %ws\\%ws type: %d size: %d data: ", info->ProcessId, 76 | info->KeyName, info->ValueName, info->DataType, info->DataSize); 77 | switch (info->DataType) { 78 | case REG_DWORD: 79 | printf("0x%08X\n", *(DWORD*)info->Data); 80 | break; 81 | 82 | case REG_SZ: 83 | case REG_EXPAND_SZ: 84 | printf("%ws\n", (WCHAR*)info->Data); 85 | break; 86 | 87 | case REG_BINARY: 88 | DisplayBinary(info->Data, min(info->DataSize, sizeof(info->Data))); 89 | break; 90 | 91 | default: 92 | DisplayBinary(info->Data, min(info->DataSize, sizeof(info->Data))); 93 | break; 94 | 95 | } 96 | 97 | break; 98 | } 99 | 100 | default: 101 | break; 102 | } 103 | buffer += header->Size; 104 | count -= header->Size; 105 | } 106 | 107 | } 108 | 109 | int main() { 110 | auto hFile = ::CreateFile(L"\\\\.\\SysMon", GENERIC_READ, 0, nullptr, OPEN_EXISTING, 0, nullptr); 111 | if (hFile == INVALID_HANDLE_VALUE) 112 | return Error("Failed to open file"); 113 | 114 | BYTE buffer[1 << 16]; 115 | 116 | while (true) { 117 | DWORD bytes; 118 | if (!::ReadFile(hFile, buffer, sizeof(buffer), &bytes, nullptr)) 119 | return Error("Failed to read"); 120 | 121 | if (bytes != 0) 122 | DisplayInfo(buffer, bytes); 123 | 124 | ::Sleep(200); 125 | } 126 | } 127 | 128 | -------------------------------------------------------------------------------- /chapter09/SysMonClient/SysMonClient.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 | -------------------------------------------------------------------------------- /chapter09/SysMonClient/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 | -------------------------------------------------------------------------------- /chapter09/SysMonClient/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 | -------------------------------------------------------------------------------- /chapter10/DelProtect/DelProtect.inf: -------------------------------------------------------------------------------- 1 | ;;; 2 | ;;; DelProtect 3 | ;;; 4 | 5 | [Version] 6 | Signature = "$Windows NT$" 7 | Class = "Undelete" 8 | ClassGuid = {fe8f1572-c67a-48c0-bbac-0b5c6d66cafb} 9 | Provider = %ManufacturerName% 10 | DriverVer = 11 | CatalogFile = DelProtect.cat 12 | 13 | [DestinationDirs] 14 | DefaultDestDir = 12 15 | MiniFilter.DriverFiles = 12 ;%windir%\system32\drivers 16 | 17 | ;; 18 | ;; Default install sections 19 | ;; 20 | 21 | [DefaultInstall] 22 | OptionDesc = %ServiceDescription% 23 | CopyFiles = MiniFilter.DriverFiles 24 | 25 | [DefaultInstall.Services] 26 | AddService = %ServiceName%,,MiniFilter.Service 27 | 28 | ;; 29 | ;; Default uninstall sections 30 | ;; 31 | 32 | [DefaultUninstall] 33 | DelFiles = MiniFilter.DriverFiles 34 | 35 | [DefaultUninstall.Services] 36 | DelService = %ServiceName%,0x200 ;Ensure service is stopped before deleting 37 | 38 | ; 39 | ; Services Section 40 | ; 41 | 42 | [MiniFilter.Service] 43 | DisplayName = %ServiceName% 44 | Description = %ServiceDescription% 45 | ServiceBinary = %12%\%DriverName%.sys ;%windir%\system32\drivers\ 46 | Dependencies = "FltMgr" 47 | ServiceType = 2 ;SERVICE_FILE_SYSTEM_DRIVER 48 | StartType = 3 ;SERVICE_DEMAND_START 49 | ErrorControl = 1 ;SERVICE_ERROR_NORMAL 50 | LoadOrderGroup = "FS Undelete filters" 51 | AddReg = MiniFilter.AddRegistry 52 | 53 | ; 54 | ; Registry Modifications 55 | ; 56 | 57 | [MiniFilter.AddRegistry] 58 | HKR,,"DebugFlags",0x00010001 ,0x0 59 | HKR,,"SupportedFeatures",0x00010001,0x3 60 | HKR,"Instances","DefaultInstance",0x00000000,%DefaultInstance% 61 | HKR,"Instances\"%Instance1.Name%,"Altitude",0x00000000,%Instance1.Altitude% 62 | HKR,"Instances\"%Instance1.Name%,"Flags",0x00010001,%Instance1.Flags% 63 | 64 | ; 65 | ; Copy Files 66 | ; 67 | 68 | [MiniFilter.DriverFiles] 69 | %DriverName%.sys 70 | 71 | [SourceDisksFiles] 72 | DelProtect.sys = 1,, 73 | 74 | [SourceDisksNames] 75 | 1 = %DiskId1%,,, 76 | 77 | ;; 78 | ;; String Section 79 | ;; 80 | 81 | [Strings] 82 | ; TODO - Add your manufacturer 83 | ManufacturerName = "WindowsDriversBook" 84 | ServiceDescription = "DelProtect Mini-Filter Driver" 85 | ServiceName = "DelProtect" 86 | DriverName = "DelProtect" 87 | DiskId1 = "DelProtect Device Installation Disk" 88 | 89 | ;Instances specific information. 90 | DefaultInstance = "DelProtect Instance" 91 | Instance1.Name = "DelProtect Instance" 92 | Instance1.Altitude = "345101" 93 | Instance1.Flags = 0x0 ; Allow all attachments 94 | -------------------------------------------------------------------------------- /chapter10/DelProtect/DelProtect.rc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #define VER_FILETYPE VFT_DRV 6 | #define VER_FILESUBTYPE VFT2_DRV_SYSTEM 7 | #define VER_FILEDESCRIPTION_STR "DelProtect Filter Driver" 8 | #define VER_INTERNALNAME_STR "DelProtect.sys" 9 | 10 | #include "common.ver" 11 | -------------------------------------------------------------------------------- /chapter10/DelProtect/DelProtect.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 | Resource Files 29 | 30 | 31 | 32 | 33 | Source Files 34 | 35 | 36 | -------------------------------------------------------------------------------- /chapter10/DelProtect2/AutoLock.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | template 4 | struct AutoLock { 5 | AutoLock(TLock& lock) : _lock(lock) { 6 | _lock.Lock(); 7 | } 8 | 9 | ~AutoLock() { 10 | _lock.Unlock(); 11 | } 12 | 13 | private: 14 | TLock& _lock; 15 | }; 16 | -------------------------------------------------------------------------------- /chapter10/DelProtect2/DelProtect.rc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #define VER_FILETYPE VFT_DRV 6 | #define VER_FILESUBTYPE VFT2_DRV_SYSTEM 7 | #define VER_FILEDESCRIPTION_STR "DelProtect Filter Driver" 8 | #define VER_INTERNALNAME_STR "DelProtect.sys" 9 | 10 | #include "common.ver" 11 | -------------------------------------------------------------------------------- /chapter10/DelProtect2/DelProtect2.inf: -------------------------------------------------------------------------------- 1 | ;;; 2 | ;;; DelProtect 3 | ;;; 4 | 5 | [Version] 6 | Signature = "$Windows NT$" 7 | Class = "Undelete" 8 | ClassGuid = {fe8f1572-c67a-48c0-bbac-0b5c6d66cafb} 9 | Provider = %ManufacturerName% 10 | DriverVer = 11 | CatalogFile = DelProtect.cat 12 | 13 | [DestinationDirs] 14 | DefaultDestDir = 12 15 | MiniFilter.DriverFiles = 12 ;%windir%\system32\drivers 16 | 17 | ;; 18 | ;; Default install sections 19 | ;; 20 | 21 | [DefaultInstall] 22 | OptionDesc = %ServiceDescription% 23 | CopyFiles = MiniFilter.DriverFiles 24 | 25 | [DefaultInstall.Services] 26 | AddService = %ServiceName%,,MiniFilter.Service 27 | 28 | ;; 29 | ;; Default uninstall sections 30 | ;; 31 | 32 | [DefaultUninstall] 33 | DelFiles = MiniFilter.DriverFiles 34 | 35 | [DefaultUninstall.Services] 36 | DelService = %ServiceName%,0x200 ;Ensure service is stopped before deleting 37 | 38 | ; 39 | ; Services Section 40 | ; 41 | 42 | [MiniFilter.Service] 43 | DisplayName = %ServiceName% 44 | Description = %ServiceDescription% 45 | ServiceBinary = %12%\%DriverName%.sys ;%windir%\system32\drivers\ 46 | Dependencies = "FltMgr" 47 | ServiceType = 2 ;SERVICE_FILE_SYSTEM_DRIVER 48 | StartType = 3 ;SERVICE_DEMAND_START 49 | ErrorControl = 1 ;SERVICE_ERROR_NORMAL 50 | LoadOrderGroup = "FS Undelete filters" 51 | AddReg = MiniFilter.AddRegistry 52 | 53 | ; 54 | ; Registry Modifications 55 | ; 56 | 57 | [MiniFilter.AddRegistry] 58 | HKR,,"DebugFlags",0x00010001 ,0x0 59 | HKR,,"SupportedFeatures",0x00010001,0x3 60 | HKR,"Instances","DefaultInstance",0x00000000,%DefaultInstance% 61 | HKR,"Instances\"%Instance1.Name%,"Altitude",0x00000000,%Instance1.Altitude% 62 | HKR,"Instances\"%Instance1.Name%,"Flags",0x00010001,%Instance1.Flags% 63 | 64 | ; 65 | ; Copy Files 66 | ; 67 | 68 | [MiniFilter.DriverFiles] 69 | %DriverName%.sys 70 | 71 | [SourceDisksFiles] 72 | DelProtect2.sys = 1,, 73 | 74 | [SourceDisksNames] 75 | 1 = %DiskId1%,,, 76 | 77 | ;; 78 | ;; String Section 79 | ;; 80 | 81 | [Strings] 82 | ; TODO - Add your manufacturer 83 | ManufacturerName = "WindowsDriversBook" 84 | ServiceDescription = "DelProtect Mini-Filter Driver" 85 | ServiceName = "DelProtect2" 86 | DriverName = "DelProtect2" 87 | DiskId1 = "DelProtect Device Installation Disk" 88 | 89 | ;Instances specific information. 90 | DefaultInstance = "DelProtect Instance" 91 | Instance1.Name = "DelProtect Instance" 92 | Instance1.Altitude = "345102" 93 | Instance1.Flags = 0x0 ; Allow all attachments 94 | -------------------------------------------------------------------------------- /chapter10/DelProtect2/DelProtect2.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 | Resource Files 24 | 25 | 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | 35 | 36 | Header Files 37 | 38 | 39 | 40 | 41 | Driver Files 42 | 43 | 44 | -------------------------------------------------------------------------------- /chapter10/DelProtect2/DelProtectCommon.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define IOCTL_DELPROTECT_ADD_EXE CTL_CODE(0x8000, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS) 4 | #define IOCTL_DELPROTECT_REMOVE_EXE CTL_CODE(0x8000, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS) 5 | #define IOCTL_DELPROTECT_CLEAR CTL_CODE(0x8000, 0x802, METHOD_NEITHER, FILE_ANY_ACCESS) 6 | 7 | -------------------------------------------------------------------------------- /chapter10/DelProtect2/FastMutex.cpp: -------------------------------------------------------------------------------- 1 | #include "FastMutex.h" 2 | 3 | 4 | void FastMutex::Init() { 5 | ExInitializeFastMutex(&_mutex); 6 | } 7 | 8 | void FastMutex::Lock() { 9 | ExAcquireFastMutex(&_mutex); 10 | } 11 | 12 | void FastMutex::Unlock() { 13 | ExReleaseFastMutex(&_mutex); 14 | } 15 | -------------------------------------------------------------------------------- /chapter10/DelProtect2/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 | -------------------------------------------------------------------------------- /chapter10/DelProtect3/AutoLock.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | template 4 | struct AutoLock { 5 | AutoLock(TLock& lock) : _lock(lock) { 6 | _lock.Lock(); 7 | } 8 | 9 | ~AutoLock() { 10 | _lock.Unlock(); 11 | } 12 | 13 | private: 14 | TLock& _lock; 15 | }; 16 | -------------------------------------------------------------------------------- /chapter10/DelProtect3/DelProtect.rc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #define VER_FILETYPE VFT_DRV 6 | #define VER_FILESUBTYPE VFT2_DRV_SYSTEM 7 | #define VER_FILEDESCRIPTION_STR "DelProtect Filter Driver" 8 | #define VER_INTERNALNAME_STR "DelProtect.sys" 9 | 10 | #include "common.ver" 11 | -------------------------------------------------------------------------------- /chapter10/DelProtect3/DelProtect3.inf: -------------------------------------------------------------------------------- 1 | ;;; 2 | ;;; DelProtect 3 | ;;; 4 | 5 | [Version] 6 | Signature = "$Windows NT$" 7 | Class = "Undelete" 8 | ClassGuid = {fe8f1572-c67a-48c0-bbac-0b5c6d66cafb} 9 | Provider = %ManufacturerName% 10 | DriverVer = 11 | CatalogFile = DelProtect.cat 12 | 13 | [DestinationDirs] 14 | DefaultDestDir = 12 15 | MiniFilter.DriverFiles = 12 ;%windir%\system32\drivers 16 | 17 | ;; 18 | ;; Default install sections 19 | ;; 20 | 21 | [DefaultInstall] 22 | OptionDesc = %ServiceDescription% 23 | CopyFiles = MiniFilter.DriverFiles 24 | 25 | [DefaultInstall.Services] 26 | AddService = %ServiceName%,,MiniFilter.Service 27 | 28 | ;; 29 | ;; Default uninstall sections 30 | ;; 31 | 32 | [DefaultUninstall] 33 | DelFiles = MiniFilter.DriverFiles 34 | 35 | [DefaultUninstall.Services] 36 | DelService = %ServiceName%,0x200 ;Ensure service is stopped before deleting 37 | 38 | ; 39 | ; Services Section 40 | ; 41 | 42 | [MiniFilter.Service] 43 | DisplayName = %ServiceName% 44 | Description = %ServiceDescription% 45 | ServiceBinary = %12%\%DriverName%.sys ;%windir%\system32\drivers\ 46 | Dependencies = "FltMgr" 47 | ServiceType = 2 ;SERVICE_FILE_SYSTEM_DRIVER 48 | StartType = 3 ;SERVICE_DEMAND_START 49 | ErrorControl = 1 ;SERVICE_ERROR_NORMAL 50 | LoadOrderGroup = "FS Undelete filters" 51 | AddReg = MiniFilter.AddRegistry 52 | 53 | ; 54 | ; Registry Modifications 55 | ; 56 | 57 | [MiniFilter.AddRegistry] 58 | HKR,,"DebugFlags",0x00010001 ,0x0 59 | HKR,,"SupportedFeatures",0x00010001,0x3 60 | HKR,"Instances","DefaultInstance",0x00000000,%DefaultInstance% 61 | HKR,"Instances\"%Instance1.Name%,"Altitude",0x00000000,%Instance1.Altitude% 62 | HKR,"Instances\"%Instance1.Name%,"Flags",0x00010001,%Instance1.Flags% 63 | 64 | ; 65 | ; Copy Files 66 | ; 67 | 68 | [MiniFilter.DriverFiles] 69 | %DriverName%.sys 70 | 71 | [SourceDisksFiles] 72 | DelProtect3.sys = 1,, 73 | 74 | [SourceDisksNames] 75 | 1 = %DiskId1%,,, 76 | 77 | ;; 78 | ;; String Section 79 | ;; 80 | 81 | [Strings] 82 | ; TODO - Add your manufacturer 83 | ManufacturerName = "WindowsDriversBook" 84 | ServiceDescription = "DelProtect Mini-Filter Driver" 85 | ServiceName = "DelProtect3" 86 | DriverName = "DelProtect3" 87 | DiskId1 = "DelProtect Device Installation Disk" 88 | 89 | ;Instances specific information. 90 | DefaultInstance = "DelProtect Instance" 91 | Instance1.Name = "DelProtect Instance" 92 | Instance1.Altitude = "345103" 93 | Instance1.Flags = 0x0 ; Allow all attachments 94 | -------------------------------------------------------------------------------- /chapter10/DelProtect3/DelProtect3.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 | Resource Files 24 | 25 | 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | Source Files 35 | 36 | 37 | 38 | 39 | Header Files 40 | 41 | 42 | Header Files 43 | 44 | 45 | 46 | 47 | Driver Files 48 | 49 | 50 | -------------------------------------------------------------------------------- /chapter10/DelProtect3/DelProtectCommon.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define IOCTL_DELPROTECT_ADD_DIR CTL_CODE(0x8000, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS) 4 | #define IOCTL_DELPROTECT_REMOVE_DIR CTL_CODE(0x8000, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS) 5 | #define IOCTL_DELPROTECT_CLEAR CTL_CODE(0x8000, 0x802, METHOD_NEITHER, FILE_ANY_ACCESS) 6 | 7 | -------------------------------------------------------------------------------- /chapter10/DelProtect3/FastMutex.cpp: -------------------------------------------------------------------------------- 1 | #include "FastMutex.h" 2 | 3 | 4 | void FastMutex::Init() { 5 | ExInitializeFastMutex(&_mutex); 6 | } 7 | 8 | void FastMutex::Lock() { 9 | ExAcquireFastMutex(&_mutex); 10 | } 11 | 12 | void FastMutex::Unlock() { 13 | ExReleaseFastMutex(&_mutex); 14 | } 15 | -------------------------------------------------------------------------------- /chapter10/DelProtect3/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 | -------------------------------------------------------------------------------- /chapter10/DelProtect3/kstring.cpp: -------------------------------------------------------------------------------- 1 | #include "kstring.h" 2 | 3 | kstring::kstring(const wchar_t* str, POOL_TYPE pool, ULONG tag) : kstring(str, 0, pool, tag) { 4 | } 5 | 6 | kstring::kstring(const wchar_t* str, ULONG count, POOL_TYPE pool, ULONG tag) : m_Pool(pool), m_Tag(tag) { 7 | if (str) { 8 | m_Len = count == 0 ? static_cast(wcslen(str)) : count; 9 | m_Capacity = m_Len + 1; 10 | m_str = Allocate(m_Capacity, str); 11 | if (!m_str) 12 | ExRaiseStatus(STATUS_NO_MEMORY); 13 | } 14 | else { 15 | m_str = nullptr; 16 | m_Len = m_Capacity = 0; 17 | } 18 | } 19 | 20 | kstring::~kstring() { 21 | Release(); 22 | } 23 | 24 | void kstring::Release() { 25 | if (m_str) { 26 | ExFreePoolWithTag(m_str, m_Tag); 27 | m_str = nullptr; 28 | } 29 | } 30 | 31 | kstring::kstring(kstring&& other) { 32 | m_Len = other.m_Len; 33 | m_str = other.m_str; 34 | m_Pool = other.m_Pool; 35 | other.m_str = nullptr; 36 | other.m_Len = 0; 37 | } 38 | 39 | kstring& kstring::operator+=(const kstring& other) { 40 | return Append(other); 41 | } 42 | 43 | kstring& kstring::operator+=(PCWSTR str) { 44 | m_Len += static_cast(::wcslen(str)); 45 | auto newBuffer = Allocate(m_Len, m_str); 46 | ::wcscat_s(newBuffer, m_Len + 1, str); 47 | Release(); 48 | m_str = newBuffer; 49 | return *this; 50 | } 51 | 52 | bool kstring::operator==(const kstring& other) { 53 | return wcscmp(m_str, other.m_str) == 0; 54 | } 55 | 56 | const wchar_t kstring::GetAt(size_t index) const { 57 | NT_ASSERT(index < m_Len); 58 | return m_str[index]; 59 | } 60 | 61 | wchar_t& kstring::GetAt(size_t index) { 62 | NT_ASSERT(index < m_Len); 63 | return m_str[index]; 64 | } 65 | 66 | kstring& kstring::operator=(kstring&& other) { 67 | if (this != &other) { 68 | if (m_str) 69 | ExFreePoolWithTag(m_str, m_Tag); 70 | m_Len = other.m_Len; 71 | m_str = other.m_str; 72 | other.m_str = nullptr; 73 | other.m_Len = 0; 74 | } 75 | return *this; 76 | } 77 | 78 | kstring::kstring(PCUNICODE_STRING str, POOL_TYPE pool, ULONG tag) : m_Pool(pool), m_Tag(tag) { 79 | m_Len = str->Length / sizeof(WCHAR); 80 | m_str = Allocate(m_Len, str->Buffer); 81 | } 82 | 83 | kstring::kstring(const kstring& other) : m_Len(other.m_Len) { 84 | m_Pool = other.m_Pool; 85 | m_Tag = other.m_Tag; 86 | if (m_Len > 0) { 87 | m_str = Allocate(m_Len, other.m_str); 88 | } 89 | else { 90 | m_str = nullptr; 91 | } 92 | } 93 | 94 | kstring& kstring::operator=(const kstring& other) { 95 | if (this != &other) { 96 | if (m_str) 97 | ExFreePoolWithTag(m_str, m_Tag); 98 | m_Len = other.m_Len; 99 | m_Tag = other.m_Tag; 100 | m_Pool = other.m_Pool; 101 | if (other.m_str) { 102 | m_str = Allocate(m_Len, other.m_str); 103 | } 104 | } 105 | return *this; 106 | } 107 | 108 | UNICODE_STRING* kstring::GetUnicodeString(PUNICODE_STRING pUnicodeString) { 109 | RtlInitUnicodeString(pUnicodeString, m_str); 110 | return pUnicodeString; 111 | } 112 | 113 | wchar_t* kstring::Allocate(size_t chars, const wchar_t* src) { 114 | auto str = static_cast(ExAllocatePoolWithTag(m_Pool, sizeof(WCHAR) * (chars + 1), m_Tag)); 115 | if (!str) { 116 | KdPrint(("Failed to allocate kstring of length %d chars\n", chars)); 117 | return nullptr; 118 | } 119 | if (src) { 120 | wcscpy_s(str, chars + 1, src); 121 | } 122 | return str; 123 | } 124 | 125 | kstring kstring::ToLower() const { 126 | kstring temp(m_str); 127 | ::_wcslwr(temp.m_str); 128 | return temp; 129 | } 130 | 131 | kstring& kstring::ToLower() { 132 | ::_wcslwr(m_str); 133 | return *this; 134 | } 135 | 136 | kstring& kstring::Truncate(ULONG count) { 137 | if (count >= m_Len) { 138 | NT_ASSERT(false); 139 | } 140 | else { 141 | m_Len = count; 142 | m_str[m_Len] = L'\0'; 143 | } 144 | return *this; 145 | } 146 | 147 | kstring & kstring::Append(PCWSTR str, ULONG len) { 148 | if (len == 0) 149 | len = (ULONG)::wcslen(str); 150 | auto newBuffer = m_str; 151 | auto newAlloc = false; 152 | m_Len += len; 153 | if (m_Len + 1 > m_Capacity) { 154 | newBuffer = Allocate(m_Capacity = m_Len + 8, m_str); 155 | newAlloc = true; 156 | } 157 | ::wcsncat_s(newBuffer, m_Capacity, str, len); 158 | if (newAlloc) { 159 | Release(); 160 | m_str = newBuffer; 161 | } 162 | return *this; 163 | } 164 | -------------------------------------------------------------------------------- /chapter10/DelProtect3/kstring.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | class kstring final { 6 | public: 7 | explicit kstring(const wchar_t* str = nullptr, POOL_TYPE pool = PagedPool, ULONG tag = 0); 8 | kstring(const wchar_t* str, ULONG count, POOL_TYPE pool = PagedPool, ULONG tag = 0); 9 | kstring(const kstring& other); 10 | explicit kstring(PCUNICODE_STRING str, POOL_TYPE pool = PagedPool, ULONG tag = 0); 11 | kstring& operator= (const kstring& other); 12 | kstring(kstring&& other); 13 | kstring& operator=(kstring&& other); 14 | 15 | ~kstring(); 16 | 17 | kstring& operator+=(const kstring& other); 18 | kstring& operator+=(PCWSTR str); 19 | 20 | bool operator==(const kstring& other); 21 | 22 | operator const wchar_t* () const { 23 | return m_str; 24 | } 25 | 26 | const wchar_t* Get() const { 27 | return m_str; 28 | } 29 | 30 | ULONG Length() const { 31 | return m_Len; 32 | } 33 | 34 | kstring ToLower() const; 35 | kstring& ToLower(); 36 | kstring& Truncate(ULONG length); 37 | kstring& Append(PCWSTR str, ULONG len = 0); 38 | 39 | void Release(); 40 | 41 | inline const wchar_t GetAt(size_t index) const; 42 | 43 | wchar_t& GetAt(size_t index); 44 | 45 | const wchar_t operator[](size_t index) const { 46 | return GetAt(index); 47 | } 48 | 49 | wchar_t& operator[](size_t index) { 50 | return GetAt(index); 51 | } 52 | 53 | UNICODE_STRING* GetUnicodeString(PUNICODE_STRING); 54 | 55 | private: 56 | wchar_t* Allocate(size_t chars, const wchar_t* src = nullptr); 57 | 58 | private: 59 | wchar_t* m_str; 60 | ULONG m_Len, m_Capacity; 61 | POOL_TYPE m_Pool; 62 | ULONG m_Tag; 63 | }; 64 | -------------------------------------------------------------------------------- /chapter10/DelProtectConfig/DelProtectConfig.cpp: -------------------------------------------------------------------------------- 1 | // DelProtectConfig.cpp : This file contains the 'main' function. Program execution begins and ends there. 2 | // 3 | 4 | #include "pch.h" 5 | 6 | #include "..\DelProtect2\DelProtectCommon.h" 7 | 8 | int Error(const char* text) { 9 | printf("%s (%d)\n", text, ::GetLastError()); 10 | return 1; 11 | } 12 | 13 | int PrintUsage() { 14 | printf("Usage: DelProtectConfig