├── README.md ├── minivers Package ├── minivers Package.vcxproj └── minivers Package.vcxproj.filters ├── minivers.sln └── minivers ├── RegistrationData.c ├── copy_file.c ├── copy_file.h ├── minivers.c ├── minivers.h ├── minivers.inf ├── minivers.rc ├── minivers.vcxproj └── minivers.vcxproj.filters /README.md: -------------------------------------------------------------------------------- 1 | Minivers File System Minifilter Driver 2 | ====================================== 3 | 4 | Minivers is a Windows file system minifilter driver which monitors changes in files with certain extensions. If a monitored file is about to be changed, deleted or renamed, a backup copy of the file is performed before the operation begins. 5 | 6 | The file name of the backup files has the format: 7 | ``` 8 | .YYYYMMDD_hhmmss_mmm.minivers 9 | ``` 10 | 11 | 12 | The following file extensions are monitored: 13 | * doc 14 | * docx 15 | * xls 16 | * xlsx 17 | * txt 18 | 19 | You can add more file extensions by editing the file minivers.c: 20 | ``` 21 | /****************************************************************************** 22 | ****************************************************************************** 23 | ** ** 24 | ** File extensions to be taken into account. ** 25 | ** ** 26 | ****************************************************************************** 27 | ******************************************************************************/ 28 | DECLARE_CONST_UNICODE_STRING(DOC, L"doc"); 29 | DECLARE_CONST_UNICODE_STRING(DOCX, L"docx"); 30 | DECLARE_CONST_UNICODE_STRING(XLS, L"xls"); 31 | DECLARE_CONST_UNICODE_STRING(XLSX, L"xlsx"); 32 | DECLARE_CONST_UNICODE_STRING(TXT, L"txt"); 33 | 34 | static const UNICODE_STRING* extensions[] = {&DOC, &DOCX, &XLS, &XLSX, &TXT}; 35 | ``` 36 | 37 | 38 | The backup files have the extension `minivers`: 39 | ``` 40 | DECLARE_CONST_UNICODE_STRING(MINIVERS_EXT, L"minivers"); 41 | ``` 42 | 43 | 44 | Files with this file extension cannot be deleted, if you want to change this, change the following `define`: 45 | ``` 46 | #define IMMUTABLE_BACKUP_FILES TRUE 47 | ``` 48 | 49 | 50 | Minivers can be used to protect against ransomware, as they search files with certain extensions (not tested though). 51 | 52 | Minivers logs the name of the executable which produced the change, to avoid this change the following `define`: 53 | ``` 54 | #define LOG_IMAGE_FILENAME TRUE 55 | ``` 56 | -------------------------------------------------------------------------------- /minivers Package/minivers Package.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Win8.1 Debug 6 | Win32 7 | 8 | 9 | Win8.1 Release 10 | Win32 11 | 12 | 13 | Win8 Debug 14 | Win32 15 | 16 | 17 | Win8 Release 18 | Win32 19 | 20 | 21 | Win7 Debug 22 | Win32 23 | 24 | 25 | Win7 Release 26 | Win32 27 | 28 | 29 | Win8.1 Debug 30 | x64 31 | 32 | 33 | Win8.1 Release 34 | x64 35 | 36 | 37 | Win8 Debug 38 | x64 39 | 40 | 41 | Win8 Release 42 | x64 43 | 44 | 45 | Win7 Debug 46 | x64 47 | 48 | 49 | Win7 Release 50 | x64 51 | 52 | 53 | 54 | {305D7A16-455C-4019-946A-7CBFFC6508D1} 55 | {4605da2c-74a5-4865-98e1-152ef136825f} 56 | v4.5 57 | 11.0 58 | Win8.1 Debug 59 | Win32 60 | minivers_Package 61 | 62 | 63 | 64 | WindowsV6.3 65 | true 66 | WindowsKernelModeDriver8.1 67 | Utility 68 | Package 69 | true 70 | 71 | 72 | WindowsV6.3 73 | false 74 | WindowsKernelModeDriver8.1 75 | Utility 76 | Package 77 | true 78 | 79 | 80 | Windows8 81 | true 82 | WindowsKernelModeDriver8.1 83 | Utility 84 | Package 85 | true 86 | 87 | 88 | Windows8 89 | false 90 | WindowsKernelModeDriver8.1 91 | Utility 92 | Package 93 | true 94 | 95 | 96 | Windows7 97 | true 98 | WindowsKernelModeDriver8.1 99 | Utility 100 | Package 101 | true 102 | 103 | 104 | Windows7 105 | false 106 | WindowsKernelModeDriver8.1 107 | Utility 108 | Package 109 | true 110 | 111 | 112 | WindowsV6.3 113 | true 114 | WindowsKernelModeDriver8.1 115 | Utility 116 | Package 117 | true 118 | 119 | 120 | WindowsV6.3 121 | false 122 | WindowsKernelModeDriver8.1 123 | Utility 124 | Package 125 | true 126 | 127 | 128 | Windows8 129 | true 130 | WindowsKernelModeDriver8.1 131 | Utility 132 | Package 133 | true 134 | 135 | 136 | Windows8 137 | false 138 | WindowsKernelModeDriver8.1 139 | Utility 140 | Package 141 | true 142 | 143 | 144 | Windows7 145 | true 146 | WindowsKernelModeDriver8.1 147 | Utility 148 | Package 149 | true 150 | 151 | 152 | Windows7 153 | false 154 | WindowsKernelModeDriver8.1 155 | Utility 156 | Package 157 | true 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | DbgengKernelDebugger 169 | False 170 | True 171 | 172 | 173 | 174 | False 175 | False 176 | True 177 | 178 | 133563 179 | 180 | 181 | DbgengKernelDebugger 182 | False 183 | True 184 | 185 | 186 | 187 | False 188 | False 189 | True 190 | 191 | 133563 192 | 193 | 194 | DbgengKernelDebugger 195 | False 196 | True 197 | 198 | 199 | 200 | False 201 | False 202 | True 203 | 204 | 133563 205 | 206 | 207 | DbgengKernelDebugger 208 | False 209 | True 210 | 211 | 212 | 213 | False 214 | False 215 | True 216 | 217 | 133563 218 | 219 | 220 | DbgengKernelDebugger 221 | False 222 | True 223 | 224 | 225 | 226 | False 227 | False 228 | True 229 | 230 | 133563 231 | 232 | 233 | DbgengKernelDebugger 234 | False 235 | True 236 | 237 | 238 | 239 | False 240 | False 241 | True 242 | 243 | 133563 244 | 245 | 246 | DbgengKernelDebugger 247 | False 248 | True 249 | 250 | 251 | 252 | False 253 | False 254 | True 255 | 256 | 133563 257 | 258 | 259 | DbgengKernelDebugger 260 | False 261 | True 262 | 263 | 264 | 265 | False 266 | False 267 | True 268 | 269 | 133563 270 | 271 | 272 | DbgengKernelDebugger 273 | False 274 | True 275 | 276 | 277 | 278 | False 279 | False 280 | True 281 | 282 | 133563 283 | 284 | 285 | DbgengKernelDebugger 286 | False 287 | True 288 | 289 | 290 | 291 | False 292 | False 293 | True 294 | 295 | 133563 296 | 297 | 298 | DbgengKernelDebugger 299 | False 300 | True 301 | 302 | 303 | 304 | False 305 | False 306 | True 307 | 308 | 133563 309 | 310 | 311 | DbgengKernelDebugger 312 | False 313 | True 314 | 315 | 316 | 317 | False 318 | False 319 | True 320 | 321 | 133563 322 | 323 | 324 | 325 | 326 | 327 | 328 | {e337ac23-f84d-4e6d-81e9-729f64684a30} 329 | 330 | 331 | 332 | 333 | 334 | -------------------------------------------------------------------------------- /minivers Package/minivers Package.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {8E41214B-6785-4CFE-B992-037D68949A14} 6 | inf;inv;inx;mof;mc; 7 | 8 | 9 | -------------------------------------------------------------------------------- /minivers.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Express 2013 for Windows Desktop 4 | VisualStudioVersion = 12.0.31101.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "minivers", "minivers\minivers.vcxproj", "{E337AC23-F84D-4E6D-81E9-729F64684A30}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "minivers Package", "minivers Package\minivers Package.vcxproj", "{305D7A16-455C-4019-946A-7CBFFC6508D1}" 9 | ProjectSection(ProjectDependencies) = postProject 10 | {E337AC23-F84D-4E6D-81E9-729F64684A30} = {E337AC23-F84D-4E6D-81E9-729F64684A30} 11 | EndProjectSection 12 | EndProject 13 | Global 14 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 15 | Win7 Debug|Win32 = Win7 Debug|Win32 16 | Win7 Debug|x64 = Win7 Debug|x64 17 | Win7 Release|Win32 = Win7 Release|Win32 18 | Win7 Release|x64 = Win7 Release|x64 19 | Win8 Debug|Win32 = Win8 Debug|Win32 20 | Win8 Debug|x64 = Win8 Debug|x64 21 | Win8 Release|Win32 = Win8 Release|Win32 22 | Win8 Release|x64 = Win8 Release|x64 23 | Win8.1 Debug|Win32 = Win8.1 Debug|Win32 24 | Win8.1 Debug|x64 = Win8.1 Debug|x64 25 | Win8.1 Release|Win32 = Win8.1 Release|Win32 26 | Win8.1 Release|x64 = Win8.1 Release|x64 27 | EndGlobalSection 28 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 29 | {E337AC23-F84D-4E6D-81E9-729F64684A30}.Win7 Debug|Win32.ActiveCfg = Win7 Debug|Win32 30 | {E337AC23-F84D-4E6D-81E9-729F64684A30}.Win7 Debug|Win32.Build.0 = Win7 Debug|Win32 31 | {E337AC23-F84D-4E6D-81E9-729F64684A30}.Win7 Debug|Win32.Deploy.0 = Win7 Debug|Win32 32 | {E337AC23-F84D-4E6D-81E9-729F64684A30}.Win7 Debug|x64.ActiveCfg = Win7 Debug|x64 33 | {E337AC23-F84D-4E6D-81E9-729F64684A30}.Win7 Debug|x64.Build.0 = Win7 Debug|x64 34 | {E337AC23-F84D-4E6D-81E9-729F64684A30}.Win7 Debug|x64.Deploy.0 = Win7 Debug|x64 35 | {E337AC23-F84D-4E6D-81E9-729F64684A30}.Win7 Release|Win32.ActiveCfg = Win7 Release|Win32 36 | {E337AC23-F84D-4E6D-81E9-729F64684A30}.Win7 Release|Win32.Build.0 = Win7 Release|Win32 37 | {E337AC23-F84D-4E6D-81E9-729F64684A30}.Win7 Release|Win32.Deploy.0 = Win7 Release|Win32 38 | {E337AC23-F84D-4E6D-81E9-729F64684A30}.Win7 Release|x64.ActiveCfg = Win7 Release|x64 39 | {E337AC23-F84D-4E6D-81E9-729F64684A30}.Win7 Release|x64.Build.0 = Win7 Release|x64 40 | {E337AC23-F84D-4E6D-81E9-729F64684A30}.Win7 Release|x64.Deploy.0 = Win7 Release|x64 41 | {E337AC23-F84D-4E6D-81E9-729F64684A30}.Win8 Debug|Win32.ActiveCfg = Win8 Debug|Win32 42 | {E337AC23-F84D-4E6D-81E9-729F64684A30}.Win8 Debug|Win32.Build.0 = Win8 Debug|Win32 43 | {E337AC23-F84D-4E6D-81E9-729F64684A30}.Win8 Debug|Win32.Deploy.0 = Win8 Debug|Win32 44 | {E337AC23-F84D-4E6D-81E9-729F64684A30}.Win8 Debug|x64.ActiveCfg = Win8 Debug|x64 45 | {E337AC23-F84D-4E6D-81E9-729F64684A30}.Win8 Debug|x64.Build.0 = Win8 Debug|x64 46 | {E337AC23-F84D-4E6D-81E9-729F64684A30}.Win8 Debug|x64.Deploy.0 = Win8 Debug|x64 47 | {E337AC23-F84D-4E6D-81E9-729F64684A30}.Win8 Release|Win32.ActiveCfg = Win8 Release|Win32 48 | {E337AC23-F84D-4E6D-81E9-729F64684A30}.Win8 Release|Win32.Build.0 = Win8 Release|Win32 49 | {E337AC23-F84D-4E6D-81E9-729F64684A30}.Win8 Release|Win32.Deploy.0 = Win8 Release|Win32 50 | {E337AC23-F84D-4E6D-81E9-729F64684A30}.Win8 Release|x64.ActiveCfg = Win8 Release|x64 51 | {E337AC23-F84D-4E6D-81E9-729F64684A30}.Win8 Release|x64.Build.0 = Win8 Release|x64 52 | {E337AC23-F84D-4E6D-81E9-729F64684A30}.Win8 Release|x64.Deploy.0 = Win8 Release|x64 53 | {E337AC23-F84D-4E6D-81E9-729F64684A30}.Win8.1 Debug|Win32.ActiveCfg = Win8.1 Debug|Win32 54 | {E337AC23-F84D-4E6D-81E9-729F64684A30}.Win8.1 Debug|Win32.Build.0 = Win8.1 Debug|Win32 55 | {E337AC23-F84D-4E6D-81E9-729F64684A30}.Win8.1 Debug|Win32.Deploy.0 = Win8.1 Debug|Win32 56 | {E337AC23-F84D-4E6D-81E9-729F64684A30}.Win8.1 Debug|x64.ActiveCfg = Win8.1 Debug|x64 57 | {E337AC23-F84D-4E6D-81E9-729F64684A30}.Win8.1 Debug|x64.Build.0 = Win8.1 Debug|x64 58 | {E337AC23-F84D-4E6D-81E9-729F64684A30}.Win8.1 Debug|x64.Deploy.0 = Win8.1 Debug|x64 59 | {E337AC23-F84D-4E6D-81E9-729F64684A30}.Win8.1 Release|Win32.ActiveCfg = Win8.1 Release|Win32 60 | {E337AC23-F84D-4E6D-81E9-729F64684A30}.Win8.1 Release|Win32.Build.0 = Win8.1 Release|Win32 61 | {E337AC23-F84D-4E6D-81E9-729F64684A30}.Win8.1 Release|Win32.Deploy.0 = Win8.1 Release|Win32 62 | {E337AC23-F84D-4E6D-81E9-729F64684A30}.Win8.1 Release|x64.ActiveCfg = Win8.1 Release|x64 63 | {E337AC23-F84D-4E6D-81E9-729F64684A30}.Win8.1 Release|x64.Build.0 = Win8.1 Release|x64 64 | {E337AC23-F84D-4E6D-81E9-729F64684A30}.Win8.1 Release|x64.Deploy.0 = Win8.1 Release|x64 65 | {305D7A16-455C-4019-946A-7CBFFC6508D1}.Win7 Debug|Win32.ActiveCfg = Win7 Debug|Win32 66 | {305D7A16-455C-4019-946A-7CBFFC6508D1}.Win7 Debug|Win32.Build.0 = Win7 Debug|Win32 67 | {305D7A16-455C-4019-946A-7CBFFC6508D1}.Win7 Debug|Win32.Deploy.0 = Win7 Debug|Win32 68 | {305D7A16-455C-4019-946A-7CBFFC6508D1}.Win7 Debug|x64.ActiveCfg = Win7 Debug|x64 69 | {305D7A16-455C-4019-946A-7CBFFC6508D1}.Win7 Debug|x64.Build.0 = Win7 Debug|x64 70 | {305D7A16-455C-4019-946A-7CBFFC6508D1}.Win7 Debug|x64.Deploy.0 = Win7 Debug|x64 71 | {305D7A16-455C-4019-946A-7CBFFC6508D1}.Win7 Release|Win32.ActiveCfg = Win7 Release|Win32 72 | {305D7A16-455C-4019-946A-7CBFFC6508D1}.Win7 Release|Win32.Build.0 = Win7 Release|Win32 73 | {305D7A16-455C-4019-946A-7CBFFC6508D1}.Win7 Release|Win32.Deploy.0 = Win7 Release|Win32 74 | {305D7A16-455C-4019-946A-7CBFFC6508D1}.Win7 Release|x64.ActiveCfg = Win7 Release|x64 75 | {305D7A16-455C-4019-946A-7CBFFC6508D1}.Win7 Release|x64.Build.0 = Win7 Release|x64 76 | {305D7A16-455C-4019-946A-7CBFFC6508D1}.Win7 Release|x64.Deploy.0 = Win7 Release|x64 77 | {305D7A16-455C-4019-946A-7CBFFC6508D1}.Win8 Debug|Win32.ActiveCfg = Win8 Debug|Win32 78 | {305D7A16-455C-4019-946A-7CBFFC6508D1}.Win8 Debug|Win32.Build.0 = Win8 Debug|Win32 79 | {305D7A16-455C-4019-946A-7CBFFC6508D1}.Win8 Debug|Win32.Deploy.0 = Win8 Debug|Win32 80 | {305D7A16-455C-4019-946A-7CBFFC6508D1}.Win8 Debug|x64.ActiveCfg = Win8 Debug|x64 81 | {305D7A16-455C-4019-946A-7CBFFC6508D1}.Win8 Debug|x64.Build.0 = Win8 Debug|x64 82 | {305D7A16-455C-4019-946A-7CBFFC6508D1}.Win8 Debug|x64.Deploy.0 = Win8 Debug|x64 83 | {305D7A16-455C-4019-946A-7CBFFC6508D1}.Win8 Release|Win32.ActiveCfg = Win8 Release|Win32 84 | {305D7A16-455C-4019-946A-7CBFFC6508D1}.Win8 Release|Win32.Build.0 = Win8 Release|Win32 85 | {305D7A16-455C-4019-946A-7CBFFC6508D1}.Win8 Release|Win32.Deploy.0 = Win8 Release|Win32 86 | {305D7A16-455C-4019-946A-7CBFFC6508D1}.Win8 Release|x64.ActiveCfg = Win8 Release|x64 87 | {305D7A16-455C-4019-946A-7CBFFC6508D1}.Win8 Release|x64.Build.0 = Win8 Release|x64 88 | {305D7A16-455C-4019-946A-7CBFFC6508D1}.Win8 Release|x64.Deploy.0 = Win8 Release|x64 89 | {305D7A16-455C-4019-946A-7CBFFC6508D1}.Win8.1 Debug|Win32.ActiveCfg = Win8.1 Debug|Win32 90 | {305D7A16-455C-4019-946A-7CBFFC6508D1}.Win8.1 Debug|Win32.Build.0 = Win8.1 Debug|Win32 91 | {305D7A16-455C-4019-946A-7CBFFC6508D1}.Win8.1 Debug|Win32.Deploy.0 = Win8.1 Debug|Win32 92 | {305D7A16-455C-4019-946A-7CBFFC6508D1}.Win8.1 Debug|x64.ActiveCfg = Win8.1 Debug|x64 93 | {305D7A16-455C-4019-946A-7CBFFC6508D1}.Win8.1 Debug|x64.Build.0 = Win8.1 Debug|x64 94 | {305D7A16-455C-4019-946A-7CBFFC6508D1}.Win8.1 Debug|x64.Deploy.0 = Win8.1 Debug|x64 95 | {305D7A16-455C-4019-946A-7CBFFC6508D1}.Win8.1 Release|Win32.ActiveCfg = Win8.1 Release|Win32 96 | {305D7A16-455C-4019-946A-7CBFFC6508D1}.Win8.1 Release|Win32.Build.0 = Win8.1 Release|Win32 97 | {305D7A16-455C-4019-946A-7CBFFC6508D1}.Win8.1 Release|Win32.Deploy.0 = Win8.1 Release|Win32 98 | {305D7A16-455C-4019-946A-7CBFFC6508D1}.Win8.1 Release|x64.ActiveCfg = Win8.1 Release|x64 99 | {305D7A16-455C-4019-946A-7CBFFC6508D1}.Win8.1 Release|x64.Build.0 = Win8.1 Release|x64 100 | {305D7A16-455C-4019-946A-7CBFFC6508D1}.Win8.1 Release|x64.Deploy.0 = Win8.1 Release|x64 101 | EndGlobalSection 102 | GlobalSection(SolutionProperties) = preSolution 103 | HideSolutionNode = FALSE 104 | EndGlobalSection 105 | EndGlobal 106 | -------------------------------------------------------------------------------- /minivers/RegistrationData.c: -------------------------------------------------------------------------------- 1 | #include "minivers.h" 2 | 3 | /* Place all the following DATA and CONSTANT DATA in the INIT segment. */ 4 | #ifdef ALLOC_DATA_PRAGMA 5 | #pragma data_seg("INIT") 6 | #pragma const_seg("INIT") 7 | #endif /* ALLOC_DATA_PRAGMA */ 8 | 9 | CONST FLT_OPERATION_REGISTRATION callbacks[] = { 10 | {IRP_MJ_CREATE, 0, PreOperationCallback, NULL}, 11 | {IRP_MJ_SET_INFORMATION, 0, PreOperationCallback, NULL}, 12 | {IRP_MJ_OPERATION_END } 13 | }; 14 | 15 | CONST FLT_REGISTRATION filter_registration = { 16 | sizeof(FLT_REGISTRATION), /* Size. */ 17 | FLT_REGISTRATION_VERSION, /* Version. */ 18 | 0, /* Flags. */ 19 | NULL, /* ContextRegistration. */ 20 | callbacks, /* OperationRegistration. */ 21 | FilterUnload, /* FilterUnloadCallback. */ 22 | InstanceSetup, /* InstanceSetupCallback. */ 23 | InstanceQueryTeardown, /* InstanceQueryTeardownCallback. */ 24 | NULL, /* InstanceTeardownStartCallback. */ 25 | NULL, /* InstanceTeardownCompleteCallback. */ 26 | NULL, /* GenerateFileNameCallback. */ 27 | NULL, /* NormalizeNameComponentCallback. */ 28 | NULL /* NormalizeContextCleanupCallback. */ 29 | 30 | #if FLT_MGR_LONGHORN 31 | , NULL /* TransactionNotificationCallback. */ 32 | , NULL /* NormalizeNameComponentExCallback. */ 33 | #endif /* FLT_MGR_LONGHORN */ 34 | #if FLT_MFG_WIN8 35 | , NULL /* SectionNotificationCallback. */ 36 | #endif 37 | }; 38 | 39 | /* Restore the given section types back to their previous section definition. */ 40 | #ifdef ALLOC_DATA_PRAGMA 41 | #pragma data_seg() 42 | #pragma const_seg() 43 | #endif /* ALLOC_DATA_PRAGMA */ 44 | -------------------------------------------------------------------------------- /minivers/copy_file.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "copy_file.h" 3 | #include "minivers.h" 4 | 5 | #define BUFFER_SIZE (4 * 1024) 6 | 7 | static BOOLEAN write(HANDLE hFile, void* buf, ULONG len); 8 | static BOOLEAN delete_file(PFLT_INSTANCE instance, PFILE_OBJECT file); 9 | 10 | /* Disable warning: 11 | * Conditional expression is constant: 12 | * do { 13 | * ... 14 | * } while (1); 15 | */ 16 | #pragma warning(disable:4127) 17 | 18 | BOOLEAN copy_file(PFLT_FILTER filter, 19 | PFLT_INSTANCE instance, 20 | UNICODE_STRING* dest, 21 | UNICODE_STRING* src) 22 | { 23 | HANDLE hInput, hOutput; 24 | PFILE_OBJECT out; 25 | OBJECT_ATTRIBUTES attr; 26 | IO_STATUS_BLOCK io_status_block; 27 | PVOID buf; 28 | ULONGLONG filesize; 29 | NTSTATUS status; 30 | 31 | InitializeObjectAttributes(&attr, 32 | src, 33 | OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, 34 | NULL, 35 | NULL); 36 | 37 | /* Open input file for reading. */ 38 | status = FltCreateFile(filter, /* Filter */ 39 | instance, /* Instance */ 40 | &hInput, /* FileHandle */ 41 | GENERIC_READ, /* DesiredAccess */ 42 | &attr, /* ObjectAttributes */ 43 | &io_status_block, /* IoStatusBlock */ 44 | NULL, /* AllocationSize */ 45 | FILE_ATTRIBUTE_NORMAL, /* FileAttributes */ 46 | FILE_SHARE_READ | /* ShareAccess */ 47 | FILE_SHARE_WRITE | 48 | FILE_SHARE_DELETE, 49 | FILE_OPEN, /* CreateDisposition */ 50 | FILE_SYNCHRONOUS_IO_NONALERT, /* CreateOptions */ 51 | NULL, /* EaBuffer */ 52 | 0, /* EaLength */ 53 | IO_FORCE_ACCESS_CHECK); /* Flags */ 54 | 55 | /* If the input file could be opened... */ 56 | if (NT_SUCCESS(status)) { 57 | InitializeObjectAttributes(&attr, 58 | dest, 59 | OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, 60 | NULL, 61 | NULL); 62 | 63 | /* Open output file for writing. */ 64 | status = FltCreateFileEx(filter, /* Filter */ 65 | instance, /* Instance */ 66 | &hOutput, /* FileHandle */ 67 | &out, /* FileObject */ 68 | GENERIC_WRITE, /* DesiredAccess */ 69 | &attr, /* ObjectAttributes */ 70 | &io_status_block, /* IoStatusBlock */ 71 | NULL, /* AllocationSize */ 72 | FILE_ATTRIBUTE_NORMAL, /* FileAttributes */ 73 | 0, /* ShareAccess */ 74 | FILE_OVERWRITE_IF, /* CreateDisposition */ 75 | FILE_SYNCHRONOUS_IO_NONALERT, /* CreateOptions */ 76 | NULL, /* EaBuffer */ 77 | 0, /* EaLength */ 78 | IO_FORCE_ACCESS_CHECK); /* Flags */ 79 | 80 | /* If the output file could be opened... */ 81 | if (NT_SUCCESS(status)) { 82 | /* Allocate memory. */ 83 | if ((buf = ExAllocatePoolWithTag(NonPagedPool, 84 | BUFFER_SIZE, 85 | TAG)) != NULL) { 86 | filesize = 0; 87 | 88 | do { 89 | /* Read from the input file. */ 90 | status = ZwReadFile(hInput, /* FileHandle */ 91 | NULL, /* Event */ 92 | NULL, /* ApcRoutine */ 93 | NULL, /* ApcContext */ 94 | &io_status_block, /* IoStatusBlock */ 95 | buf, /* Buffer */ 96 | BUFFER_SIZE, /* Length */ 97 | NULL, /* ByteOffset */ 98 | NULL); /* Key */ 99 | 100 | if (NT_SUCCESS(status)) { 101 | if (write(hOutput, buf, io_status_block.Information)) { 102 | filesize += io_status_block.Information; 103 | } else { 104 | /* Free memory. */ 105 | ExFreePoolWithTag(buf, TAG); 106 | 107 | /* Close input file. */ 108 | FltClose(hInput); 109 | 110 | /* Delete output file. */ 111 | delete_file(instance, out); 112 | 113 | /* Close output file. */ 114 | FltClose(hOutput); 115 | ObDereferenceObject(out); 116 | 117 | return FALSE; 118 | } 119 | } else if (status == STATUS_END_OF_FILE) { 120 | /* Free memory. */ 121 | ExFreePoolWithTag(buf, TAG); 122 | 123 | /* Close input file. */ 124 | FltClose(hInput); 125 | 126 | /* If the file is not empty... */ 127 | if (filesize > 0) { 128 | DbgPrint("Copied file '%wZ' -> '%wZ', filesize: %lu.", 129 | src, 130 | dest, 131 | filesize); 132 | } else { 133 | /* Delete output file. */ 134 | delete_file(instance, out); 135 | } 136 | 137 | /* Close output file. */ 138 | FltClose(hOutput); 139 | ObDereferenceObject(out); 140 | 141 | return TRUE; 142 | } else { 143 | /* Free memory. */ 144 | ExFreePoolWithTag(buf, TAG); 145 | 146 | /* Close input file. */ 147 | FltClose(hInput); 148 | 149 | /* Delete output file. */ 150 | delete_file(instance, out); 151 | 152 | /* Close output file. */ 153 | FltClose(hOutput); 154 | ObDereferenceObject(out); 155 | 156 | return FALSE; 157 | } 158 | } while (1); 159 | } else { 160 | /* Delete output file. */ 161 | delete_file(instance, out); 162 | 163 | /* Close output file. */ 164 | FltClose(hOutput); 165 | ObDereferenceObject(out); 166 | } 167 | } 168 | 169 | /* Close input file. */ 170 | FltClose(hInput); 171 | } 172 | 173 | return FALSE; 174 | } 175 | 176 | BOOLEAN write(HANDLE hFile, void* buf, ULONG len) 177 | { 178 | IO_STATUS_BLOCK io_status_block; 179 | UCHAR* b; 180 | 181 | b = (UCHAR*) buf; 182 | 183 | while (len > 0) { 184 | if (!NT_SUCCESS(ZwWriteFile(hFile, /* FileHandle */ 185 | NULL, /* Event */ 186 | NULL, /* ApcRoutine */ 187 | NULL, /* ApcContext */ 188 | &io_status_block, /* IoStatusBlock */ 189 | b, /* Buffer */ 190 | len, /* Length */ 191 | NULL, /* ByteOffset */ 192 | NULL))) { /* Key */ 193 | return FALSE; 194 | } 195 | 196 | b += io_status_block.Information; 197 | len -= io_status_block.Information; 198 | } 199 | 200 | return TRUE; 201 | } 202 | 203 | BOOLEAN delete_file(PFLT_INSTANCE instance, PFILE_OBJECT file) 204 | { 205 | FILE_DISPOSITION_INFORMATION info; 206 | 207 | info.DeleteFile = TRUE; 208 | 209 | return NT_SUCCESS(FltSetInformationFile(instance, 210 | file, 211 | &info, 212 | sizeof(FILE_DISPOSITION_INFORMATION), 213 | FileDispositionInformation)); 214 | } 215 | -------------------------------------------------------------------------------- /minivers/copy_file.h: -------------------------------------------------------------------------------- 1 | #ifndef COPY_FILE_H 2 | #define COPY_FILE_H 3 | 4 | #include 5 | #include 6 | 7 | BOOLEAN copy_file(PFLT_FILTER filter, 8 | PFLT_INSTANCE instance, 9 | UNICODE_STRING* dest, 10 | UNICODE_STRING* src); 11 | 12 | #endif /* COPY_FILE_H */ 13 | -------------------------------------------------------------------------------- /minivers/minivers.c: -------------------------------------------------------------------------------- 1 | #include "minivers.h" 2 | #include 3 | #include "copy_file.h" 4 | 5 | #define DEFERRED_IO TRUE 6 | #define IMMUTABLE_BACKUP_FILES TRUE 7 | #define LOG_IMAGE_FILENAME TRUE 8 | 9 | static DRIVER_DATA driver_data; 10 | 11 | #if LOG_IMAGE_FILENAME 12 | #define EXE_MAX_LEN (4 * 1024) 13 | 14 | /* Prototype of the function 'ZwQueryInformationProcess()'. */ 15 | typedef NTSTATUS (*QueryInformationProcess)(HANDLE, 16 | PROCESSINFOCLASS, 17 | PVOID, 18 | ULONG, 19 | PULONG); 20 | 21 | /* Pointer to the function 'ZwQueryInformationProcess()'. */ 22 | static QueryInformationProcess fnQueryInformationProcess = NULL; 23 | #endif /* LOG_IMAGE_FILENAME */ 24 | 25 | 26 | /****************************************************************************** 27 | ****************************************************************************** 28 | ** ** 29 | ** File extensions to be taken into account. ** 30 | ** ** 31 | ****************************************************************************** 32 | ******************************************************************************/ 33 | DECLARE_CONST_UNICODE_STRING(DOC, L"doc"); 34 | DECLARE_CONST_UNICODE_STRING(DOCX, L"docx"); 35 | DECLARE_CONST_UNICODE_STRING(XLS, L"xls"); 36 | DECLARE_CONST_UNICODE_STRING(XLSX, L"xlsx"); 37 | DECLARE_CONST_UNICODE_STRING(TXT, L"txt"); 38 | 39 | static const UNICODE_STRING* extensions[] = {&DOC, &DOCX, &XLS, &XLSX, &TXT}; 40 | 41 | 42 | /****************************************************************************** 43 | ****************************************************************************** 44 | ** ** 45 | ** minivers's file extension. ** 46 | ** ** 47 | ****************************************************************************** 48 | ******************************************************************************/ 49 | DECLARE_CONST_UNICODE_STRING(MINIVERS_EXT, L"minivers"); 50 | 51 | 52 | DRIVER_INITIALIZE DriverEntry; 53 | NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT DriverObject, 54 | _In_ PUNICODE_STRING RegistryPath); 55 | 56 | static NTSTATUS process_irp(PFLT_CALLBACK_DATA Data, 57 | PCFLT_RELATED_OBJECTS FltObjects, 58 | PVOID* CompletionContext, 59 | BOOLEAN deferred_io); 60 | 61 | static BOOLEAN get_file_name_information(PFLT_CALLBACK_DATA data, 62 | PFLT_FILE_NAME_INFORMATION* name_info); 63 | 64 | static BOOLEAN find_extension(const UNICODE_STRING* ext); 65 | static BOOLEAN duplicate_file(PFLT_CALLBACK_DATA CallbackData, 66 | PFLT_INSTANCE instance); 67 | 68 | static void deferred_io_workitem(PFLT_DEFERRED_IO_WORKITEM FltWorkItem, 69 | PFLT_CALLBACK_DATA CallbackData, 70 | PVOID Context); 71 | 72 | #if LOG_IMAGE_FILENAME 73 | static BOOLEAN get_process_image_filename(PEPROCESS process, 74 | void* buf, 75 | size_t len); 76 | #endif /* LOG_IMAGE_FILENAME */ 77 | 78 | #ifdef ALLOC_PRAGMA 79 | #pragma alloc_text(INIT, DriverEntry) 80 | #pragma alloc_text(PAGE, InstanceSetup) 81 | #pragma alloc_text(PAGE, FilterUnload) 82 | #pragma alloc_text(PAGE, InstanceQueryTeardown) 83 | #endif /* ALLOC_PRAGMA */ 84 | 85 | 86 | NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT DriverObject, 87 | _In_ PUNICODE_STRING RegistryPath) 88 | { 89 | #if LOG_IMAGE_FILENAME 90 | UNICODE_STRING name; 91 | #endif 92 | 93 | NTSTATUS status; 94 | 95 | UNREFERENCED_PARAMETER(RegistryPath); 96 | 97 | #if LOG_IMAGE_FILENAME 98 | RtlInitUnicodeString(&name, L"ZwQueryInformationProcess"); 99 | 100 | /* Get a pointer to the function 'ZwQueryInformationProcess()'. */ 101 | fnQueryInformationProcess = (QueryInformationProcess) 102 | (ULONG_PTR) MmGetSystemRoutineAddress(&name); 103 | #endif /* LOG_IMAGE_FILENAME */ 104 | 105 | /* Register with the filter manager. */ 106 | status = FltRegisterFilter(DriverObject, 107 | &filter_registration, 108 | &driver_data.filter); 109 | 110 | if (NT_SUCCESS(status)) { 111 | /* Start filtering. */ 112 | status = FltStartFiltering(driver_data.filter); 113 | 114 | if (!NT_SUCCESS(status)) { 115 | FltUnregisterFilter(driver_data.filter); 116 | } 117 | } 118 | 119 | return status; 120 | } 121 | 122 | NTSTATUS InstanceSetup(_In_ PCFLT_RELATED_OBJECTS FltObjects, 123 | _In_ FLT_INSTANCE_SETUP_FLAGS Flags, 124 | _In_ DEVICE_TYPE VolumeDeviceType, 125 | _In_ FLT_FILESYSTEM_TYPE VolumeFilesystemType) 126 | { 127 | UNREFERENCED_PARAMETER(FltObjects); 128 | UNREFERENCED_PARAMETER(Flags); 129 | UNREFERENCED_PARAMETER(VolumeFilesystemType); 130 | 131 | PAGED_CODE(); 132 | 133 | return (VolumeDeviceType != FILE_DEVICE_CD_ROM_FILE_SYSTEM) ? 134 | STATUS_SUCCESS : 135 | STATUS_FLT_DO_NOT_ATTACH; 136 | } 137 | 138 | NTSTATUS FilterUnload(_In_ FLT_FILTER_UNLOAD_FLAGS Flags) 139 | { 140 | UNREFERENCED_PARAMETER(Flags); 141 | 142 | PAGED_CODE(); 143 | 144 | FltUnregisterFilter(driver_data.filter); 145 | 146 | return STATUS_SUCCESS; 147 | } 148 | 149 | NTSTATUS InstanceQueryTeardown(_In_ PCFLT_RELATED_OBJECTS FltObjects, 150 | _In_ FLT_INSTANCE_QUERY_TEARDOWN_FLAGS Flags) 151 | { 152 | UNREFERENCED_PARAMETER(FltObjects); 153 | UNREFERENCED_PARAMETER(Flags); 154 | 155 | PAGED_CODE(); 156 | 157 | return STATUS_SUCCESS; 158 | } 159 | 160 | FLT_PREOP_CALLBACK_STATUS 161 | PreOperationCallback( 162 | _Inout_ PFLT_CALLBACK_DATA Data, 163 | _In_ PCFLT_RELATED_OBJECTS FltObjects, 164 | _Flt_CompletionContext_Outptr_ PVOID* CompletionContext 165 | ) 166 | { 167 | /* IRP-based I/O operation? */ 168 | if (FLT_IS_IRP_OPERATION(Data)) { 169 | /* Open file? */ 170 | if (Data->Iopb->MajorFunction == IRP_MJ_CREATE) { 171 | /* Open file for writing/appending? */ 172 | if (Data->Iopb->Parameters.Create.SecurityContext->DesiredAccess & 173 | (FILE_WRITE_DATA | FILE_APPEND_DATA)) { 174 | return process_irp(Data, FltObjects, CompletionContext, DEFERRED_IO); 175 | } 176 | } else if (Data->Iopb->MajorFunction == IRP_MJ_SET_INFORMATION) { 177 | switch (Data->Iopb->Parameters.SetFileInformation.FileInformationClass) { 178 | case FileDispositionInformation: 179 | if (((FILE_DISPOSITION_INFORMATION*) 180 | Data->Iopb->Parameters.SetFileInformation.InfoBuffer 181 | )->DeleteFile) { 182 | return process_irp(Data, FltObjects, CompletionContext, FALSE); 183 | } 184 | 185 | break; 186 | case FileEndOfFileInformation: 187 | case FileRenameInformation: 188 | return process_irp(Data, FltObjects, CompletionContext, FALSE); 189 | } 190 | } 191 | } 192 | 193 | return FLT_PREOP_SUCCESS_NO_CALLBACK; 194 | } 195 | 196 | NTSTATUS process_irp(PFLT_CALLBACK_DATA Data, 197 | PCFLT_RELATED_OBJECTS FltObjects, 198 | PVOID* CompletionContext, 199 | BOOLEAN deferred_io) 200 | { 201 | PFLT_FILE_NAME_INFORMATION name_info; 202 | PFLT_DEFERRED_IO_WORKITEM work; 203 | 204 | #if LOG_IMAGE_FILENAME 205 | PEPROCESS process; 206 | ULONG pid; 207 | char buf[sizeof(UNICODE_STRING) + (sizeof(WCHAR) * EXE_MAX_LEN)]; 208 | PUNICODE_STRING exe; 209 | #endif // LOG_IMAGE_FILENAME 210 | 211 | /* Get name information. */ 212 | if (get_file_name_information(Data, &name_info)) { 213 | if (find_extension(&name_info->Extension)) { 214 | #if LOG_IMAGE_FILENAME 215 | if (fnQueryInformationProcess) { 216 | exe = (PUNICODE_STRING) buf; 217 | exe->Buffer = (WCHAR*) (buf + sizeof(UNICODE_STRING)); 218 | exe->Length = 0; 219 | exe->MaximumLength = EXE_MAX_LEN; 220 | 221 | /* Get process image filename. */ 222 | if (((pid = FltGetRequestorProcessId(Data)) != 0) && 223 | ((process = FltGetRequestorProcess(Data)) != NULL) && 224 | (get_process_image_filename(process, buf, sizeof(buf)))) { 225 | DbgPrint("[PID: %u, executable: '%wZ'] Filename: '%wZ', " 226 | "extension: '%wZ'.", 227 | pid, 228 | exe, 229 | &name_info->Name, 230 | &name_info->Extension); 231 | } else { 232 | DbgPrint("Filename: '%wZ', extension: '%wZ'.", 233 | &name_info->Name, 234 | &name_info->Extension); 235 | } 236 | } else { 237 | DbgPrint("Filename: '%wZ', extension: '%wZ'.", 238 | &name_info->Name, 239 | &name_info->Extension); 240 | } 241 | #else 242 | DbgPrint("Filename: '%wZ', extension: '%wZ'.", 243 | &name_info->Name, 244 | &name_info->Extension); 245 | #endif 246 | 247 | if (deferred_io) { 248 | if ((work = FltAllocateDeferredIoWorkItem()) != NULL) { 249 | if (NT_SUCCESS(FltQueueDeferredIoWorkItem(work, 250 | Data, 251 | deferred_io_workitem, 252 | DelayedWorkQueue, 253 | FltObjects->Instance))) { 254 | FltReleaseFileNameInformation(name_info); 255 | 256 | *CompletionContext = NULL; 257 | 258 | return FLT_PREOP_PENDING; 259 | } else { 260 | FltFreeDeferredIoWorkItem(work); 261 | } 262 | } 263 | } 264 | 265 | duplicate_file(Data, FltObjects->Instance); 266 | #if IMMUTABLE_BACKUP_FILES 267 | } else if (RtlEqualUnicodeString(&name_info->Extension, 268 | &MINIVERS_EXT, 269 | TRUE)) { 270 | DbgPrint("Filename: '%wZ', extension: '%wZ'.", 271 | &name_info->Name, 272 | &name_info->Extension); 273 | 274 | FltReleaseFileNameInformation(name_info); 275 | 276 | Data->IoStatus.Status = STATUS_ACCESS_DENIED; 277 | return FLT_PREOP_COMPLETE; 278 | #endif /* IMMUTABLE_BACKUP_FILES */ 279 | } 280 | 281 | FltReleaseFileNameInformation(name_info); 282 | } 283 | 284 | return FLT_PREOP_SUCCESS_NO_CALLBACK; 285 | } 286 | 287 | BOOLEAN get_file_name_information(PFLT_CALLBACK_DATA data, 288 | PFLT_FILE_NAME_INFORMATION* name_info) 289 | { 290 | /* Get name information. */ 291 | if (NT_SUCCESS(FltGetFileNameInformation( 292 | data, 293 | FLT_FILE_NAME_NORMALIZED | 294 | FLT_FILE_NAME_QUERY_ALWAYS_ALLOW_CACHE_LOOKUP, 295 | name_info 296 | ))) { 297 | /* Parse file name information. */ 298 | if (NT_SUCCESS(FltParseFileNameInformation(*name_info))) { 299 | return TRUE; 300 | } 301 | 302 | FltReleaseFileNameInformation(*name_info); 303 | #if OSVER(NTDDI_VERSION) > NTDDI_WIN2K 304 | } else { 305 | /* 306 | * We couldn't get the "normalized" name, try to get the "opened" 307 | * name. 308 | */ 309 | if (NT_SUCCESS(FltGetFileNameInformation(data, 310 | FLT_FILE_NAME_OPENED | 311 | FLT_FILE_NAME_QUERY_ALWAYS_ALLOW_CACHE_LOOKUP, 312 | name_info 313 | ))) { 314 | if (NT_SUCCESS(FltParseFileNameInformation(*name_info))) { 315 | return TRUE; 316 | } 317 | 318 | FltReleaseFileNameInformation(*name_info); 319 | } 320 | #endif /* OSVER(NTDDI_VERSION) > NTDDI_WIN2K */ 321 | } 322 | 323 | return FALSE; 324 | } 325 | 326 | BOOLEAN find_extension(const UNICODE_STRING* ext) 327 | { 328 | size_t i; 329 | 330 | for (i = 0; i < ARRAYSIZE(extensions); i++) { 331 | if (RtlEqualUnicodeString(ext, extensions[i], TRUE)) { 332 | return TRUE; 333 | } 334 | } 335 | 336 | return FALSE; 337 | } 338 | 339 | BOOLEAN duplicate_file(PFLT_CALLBACK_DATA CallbackData, PFLT_INSTANCE instance) 340 | { 341 | PFLT_FILE_NAME_INFORMATION name_info; 342 | UNICODE_STRING dest; 343 | LARGE_INTEGER system_time, local_time; 344 | TIME_FIELDS time; 345 | 346 | /* Get name information. */ 347 | if (get_file_name_information(CallbackData, &name_info)) { 348 | /* Compute size in bytes. 349 | * Suffix's format: .YYYYMMDD_hhmmss_mmm. 350 | */ 351 | dest.MaximumLength = name_info->Name.Length + 352 | 42 + 353 | MINIVERS_EXT.Length + 354 | sizeof(WCHAR); 355 | 356 | /* Allocate memory for the destination file name. */ 357 | if ((dest.Buffer = ExAllocatePoolWithTag(NonPagedPool, 358 | dest.MaximumLength, 359 | TAG)) != NULL) { 360 | dest.Length = 0; 361 | 362 | /* Get system time. */ 363 | KeQuerySystemTime(&system_time); 364 | 365 | /* Convert system time to local time. */ 366 | ExSystemTimeToLocalTime(&system_time, &local_time); 367 | 368 | RtlTimeToTimeFields(&local_time, &time); 369 | 370 | /* Compose name of the new file. */ 371 | if (NT_SUCCESS(RtlUnicodeStringPrintf( 372 | &dest, 373 | L"%wZ.%04u%02u%02u_%02u%02u%02u_%03u.%wZ", 374 | &name_info->Name, 375 | time.Year, 376 | time.Month, 377 | time.Day, 378 | time.Hour, 379 | time.Minute, 380 | time.Second, 381 | time.Milliseconds, 382 | &MINIVERS_EXT 383 | ))) { 384 | /* Copy file. */ 385 | if (copy_file(driver_data.filter, instance, &dest, &name_info->Name)) { 386 | ExFreePoolWithTag(dest.Buffer, TAG); 387 | FltReleaseFileNameInformation(name_info); 388 | 389 | return TRUE; 390 | } 391 | } 392 | 393 | ExFreePoolWithTag(dest.Buffer, TAG); 394 | } 395 | 396 | FltReleaseFileNameInformation(name_info); 397 | } 398 | 399 | return FALSE; 400 | } 401 | 402 | void deferred_io_workitem(PFLT_DEFERRED_IO_WORKITEM FltWorkItem, 403 | PFLT_CALLBACK_DATA CallbackData, 404 | PVOID Context) 405 | { 406 | duplicate_file(CallbackData, Context); 407 | 408 | FltFreeDeferredIoWorkItem(FltWorkItem); 409 | 410 | FltCompletePendedPreOperation(CallbackData, 411 | FLT_PREOP_SUCCESS_NO_CALLBACK, 412 | NULL); 413 | } 414 | 415 | #if LOG_IMAGE_FILENAME 416 | BOOLEAN get_process_image_filename(PEPROCESS process, void* buf, size_t len) 417 | { 418 | HANDLE hProcess; 419 | NTSTATUS status; 420 | 421 | PAGED_CODE(); 422 | 423 | /* Get process handle. */ 424 | if (NT_SUCCESS(ObOpenObjectByPointer(process, 425 | OBJ_KERNEL_HANDLE, 426 | NULL, 427 | 0, 428 | 0, 429 | KernelMode, 430 | &hProcess))) { 431 | /* Get process image filename. */ 432 | status = fnQueryInformationProcess(hProcess, 433 | ProcessImageFileName, 434 | buf, 435 | len, 436 | NULL); 437 | 438 | ZwClose(hProcess); 439 | 440 | return NT_SUCCESS(status) ? TRUE : FALSE; 441 | } 442 | 443 | return FALSE; 444 | } 445 | #endif /* LOG_IMAGE_FILENAME */ 446 | -------------------------------------------------------------------------------- /minivers/minivers.h: -------------------------------------------------------------------------------- 1 | #ifndef MINIVERS_H 2 | #define MINIVERS_H 3 | 4 | #include 5 | #include 6 | 7 | #pragma prefast(disable:__WARNING_ENCODE_MEMBER_FUNCTION_POINTER, "Not valid for kernel mode drivers") 8 | 9 | #define TAG 'reVM' 10 | 11 | 12 | /****************************************************************************** 13 | ****************************************************************************** 14 | ** ** 15 | ** Type definitions. ** 16 | ** ** 17 | ****************************************************************************** 18 | ******************************************************************************/ 19 | typedef struct { 20 | /* The filter that results from a call to FltRegisterFilter. */ 21 | PFLT_FILTER filter; 22 | } DRIVER_DATA; 23 | 24 | 25 | /****************************************************************************** 26 | ****************************************************************************** 27 | ** ** 28 | ** Global variables. ** 29 | ** ** 30 | ****************************************************************************** 31 | ******************************************************************************/ 32 | extern const FLT_REGISTRATION filter_registration; 33 | 34 | 35 | /****************************************************************************** 36 | ****************************************************************************** 37 | ** ** 38 | ** Function prototypes. ** 39 | ** ** 40 | ****************************************************************************** 41 | ******************************************************************************/ 42 | FLT_PREOP_CALLBACK_STATUS 43 | PreOperationCallback( 44 | _Inout_ PFLT_CALLBACK_DATA Data, 45 | _In_ PCFLT_RELATED_OBJECTS FltObjects, 46 | _Flt_CompletionContext_Outptr_ PVOID* CompletionContext 47 | ); 48 | 49 | NTSTATUS InstanceSetup(_In_ PCFLT_RELATED_OBJECTS FltObjects, 50 | _In_ FLT_INSTANCE_SETUP_FLAGS Flags, 51 | _In_ DEVICE_TYPE VolumeDeviceType, 52 | _In_ FLT_FILESYSTEM_TYPE VolumeFilesystemType); 53 | 54 | NTSTATUS FilterUnload(_In_ FLT_FILTER_UNLOAD_FLAGS Flags); 55 | 56 | NTSTATUS InstanceQueryTeardown(_In_ PCFLT_RELATED_OBJECTS FltObjects, 57 | _In_ FLT_INSTANCE_QUERY_TEARDOWN_FLAGS Flags); 58 | 59 | #endif /* MINIVERS_H */ 60 | -------------------------------------------------------------------------------- /minivers/minivers.inf: -------------------------------------------------------------------------------- 1 | ;;; 2 | ;;; minivers 3 | ;;; 4 | 5 | [Version] 6 | Signature = "$Windows NT$" 7 | Class = "ActivityMonitor" ;This is determined by the work this filter driver does 8 | ClassGuid = {b86dff51-a31e-4bac-b3cf-e8cfe75c9fc2} ;This value is determined by the Class 9 | Provider = %ManufacturerName% 10 | DriverVer = 05/28/2017,1.0.0.0 11 | CatalogFile = minivers.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 = "FSFilter Activity Monitor" 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 | minivers.sys = 1,, 73 | 74 | [SourceDisksNames] 75 | 1 = %DiskId1%,,, 76 | 77 | ;; 78 | ;; String Section 79 | ;; 80 | 81 | [Strings] 82 | ; TODO - Add your manufacturer 83 | ManufacturerName = "Template" 84 | ServiceDescription = "minivers Mini-Filter Driver" 85 | ServiceName = "minivers" 86 | DriverName = "minivers" 87 | DiskId1 = "minivers Device Installation Disk" 88 | 89 | ;Instances specific information. 90 | DefaultInstance = "minivers Instance" 91 | Instance1.Name = "minivers Instance" 92 | Instance1.Altitude = "385100" ; minispy.sys - Top 93 | Instance1.Flags = 0x0 ; Allow all attachments 94 | -------------------------------------------------------------------------------- /minivers/minivers.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 "minivers Filter Driver" 8 | #define VER_INTERNALNAME_STR "minivers.sys" 9 | 10 | #include "common.ver" 11 | -------------------------------------------------------------------------------- /minivers/minivers.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Win8.1 Debug 6 | Win32 7 | 8 | 9 | Win8.1 Release 10 | Win32 11 | 12 | 13 | Win8 Debug 14 | Win32 15 | 16 | 17 | Win8 Release 18 | Win32 19 | 20 | 21 | Win7 Debug 22 | Win32 23 | 24 | 25 | Win7 Release 26 | Win32 27 | 28 | 29 | Win8.1 Debug 30 | x64 31 | 32 | 33 | Win8.1 Release 34 | x64 35 | 36 | 37 | Win8 Debug 38 | x64 39 | 40 | 41 | Win8 Release 42 | x64 43 | 44 | 45 | Win7 Debug 46 | x64 47 | 48 | 49 | Win7 Release 50 | x64 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | {E337AC23-F84D-4E6D-81E9-729F64684A30} 62 | {f2f62967-0815-4fd7-9b86-6eedcac766eb} 63 | v4.5 64 | 11.0 65 | Win8.1 Debug 66 | Win32 67 | minivers 68 | 69 | 70 | 71 | WindowsV6.3 72 | true 73 | WindowsKernelModeDriver8.1 74 | Driver 75 | WDM 76 | 77 | 78 | WindowsV6.3 79 | false 80 | WindowsKernelModeDriver8.1 81 | Driver 82 | WDM 83 | 84 | 85 | Windows8 86 | true 87 | WindowsKernelModeDriver8.1 88 | Driver 89 | WDM 90 | 91 | 92 | Windows8 93 | false 94 | WindowsKernelModeDriver8.1 95 | Driver 96 | WDM 97 | 98 | 99 | Windows7 100 | true 101 | WindowsKernelModeDriver8.1 102 | Driver 103 | WDM 104 | 105 | 106 | Windows7 107 | false 108 | WindowsKernelModeDriver8.1 109 | Driver 110 | WDM 111 | 112 | 113 | WindowsV6.3 114 | true 115 | WindowsKernelModeDriver8.1 116 | Driver 117 | WDM 118 | 119 | 120 | WindowsV6.3 121 | false 122 | WindowsKernelModeDriver8.1 123 | Driver 124 | WDM 125 | 126 | 127 | Windows8 128 | true 129 | WindowsKernelModeDriver8.1 130 | Driver 131 | WDM 132 | 133 | 134 | Windows8 135 | false 136 | WindowsKernelModeDriver8.1 137 | Driver 138 | WDM 139 | 140 | 141 | Windows7 142 | true 143 | WindowsKernelModeDriver8.1 144 | Driver 145 | WDM 146 | 147 | 148 | Windows7 149 | false 150 | WindowsKernelModeDriver8.1 151 | Driver 152 | WDM 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | DbgengKernelDebugger 164 | 165 | 166 | DbgengKernelDebugger 167 | 168 | 169 | DbgengKernelDebugger 170 | 171 | 172 | DbgengKernelDebugger 173 | 174 | 175 | DbgengKernelDebugger 176 | 177 | 178 | DbgengKernelDebugger 179 | 180 | 181 | DbgengKernelDebugger 182 | 183 | 184 | DbgengKernelDebugger 185 | 186 | 187 | DbgengKernelDebugger 188 | 189 | 190 | DbgengKernelDebugger 191 | 192 | 193 | DbgengKernelDebugger 194 | 195 | 196 | DbgengKernelDebugger 197 | 198 | 199 | 200 | $(DDK_LIB_PATH)\fltmgr.lib;%(AdditionalDependencies) 201 | 202 | 203 | 204 | 205 | $(DDK_LIB_PATH)\fltmgr.lib;%(AdditionalDependencies) 206 | 207 | 208 | 209 | 210 | $(DDK_LIB_PATH)\fltmgr.lib;%(AdditionalDependencies) 211 | 212 | 213 | 214 | 215 | $(DDK_LIB_PATH)\fltmgr.lib;%(AdditionalDependencies) 216 | 217 | 218 | 219 | 220 | $(DDK_LIB_PATH)\fltmgr.lib;%(AdditionalDependencies) 221 | 222 | 223 | 224 | 225 | $(DDK_LIB_PATH)\fltmgr.lib;%(AdditionalDependencies) 226 | 227 | 228 | 229 | 230 | $(DDK_LIB_PATH)\fltmgr.lib;%(AdditionalDependencies) 231 | 232 | 233 | 234 | 235 | $(DDK_LIB_PATH)\fltmgr.lib;%(AdditionalDependencies) 236 | 237 | 238 | 239 | 240 | $(DDK_LIB_PATH)\fltmgr.lib;%(AdditionalDependencies) 241 | 242 | 243 | 244 | 245 | $(DDK_LIB_PATH)\fltmgr.lib;%(AdditionalDependencies) 246 | 247 | 248 | 249 | 250 | $(DDK_LIB_PATH)\fltmgr.lib;%(AdditionalDependencies) 251 | 252 | 253 | 254 | 255 | $(DDK_LIB_PATH)\fltmgr.lib;%(AdditionalDependencies) 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | -------------------------------------------------------------------------------- /minivers/minivers.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {8E41214B-6785-4CFE-B992-037D68949A14} 18 | inf;inv;inx;mof;mc; 19 | 20 | 21 | 22 | 23 | Driver Files 24 | 25 | 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | Source Files 35 | 36 | 37 | 38 | 39 | Resource Files 40 | 41 | 42 | 43 | 44 | Header Files 45 | 46 | 47 | Header Files 48 | 49 | 50 | --------------------------------------------------------------------------------