├── FileDelete ├── FileDelete │ ├── file_delete.h │ ├── common.h │ ├── FileDelete.vcxproj.user │ ├── device_handlers.h │ ├── ProcessReference.h │ ├── consts.h │ ├── FileReference.h │ ├── FileDelete.inf │ ├── ProcessReference.cpp │ ├── handle.cpp │ ├── handle.h │ ├── FileReference.cpp │ ├── device_handlers.cpp │ ├── main.cpp │ ├── FileDelete.vcxproj.filters │ ├── file_delete.cpp │ └── FileDelete.vcxproj ├── FileDeleteCom │ ├── FileDeleteCom.vcxproj.user │ ├── FileDeleteCom.cpp │ ├── FileDeleteCom.vcxproj.filters │ └── FileDeleteCom.vcxproj └── FileDelete.sln ├── .gitignore └── README.md /FileDelete/FileDelete/file_delete.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "common.h" 5 | 6 | NTSTATUS delete_file(const FileDeleteArgs& args); -------------------------------------------------------------------------------- /FileDelete/FileDelete/common.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct FileDeleteArgs { 4 | wchar_t file_path[256]; 5 | }; 6 | 7 | #define FILE_DELETE_IOCTL CTL_CODE(FILE_DEVICE_UNKNOWN, 0x1337, METHOD_BUFFERED, FILE_WRITE_DATA) -------------------------------------------------------------------------------- /FileDelete/FileDelete/FileDelete.vcxproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /FileDelete/FileDeleteCom/FileDeleteCom.vcxproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /FileDelete/FileDelete/device_handlers.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | 5 | NTSTATUS device_create_close(PDEVICE_OBJECT device_object, PIRP irp); 6 | 7 | NTSTATUS device_ioctl(PDEVICE_OBJECT device_object, PIRP irp); -------------------------------------------------------------------------------- /FileDelete/FileDelete/ProcessReference.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "consts.h" 6 | 7 | class ProcessReference { 8 | public: 9 | ProcessReference(); 10 | ~ProcessReference(); 11 | 12 | NTSTATUS init(size_t pid, bool attach); 13 | 14 | DELETE_DEFAULT_CTORS(ProcessReference); 15 | private: 16 | PEPROCESS m_process; 17 | bool m_attach{}; 18 | KAPC_STATE* m_apc_state; 19 | }; 20 | 21 | -------------------------------------------------------------------------------- /FileDelete/FileDelete/consts.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define NT_DEVICE_NAME L"\\Device\\FileDelete" 4 | #define DOS_DEVICE_NAME L"\\DosDevices\\FileDelete" 5 | 6 | #define CHECK(ntstatus) if (!NT_SUCCESS(ntstatus)) { return ntstatus;} 7 | 8 | #define DELETE_DEFAULT_CTORS(class_name) \ 9 | class_name(class_name const&) = delete; \ 10 | class_name& operator =(class_name const&) = delete; \ 11 | class_name(class_name&&) = delete; \ 12 | class_name& operator=(class_name&&) = delete \ -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | 34 | .vs/ 35 | Debug/ 36 | Release/ 37 | x64/ 38 | script.txt 39 | *.ps1 -------------------------------------------------------------------------------- /FileDelete/FileDelete/FileReference.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "consts.h" 6 | 7 | class FileReference { 8 | public: 9 | FileReference(); 10 | ~FileReference(); 11 | 12 | NTSTATUS init(const wchar_t* file_path, ULONG desired_access, ULONG share_access); 13 | 14 | PFILE_OBJECT get_object() const; 15 | 16 | HANDLE get_handle() const; 17 | 18 | DELETE_DEFAULT_CTORS(FileReference); 19 | private: 20 | PFILE_OBJECT m_file_object; 21 | HANDLE m_file_handle; 22 | }; -------------------------------------------------------------------------------- /FileDelete/FileDelete/FileDelete.inf: -------------------------------------------------------------------------------- 1 | ; 2 | ; FileDelete.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=FileDelete.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="FileDelete Source Disk" 33 | -------------------------------------------------------------------------------- /FileDelete/FileDeleteCom/FileDeleteCom.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "../FileDelete/common.h" 5 | 6 | int wmain(int, wchar_t** argv) { 7 | std::cout << "Hello World!\n"; 8 | HANDLE driver = CreateFileA("\\\\.\\FileDelete", GENERIC_ALL, 0, 9 | nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); 10 | if (INVALID_HANDLE_VALUE == driver) { 11 | return 1; 12 | } 13 | FileDeleteArgs args = {}; 14 | memcpy(args.file_path, argv[1], wcslen(argv[1]) * sizeof(wchar_t)); 15 | 16 | DeviceIoControl(driver, FILE_DELETE_IOCTL, &args, sizeof(FileDeleteArgs), 17 | nullptr, 0, nullptr, nullptr); 18 | 19 | CloseHandle(driver); 20 | return 0; 21 | } -------------------------------------------------------------------------------- /FileDelete/FileDelete/ProcessReference.cpp: -------------------------------------------------------------------------------- 1 | #include "ProcessReference.h" 2 | 3 | ProcessReference::ProcessReference() 4 | : m_process(nullptr) { 5 | } 6 | 7 | ProcessReference::~ProcessReference() { 8 | if (nullptr != m_process) { 9 | ObDereferenceObject(m_process); 10 | if (m_attach) { 11 | KeUnstackDetachProcess(m_apc_state); 12 | ExFreePool(m_apc_state); 13 | } 14 | } 15 | 16 | } 17 | 18 | NTSTATUS ProcessReference::init(size_t pid, bool attach) { 19 | CHECK(PsLookupProcessByProcessId(reinterpret_cast(pid), &m_process)); 20 | m_attach = attach; 21 | if (attach) { 22 | m_apc_state = (KAPC_STATE*)ExAllocatePool(NonPagedPool, sizeof(KAPC_STATE)); 23 | KeStackAttachProcess(m_process, m_apc_state); 24 | } 25 | return STATUS_SUCCESS; 26 | } 27 | -------------------------------------------------------------------------------- /FileDelete/FileDelete/handle.cpp: -------------------------------------------------------------------------------- 1 | #include "handle.h" 2 | 3 | extern "C" NTSTATUS NTAPI ZwQuerySystemInformation(IN size_t SystemInformationClass, 4 | OUT PVOID SystemInformation, 5 | IN ULONG SystemInformationLength, 6 | OUT PULONG ReturnLength OPTIONAL); 7 | 8 | SYSTEM_HANDLE_INFORMATION* get_all_handles() { 9 | size_t handles_allocation_size = 0; 10 | PVOID handles_pool = nullptr; 11 | 12 | while (true) { 13 | handles_allocation_size += 0x10000; 14 | handles_pool = ExAllocatePool(PagedPool, handles_allocation_size); 15 | 16 | auto status = ZwQuerySystemInformation(SystemHandleInformation, handles_pool, (ULONG)handles_allocation_size, nullptr); 17 | if (status == STATUS_INFO_LENGTH_MISMATCH) { 18 | ExFreePool(handles_pool); 19 | } 20 | else { 21 | break; 22 | } 23 | } 24 | return (SYSTEM_HANDLE_INFORMATION*)handles_pool; 25 | } 26 | -------------------------------------------------------------------------------- /FileDelete/FileDelete/handle.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #define SystemHandleInformation 0x10 6 | 7 | using fNtQuerySystemInformation = NTSTATUS(NTAPI*)( 8 | ULONG SystemInformationClass, 9 | PVOID SystemInformation, 10 | ULONG SystemInformationLength, 11 | PULONG ReturnLength 12 | ); 13 | 14 | // handle information 15 | typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO 16 | { 17 | USHORT UniqueProcessId; 18 | USHORT CreatorBackTraceIndex; 19 | UCHAR ObjectTypeIndex; 20 | UCHAR HandleAttributes; 21 | USHORT HandleValue; 22 | PVOID Object; 23 | ULONG GrantedAccess; 24 | } SYSTEM_HANDLE_TABLE_ENTRY_INFO, * PSYSTEM_HANDLE_TABLE_ENTRY_INFO; 25 | 26 | // handle table information 27 | typedef struct _SYSTEM_HANDLE_INFORMATION 28 | { 29 | ULONG NumberOfHandles; 30 | SYSTEM_HANDLE_TABLE_ENTRY_INFO Handles[1]; 31 | } SYSTEM_HANDLE_INFORMATION, * PSYSTEM_HANDLE_INFORMATION; 32 | 33 | 34 | SYSTEM_HANDLE_INFORMATION* get_all_handles(); -------------------------------------------------------------------------------- /FileDelete/FileDeleteCom/FileDeleteCom.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /FileDelete/FileDelete/FileReference.cpp: -------------------------------------------------------------------------------- 1 | #include "FileReference.h" 2 | 3 | FileReference::FileReference() 4 | : m_file_object(nullptr), m_file_handle(nullptr){ 5 | } 6 | 7 | FileReference::~FileReference() { 8 | if (nullptr != m_file_object) { 9 | ObDereferenceObject(m_file_object); 10 | } 11 | 12 | if (nullptr != m_file_handle) { 13 | ZwClose(m_file_handle); 14 | } 15 | } 16 | 17 | NTSTATUS FileReference::init(const wchar_t* file_path, ULONG desired_access, ULONG share_access) { 18 | OBJECT_ATTRIBUTES object_attributes; 19 | UNICODE_STRING file_path_unicode_string; 20 | RtlInitUnicodeString(&file_path_unicode_string, file_path); 21 | InitializeObjectAttributes(&object_attributes, &file_path_unicode_string, OBJ_KERNEL_HANDLE, nullptr, nullptr); 22 | IO_STATUS_BLOCK io_status_block; 23 | CHECK(ZwCreateFile(&m_file_handle, desired_access, &object_attributes, &io_status_block, nullptr, FILE_ATTRIBUTE_NORMAL, 24 | share_access, FILE_OPEN, 0, nullptr, 0)); 25 | auto status = ObReferenceObjectByHandle(m_file_handle, desired_access, *IoFileObjectType, KernelMode, (PVOID*)&m_file_object, nullptr); 26 | return status; 27 | } 28 | 29 | PFILE_OBJECT FileReference::get_object() const { 30 | return m_file_object; 31 | } 32 | 33 | HANDLE FileReference::get_handle() const { 34 | return m_file_handle; 35 | } 36 | -------------------------------------------------------------------------------- /FileDelete/FileDelete/device_handlers.cpp: -------------------------------------------------------------------------------- 1 | #include "device_handlers.h" 2 | 3 | #include "common.h" 4 | #include "file_delete.h" 5 | 6 | NTSTATUS device_create_close(PDEVICE_OBJECT device_object, PIRP irp) { 7 | UNREFERENCED_PARAMETER(device_object); 8 | irp->IoStatus.Status = STATUS_SUCCESS; 9 | irp->IoStatus.Information = 0; 10 | 11 | IoCompleteRequest(irp, IO_NO_INCREMENT); 12 | 13 | return STATUS_SUCCESS; 14 | } 15 | 16 | NTSTATUS device_ioctl(PDEVICE_OBJECT device_object, PIRP irp) { 17 | UNREFERENCED_PARAMETER(device_object); 18 | 19 | NTSTATUS nt_status; 20 | PIO_STACK_LOCATION irp_stack_location = IoGetCurrentIrpStackLocation(irp); 21 | size_t input_buffer_length = irp_stack_location->Parameters.DeviceIoControl.InputBufferLength; 22 | 23 | switch (irp_stack_location->Parameters.DeviceIoControl.IoControlCode) { 24 | case FILE_DELETE_IOCTL: 25 | { 26 | if (input_buffer_length != sizeof FileDeleteArgs) { 27 | nt_status = STATUS_INVALID_PARAMETER; 28 | break; 29 | } 30 | auto args = static_cast(irp->AssociatedIrp.SystemBuffer); 31 | nt_status = delete_file(*args); 32 | } 33 | break; 34 | default: 35 | { 36 | nt_status = STATUS_INVALID_DEVICE_REQUEST; 37 | } 38 | break; 39 | } 40 | 41 | irp->IoStatus.Status = nt_status; 42 | IoCompleteRequest(irp, IO_NO_INCREMENT); 43 | return nt_status; 44 | } 45 | -------------------------------------------------------------------------------- /FileDelete/FileDelete/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "device_handlers.h" 4 | #include "consts.h" 5 | 6 | void driver_unload(PDRIVER_OBJECT driver_object) { 7 | UNICODE_STRING win32_name; 8 | RtlInitUnicodeString(&win32_name, DOS_DEVICE_NAME); 9 | IoDeleteSymbolicLink(&win32_name); 10 | if (nullptr != driver_object->DeviceObject) { 11 | IoDeleteDevice(driver_object->DeviceObject); 12 | } 13 | } 14 | 15 | extern "C" NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) { 16 | UNREFERENCED_PARAMETER(RegistryPath); 17 | 18 | DbgPrint("Hello from driver entry\n"); 19 | 20 | UNICODE_STRING nt_name; 21 | UNICODE_STRING win32_name; 22 | PDEVICE_OBJECT device_object = nullptr; 23 | 24 | RtlInitUnicodeString(&nt_name, NT_DEVICE_NAME); 25 | NTSTATUS nt_status = IoCreateDevice(DriverObject, 0, &nt_name, 26 | FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, 27 | TRUE, &device_object); 28 | 29 | if (!NT_SUCCESS(nt_status)) { 30 | DbgPrint("Couldn't create the device object\n"); 31 | return nt_status; 32 | } 33 | 34 | DriverObject->MajorFunction[IRP_MJ_CREATE] = device_create_close; 35 | DriverObject->MajorFunction[IRP_MJ_CLOSE] = device_create_close; 36 | DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = device_ioctl; 37 | DriverObject->DriverUnload = driver_unload; 38 | 39 | RtlInitUnicodeString(&win32_name, DOS_DEVICE_NAME); 40 | 41 | nt_status = IoCreateSymbolicLink(&win32_name, &nt_name); 42 | if (!NT_SUCCESS(nt_status)) { 43 | DbgPrint("Couldn't create symbolic link\n"); 44 | IoDeleteDevice(device_object); 45 | } 46 | 47 | return nt_status; 48 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # windows-kernel-file-delete 2 | 3 | ## TL;DR 4 | Force a file delete using a windows kernel driver 5 | 6 | Tested on Windows x64 1909 7 | 8 | ## How its works 9 | The deletion process is divided into several stages: 10 | 11 | 1. Close all the file handles 12 | * Get all the handles in the system (ZwQuerySystemInformation and SystemHandleInformation) 13 | * Check every handle if the handle is associated to IoFileObjectType (ObGetObjectType) 14 | * Compare the handle file name to target file name (IoQueryFileDosDeviceName) 15 | * If its the target file We attach to target process (KeStackAttachProcess) 16 | * Close the handle (NtClose) 17 | * Detach from target process (KeUnstackDetachProcess) 18 | 2. Get a reference to the file (ZwCreateFile and ObReferenceObjectByHandle) 19 | 3. Special treatment for executables, set the FileObject SectionObjectPointer->ImageSectionObject, SectionObjectPointer->DataSectionObject and SectionObjectPointer->SharedCacheMap to null in order to mark that the file is not mapped 20 | 4. Send IRP to the file system driver which marks the file for deletion 21 | * Get the file system device object (IoGetBaseFileSystemDeviceObject) 22 | * Allocate IRP and fill it with IRP_MJ_SET_INFORMATION and FILE_DISPOSITION_INFORMATION (IoAllocateIrp, KeInitializeEvent and IoSetCompletionRoutine) 23 | * Send the IRP to the file system device object (IoCallDriver and KeWaitForSingleObject) 24 | 5. Restore SectionObjectPointer->ImageSectionObject, SectionObjectPointer->DataSectionObject and SectionObjectPointer->SharedCacheMap fields 25 | 6. Close the file reference in order to delete it (ZwClose and ObDereferenceObject) 26 | 27 | ## Usage 28 | 29 | sc create FileDelete binPath= {driver_path} type= kernel 30 | 31 | sc start FileDelete 32 | 33 | FileDeleteCom.exe {file_path} 34 | 35 | DONE!!! 36 | -------------------------------------------------------------------------------- /FileDelete/FileDelete/FileDelete.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 | Source Files 38 | 39 | 40 | Source Files 41 | 42 | 43 | Source Files 44 | 45 | 46 | 47 | 48 | Header Files 49 | 50 | 51 | Header Files 52 | 53 | 54 | Header Files 55 | 56 | 57 | Header Files 58 | 59 | 60 | Header Files 61 | 62 | 63 | Header Files 64 | 65 | 66 | Header Files 67 | 68 | 69 | -------------------------------------------------------------------------------- /FileDelete/FileDelete.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30907.101 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FileDelete", "FileDelete\FileDelete.vcxproj", "{DD29F5EE-2A5A-4790-9C77-043EF43990BA}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FileDeleteCom", "FileDeleteCom\FileDeleteCom.vcxproj", "{B9FD992D-C853-434B-97F3-CDA5DA0D3E56}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|ARM = Debug|ARM 13 | Debug|ARM64 = Debug|ARM64 14 | Debug|x64 = Debug|x64 15 | Debug|x86 = Debug|x86 16 | Release|ARM = Release|ARM 17 | Release|ARM64 = Release|ARM64 18 | Release|x64 = Release|x64 19 | Release|x86 = Release|x86 20 | EndGlobalSection 21 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 22 | {DD29F5EE-2A5A-4790-9C77-043EF43990BA}.Debug|ARM.ActiveCfg = Debug|ARM 23 | {DD29F5EE-2A5A-4790-9C77-043EF43990BA}.Debug|ARM.Build.0 = Debug|ARM 24 | {DD29F5EE-2A5A-4790-9C77-043EF43990BA}.Debug|ARM.Deploy.0 = Debug|ARM 25 | {DD29F5EE-2A5A-4790-9C77-043EF43990BA}.Debug|ARM64.ActiveCfg = Debug|ARM64 26 | {DD29F5EE-2A5A-4790-9C77-043EF43990BA}.Debug|ARM64.Build.0 = Debug|ARM64 27 | {DD29F5EE-2A5A-4790-9C77-043EF43990BA}.Debug|ARM64.Deploy.0 = Debug|ARM64 28 | {DD29F5EE-2A5A-4790-9C77-043EF43990BA}.Debug|x64.ActiveCfg = Debug|x64 29 | {DD29F5EE-2A5A-4790-9C77-043EF43990BA}.Debug|x64.Build.0 = Debug|x64 30 | {DD29F5EE-2A5A-4790-9C77-043EF43990BA}.Debug|x64.Deploy.0 = Debug|x64 31 | {DD29F5EE-2A5A-4790-9C77-043EF43990BA}.Debug|x86.ActiveCfg = Debug|Win32 32 | {DD29F5EE-2A5A-4790-9C77-043EF43990BA}.Debug|x86.Build.0 = Debug|Win32 33 | {DD29F5EE-2A5A-4790-9C77-043EF43990BA}.Debug|x86.Deploy.0 = Debug|Win32 34 | {DD29F5EE-2A5A-4790-9C77-043EF43990BA}.Release|ARM.ActiveCfg = Release|ARM 35 | {DD29F5EE-2A5A-4790-9C77-043EF43990BA}.Release|ARM.Build.0 = Release|ARM 36 | {DD29F5EE-2A5A-4790-9C77-043EF43990BA}.Release|ARM.Deploy.0 = Release|ARM 37 | {DD29F5EE-2A5A-4790-9C77-043EF43990BA}.Release|ARM64.ActiveCfg = Release|ARM64 38 | {DD29F5EE-2A5A-4790-9C77-043EF43990BA}.Release|ARM64.Build.0 = Release|ARM64 39 | {DD29F5EE-2A5A-4790-9C77-043EF43990BA}.Release|ARM64.Deploy.0 = Release|ARM64 40 | {DD29F5EE-2A5A-4790-9C77-043EF43990BA}.Release|x64.ActiveCfg = Release|x64 41 | {DD29F5EE-2A5A-4790-9C77-043EF43990BA}.Release|x64.Build.0 = Release|x64 42 | {DD29F5EE-2A5A-4790-9C77-043EF43990BA}.Release|x64.Deploy.0 = Release|x64 43 | {DD29F5EE-2A5A-4790-9C77-043EF43990BA}.Release|x86.ActiveCfg = Release|Win32 44 | {DD29F5EE-2A5A-4790-9C77-043EF43990BA}.Release|x86.Build.0 = Release|Win32 45 | {DD29F5EE-2A5A-4790-9C77-043EF43990BA}.Release|x86.Deploy.0 = Release|Win32 46 | {B9FD992D-C853-434B-97F3-CDA5DA0D3E56}.Debug|ARM.ActiveCfg = Debug|Win32 47 | {B9FD992D-C853-434B-97F3-CDA5DA0D3E56}.Debug|ARM64.ActiveCfg = Debug|Win32 48 | {B9FD992D-C853-434B-97F3-CDA5DA0D3E56}.Debug|x64.ActiveCfg = Debug|x64 49 | {B9FD992D-C853-434B-97F3-CDA5DA0D3E56}.Debug|x64.Build.0 = Debug|x64 50 | {B9FD992D-C853-434B-97F3-CDA5DA0D3E56}.Debug|x86.ActiveCfg = Debug|Win32 51 | {B9FD992D-C853-434B-97F3-CDA5DA0D3E56}.Debug|x86.Build.0 = Debug|Win32 52 | {B9FD992D-C853-434B-97F3-CDA5DA0D3E56}.Release|ARM.ActiveCfg = Release|Win32 53 | {B9FD992D-C853-434B-97F3-CDA5DA0D3E56}.Release|ARM64.ActiveCfg = Release|Win32 54 | {B9FD992D-C853-434B-97F3-CDA5DA0D3E56}.Release|x64.ActiveCfg = Release|x64 55 | {B9FD992D-C853-434B-97F3-CDA5DA0D3E56}.Release|x64.Build.0 = Release|x64 56 | {B9FD992D-C853-434B-97F3-CDA5DA0D3E56}.Release|x86.ActiveCfg = Release|Win32 57 | {B9FD992D-C853-434B-97F3-CDA5DA0D3E56}.Release|x86.Build.0 = Release|Win32 58 | EndGlobalSection 59 | GlobalSection(SolutionProperties) = preSolution 60 | HideSolutionNode = FALSE 61 | EndGlobalSection 62 | GlobalSection(ExtensibilityGlobals) = postSolution 63 | SolutionGuid = {3E2C5BBA-8F24-43CB-9DF3-809804EE1213} 64 | EndGlobalSection 65 | EndGlobal 66 | -------------------------------------------------------------------------------- /FileDelete/FileDelete/file_delete.cpp: -------------------------------------------------------------------------------- 1 | #include "file_delete.h" 2 | 3 | 4 | #include "common.h" 5 | #include "FileReference.h" 6 | #include "handle.h" 7 | #include "ProcessReference.h" 8 | 9 | extern "C" POBJECT_TYPE NTAPI ObGetObjectType(_In_ PVOID Object); 10 | 11 | NTSTATUS close_all_file_handles(const wchar_t* file_path) { 12 | UNREFERENCED_PARAMETER(file_path); 13 | PSYSTEM_HANDLE_INFORMATION all_system_handles = get_all_handles(); 14 | for (size_t i = 0; i < all_system_handles->NumberOfHandles; i++) { 15 | SYSTEM_HANDLE_TABLE_ENTRY_INFO handle_info = all_system_handles->Handles[i]; 16 | if (*IoFileObjectType == ObGetObjectType(handle_info.Object)) { 17 | POBJECT_NAME_INFORMATION object_name_information; 18 | auto status = IoQueryFileDosDeviceName((PFILE_OBJECT)handle_info.Object, &object_name_information); 19 | if (!NT_SUCCESS(status)) { 20 | continue; 21 | } 22 | if (0 == wcscmp(file_path, object_name_information->Name.Buffer)) { 23 | ProcessReference process; 24 | if (!NT_SUCCESS(process.init(handle_info.UniqueProcessId, true))) { 25 | continue; 26 | } 27 | NtClose((HANDLE)handle_info.HandleValue); 28 | } 29 | ExFreePool(object_name_information); 30 | } 31 | } 32 | ExFreePool(all_system_handles); 33 | return STATUS_SUCCESS; 34 | } 35 | 36 | 37 | NTSTATUS io_complete(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context) { 38 | UNREFERENCED_PARAMETER(DeviceObject); 39 | UNREFERENCED_PARAMETER(Context); 40 | Irp->UserIosb->Status = Irp->IoStatus.Status; 41 | Irp->UserIosb->Information = Irp->IoStatus.Information; 42 | 43 | KeSetEvent(Irp->UserEvent, IO_NO_INCREMENT, false); 44 | IoFreeIrp(Irp); 45 | 46 | return STATUS_MORE_PROCESSING_REQUIRED; 47 | } 48 | 49 | NTSTATUS send_delete_file_irp(PFILE_OBJECT file_object) { 50 | KEVENT event; 51 | PDEVICE_OBJECT device_object = IoGetBaseFileSystemDeviceObject(file_object); 52 | 53 | PIRP irp = IoAllocateIrp(device_object->StackSize, false); 54 | 55 | // Set the complete routine that will free the IRP and signal the event 56 | KeInitializeEvent(&event, SynchronizationEvent, false); 57 | IoSetCompletionRoutine( 58 | irp, 59 | io_complete, 60 | &event, 61 | true, 62 | true, 63 | true); 64 | 65 | FILE_DISPOSITION_INFORMATION file_disposition; 66 | file_disposition.DeleteFile = true; 67 | 68 | IO_STATUS_BLOCK io_status_block; 69 | 70 | irp->AssociatedIrp.SystemBuffer = &file_disposition; 71 | irp->UserEvent = &event; 72 | irp->UserIosb = &io_status_block; 73 | irp->Tail.Overlay.OriginalFileObject = file_object; 74 | irp->Tail.Overlay.Thread = (PETHREAD)KeGetCurrentThread(); 75 | irp->RequestorMode = KernelMode; 76 | 77 | IO_STACK_LOCATION* stack_location = IoGetNextIrpStackLocation(irp); 78 | stack_location->MajorFunction = IRP_MJ_SET_INFORMATION; 79 | stack_location->DeviceObject = device_object; 80 | stack_location->FileObject = file_object; 81 | stack_location->Parameters.SetFile.Length = sizeof(FILE_DISPOSITION_INFORMATION); 82 | stack_location->Parameters.SetFile.FileInformationClass = FileDispositionInformation; 83 | stack_location->Parameters.SetFile.FileObject = file_object; 84 | 85 | IoCallDriver(device_object, irp); 86 | KeWaitForSingleObject(&event, Executive, KernelMode, true, nullptr); 87 | 88 | return STATUS_SUCCESS; 89 | } 90 | 91 | NTSTATUS delete_file(const FileDeleteArgs& args) { 92 | CHECK(close_all_file_handles(args.file_path)); 93 | 94 | wchar_t full_file_path[256] = {}; 95 | RtlCopyMemory(full_file_path, L"\\??\\", 8); 96 | RtlCopyMemory(full_file_path + 4, &args.file_path, wcslen(args.file_path) * sizeof(wchar_t)); 97 | 98 | FileReference file_reference; 99 | CHECK(file_reference.init(full_file_path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE)); 100 | file_reference.get_object()->DeleteAccess = true; 101 | 102 | auto section_object = file_reference.get_object()->SectionObjectPointer; 103 | PVOID image_section_object = nullptr; 104 | PVOID data_section_object = nullptr; 105 | PVOID shared_cache_map = nullptr; 106 | 107 | if (nullptr != section_object) { 108 | image_section_object = file_reference.get_object()->SectionObjectPointer->ImageSectionObject; 109 | data_section_object = file_reference.get_object()->SectionObjectPointer->DataSectionObject; 110 | shared_cache_map = file_reference.get_object()->SectionObjectPointer->SharedCacheMap; 111 | } 112 | 113 | auto status = send_delete_file_irp(file_reference.get_object()); 114 | 115 | if (nullptr != section_object) { 116 | file_reference.get_object()->SectionObjectPointer->ImageSectionObject = image_section_object; 117 | file_reference.get_object()->SectionObjectPointer->DataSectionObject = data_section_object; 118 | file_reference.get_object()->SectionObjectPointer->SharedCacheMap = shared_cache_map; 119 | } 120 | 121 | return status; 122 | } 123 | -------------------------------------------------------------------------------- /FileDelete/FileDeleteCom/FileDeleteCom.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 | Win32Proj 24 | {b9fd992d-c853-434b-97f3-cda5da0d3e56} 25 | FileDeleteCom 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 | false 78 | 79 | 80 | true 81 | 82 | 83 | false 84 | 85 | 86 | 87 | Level3 88 | true 89 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 90 | true 91 | 92 | 93 | Console 94 | true 95 | 96 | 97 | 98 | 99 | Level3 100 | true 101 | true 102 | true 103 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 104 | true 105 | 106 | 107 | Console 108 | true 109 | true 110 | true 111 | 112 | 113 | 114 | 115 | Level3 116 | true 117 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 118 | true 119 | MultiThreadedDebug 120 | 121 | 122 | Console 123 | true 124 | 125 | 126 | 127 | 128 | Level3 129 | true 130 | true 131 | true 132 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 133 | true 134 | MultiThreaded 135 | 136 | 137 | Console 138 | true 139 | true 140 | true 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | -------------------------------------------------------------------------------- /FileDelete/FileDelete/FileDelete.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 | {DD29F5EE-2A5A-4790-9C77-043EF43990BA} 39 | {dd38f7fc-d7bd-488b-9242-7d8754cde80d} 40 | v4.5 41 | 12.0 42 | Debug 43 | Win32 44 | FileDelete 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 | true 120 | 121 | 122 | DbgengKernelDebugger 123 | true 124 | 125 | 126 | DbgengKernelDebugger 127 | 128 | 129 | DbgengKernelDebugger 130 | 131 | 132 | DbgengKernelDebugger 133 | 134 | 135 | DbgengKernelDebugger 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | --------------------------------------------------------------------------------