首页
社区
课程
招聘
[转帖][分享]windows驱动内核 IRP 强制删除文件
发表于: 2022-8-9 00:59 8244

[转帖][分享]windows驱动内核 IRP 强制删除文件

2022-8-9 00:59
8244

关于浮躁 急功近利

引用
内核级驱动对抗Hook ZwSetInformationFile反删除技术
强制删除文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
NTSTATUS DriverEntry( 
    IN OUT PDRIVER_OBJECT   DriverObject, 
    IN PUNICODE_STRING      RegistryPath 
    
    // 其他初始化代码 
    // …… 
 
    DbgPrint ( "Delete File %s", ForceDeleteFile(L"//DosDevices//C://test.exe") ? "Success!" : "Failed!" ) ; 
    return STATUS_SUCCESS; 
 
NTSTATUS FD_SetFileCompletion( 
                       IN PDEVICE_OBJECT DeviceObject, 
                       IN PIRP Irp, 
                       IN PVOID Context 
                       
    Irp->UserIosb->Status     = Irp->IoStatus.Status; 
    Irp->UserIosb->Information    = Irp->IoStatus.Information; 
 
    KeSetEvent ( Irp->UserEvent, IO_NO_INCREMENT, FALSE ) ; 
 
    IoFreeIrp(Irp); 
    return STATUS_MORE_PROCESSING_REQUIRED; 
 
HANDLE  FD_OpenFile ( WCHAR szFileName[] ) 
    NTSTATUS            ntStatus ; 
    UNICODE_STRING      FileName ; 
    OBJECT_ATTRIBUTES   objectAttributes; 
    HANDLE              hFile ; 
    IO_STATUS_BLOCK     ioStatus ; 
 
    // 确保IRQL在PASSIVE_LEVEL上 
    if (KeGetCurrentIrql() > PASSIVE_LEVEL) 
        return NULL; 
 
    // 初始化文件名 
    RtlInitUnicodeString ( &FileName, szFileName ) ; 
    DbgPrint ( "%ws", FileName.Buffer ) ; 
 
    //初始化对象属性 
    InitializeObjectAttributes ( &objectAttributes, &FileName,OBJ_KERNEL_HANDLE|OBJ_CASE_INSENSITIVE, NULL, NULL ) ; 
 
    // 打开文件 
    ntStatus = IoCreateFile ( &hFile, FILE_READ_ATTRIBUTES, &objectAttributes, &ioStatus, / 
        0,FILE_ATTRIBUTE_NORMAL,FILE_SHARE_DELETE,FILE_OPEN,0,NULL,0,CreateFileTypeNone,NULL,IO_NO_PARAMETER_CHECKING); 
    if ( !NT_SUCCESS(ntStatus) ) 
        return NULL ; 
 
    return  hFile ; 
 
BOOLEAN FD_StripFileAttributes ( HANDLE FileHandle ) 
    NTSTATUS                ntStatus = STATUS_SUCCESS; 
    PFILE_OBJECT            fileObject; 
    PDEVICE_OBJECT          DeviceObject; 
    PIRP                    Irp; 
    KEVENT                  SycEvent; 
    FILE_BASIC_INFORMATION  FileInformation; 
    IO_STATUS_BLOCK         ioStatus; 
    PIO_STACK_LOCATION      irpSp; 
 
    // 获取文件对象 
    ntStatus = ObReferenceObjectByHandle ( FileHandle, DELETE, 
        *IoFileObjectType, KernelMode, (PVOID*)&fileObject, NULL) ; 
    if ( !NT_SUCCESS(ntStatus) ) 
    
        DbgPrint ( "ObReferenceObjectByHandle error!" ) ; 
        return FALSE; 
    
 
    // 获取与指定文件对象相关联的设备对象 
    DeviceObject = IoGetRelatedDeviceObject ( fileObject ) ; 
 
    // 创建IRP 
    Irp = IoAllocateIrp ( DeviceObject->StackSize, TRUE ) ; 
    if ( Irp == NULL )  
    
        ObDereferenceObject(fileObject); 
 
        DbgPrint ( "FD_StripFileAttributes IoAllocateIrp error" ) ; 
        return FALSE; 
    
 
    // 初始化同步事件对象 
    KeInitializeEvent ( &SycEvent, SynchronizationEvent, FALSE ) ; 
 
    memset ( &FileInformation, 0, 0x28 ) ; 
    FileInformation.FileAttributes = FILE_ATTRIBUTE_NORMAL; 
 
    // 初始化IRP 
    Irp->AssociatedIrp.SystemBuffer          = &FileInformation; 
    Irp->UserEvent                           = &SycEvent; 
    Irp->UserIosb                            = &ioStatus; 
    Irp->Tail.Overlay.OriginalFileObject = fileObject; 
    Irp->Tail.Overlay.Thread             = (PETHREAD)KeGetCurrentThread(); 
    Irp->RequestorMode = KernelMode; 
 
    // 设置IRP堆栈信息 
    irpSp = IoGetNextIrpStackLocation(Irp); 
    irpSp->MajorFunction = IRP_MJ_SET_INFORMATION; 
    irpSp->DeviceObject      = DeviceObject; 
    irpSp->FileObject        = fileObject; 
    irpSp->Parameters.SetFile.Length             = sizeof(FILE_BASIC_INFORMATION) ; 
    irpSp->Parameters.SetFile.FileInformationClass   = FileBasicInformation; 
    irpSp->Parameters.SetFile.FileObject         = fileObject ; 
 
    // 设置完成例程 
    IoSetCompletionRoutine ( Irp, FD_SetFileCompletion ,NULL, TRUE, TRUE, TRUE ) ; 
 
    // 派发IRP 
    IoCallDriver(DeviceObject, Irp); 
 
    // 等待IRP的完成 
    KeWaitForSingleObject ( &SycEvent, Executive, KernelMode, TRUE, NULL ) ; 
 
    // 递减引用计数 
    ObDereferenceObject(fileObject); 
 
    return TRUE ; 
 
BOOLEAN FD_DeleteFile ( HANDLE FileHandle ) 
    NTSTATUS          ntStatus = STATUS_SUCCESS; 
    PFILE_OBJECT      fileObject; 
    PDEVICE_OBJECT    DeviceObject; 
    PIRP              Irp; 
    KEVENT            SycEvent ; 
    FILE_DISPOSITION_INFORMATION    FileInformation; 
    IO_STATUS_BLOCK                 ioStatus; 
    PIO_STACK_LOCATION              irpSp; 
    PSECTION_OBJECT_POINTERS        pSectionObjectPointer;      
 
    // 获取文件对象 
    ntStatus = ObReferenceObjectByHandle ( FileHandle, DELETE, 
        *IoFileObjectType, KernelMode, (PVOID*)&fileObject, NULL) ; 
    if ( !NT_SUCCESS(ntStatus) ) 
    
        DbgPrint ( "ObReferenceObjectByHandle error!" ) ; 
        return FALSE; 
    
 
    // 获取与指定文件对象相关联的设备对象 
    DeviceObject = IoGetRelatedDeviceObject ( fileObject ) ; 
 
    // 创建IRP 
    Irp = IoAllocateIrp ( DeviceObject->StackSize, TRUE ) ; 
    if (Irp == NULL) 
    
        ObDereferenceObject ( fileObject ) ; 
        DbgPrint ( "FD_DeleteFile IoAllocateIrp error" ) ; 
        return FALSE; 
    
 
    // 初始化同步事件对象 
    KeInitializeEvent ( &SycEvent, SynchronizationEvent, FALSE ) ; 
 
    FileInformation.DeleteFile = TRUE; 
 
    // 初始化IRP 
    Irp->AssociatedIrp.SystemBuffer          = &FileInformation; 
    Irp->UserEvent                           = &SycEvent; 
    Irp->UserIosb                            = &ioStatus; 
    Irp->Tail.Overlay.OriginalFileObject = fileObject; 
    Irp->Tail.Overlay.Thread             = (PETHREAD)KeGetCurrentThread(); 
    Irp->RequestorMode                       = KernelMode; 
 
    // 设置IRP堆栈 
    irpSp = IoGetNextIrpStackLocation(Irp); 
    irpSp->MajorFunction = IRP_MJ_SET_INFORMATION; 
    irpSp->DeviceObject      = DeviceObject; 
    irpSp->FileObject        = fileObject; 
    irpSp->Parameters.SetFile.Length             = sizeof(FILE_DISPOSITION_INFORMATION); 
    irpSp->Parameters.SetFile.FileInformationClass   = FileDispositionInformation; 
    irpSp->Parameters.SetFile.FileObject         = fileObject; 
 
    // 设置完成例程 
    IoSetCompletionRoutine ( Irp, FD_SetFileCompletion, NULL, TRUE, TRUE, TRUE ) ; 
 
    // 如果没有这3行,就无法删除正在运行的文件 
    pSectionObjectPointer = fileObject->SectionObjectPointer; 
    pSectionObjectPointer->ImageSectionObject = 0
    pSectionObjectPointer->DataSectionObject = 0
 
    // 派发IRP 
    IoCallDriver ( DeviceObject, Irp ) ; 
 
    // 等待IRP完成 
    KeWaitForSingleObject ( &SycEvent, Executive, KernelMode, TRUE, NULL); 
 
    // 递减引用计数 
    ObDereferenceObject ( fileObject ) ; 
 
    return TRUE ; 
 
BOOLEAN ForceDeleteFile ( WCHAR szFileName[] ) 
    HANDLE      hFile = NULL ; 
    BOOLEAN     status = FALSE ; 
 
    __try { 
        // 打开文件 
        if ( ( hFile = FD_OpenFile( szFileName ) ) == NULL ) 
        
            DbgPrint ( "FD_OpenFile error!" ) ; 
            return FALSE ; 
        
 
        // //去掉只读属性,才能删除只读文件 
        if ( FD_StripFileAttributes(hFile) == FALSE ) 
        
            ZwClose ( hFile ) ; 
            DbgPrint ( "FD_StripFileAttributes error!" ) ; 
            return FALSE ; 
        
 
        // 删除文件 
        status = FD_DeleteFile(hFile) ; 
        ZwClose ( hFile ) ; 
 
        return status ; 
 
    } __except ( 1 ) { 
        DbgPrint ( "execption!" ) ; 
    
 
    return FALSE ; 
}

在我测试中按照他的方法调用 失败
OpenFile错误
所以觉得是路径问题
经过测试发现

1
2
3
ForceDeleteFile(L"//DosDevices//C://test.exe")
\\这个路径应改为
ForceDeleteFile(L"\\DosDevices\\C:\\test.exe")

Win7 x64下测试成功


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

最后于 2022-8-9 01:00 被逍遥m编辑 ,原因:
收藏
免费 0
支持
分享
最新回复 (2)
雪    币: 210
活跃值: (1707)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
这个代码在 正常的系统用没啥毛病 但是在一些透明加解密系统上面会有bug 会让文件无法删除 
2022-8-9 19:39
0
雪    币: 881
活跃值: (9856)
能力值: ( LV13,RANK:385 )
在线值:
发帖
回帖
粉丝
3
了解下原理. 驱动如何调用驱动的. 异步同步等方式. IRP直接驱动方式. 上面就是IRP驱动方式. 如果学习代码,了解下我说的这些. 直接底层调用驱动帮你删就可以了. 而不局限于只会用.  了解了就明白为啥这样写了. 为啥要设置那三行代码.  了解了 自己都可以实现 CreateFile ZwReadFile ZwWriteFile ZwDeviceControlFile.....
2022-8-10 19:22
0
游客
登录 | 注册 方可回帖
返回
//