关于不结束进程强删文件一点点看法
来源:互联网 发布:中国科学文献数据库 编辑:程序博客网 时间:2024/05/02 01:11
这也是好久以前的代码了。我是菜鸟,在这个问题上研究的不够深,说错了还请大牛指正。
这个问题也是一个老问题,不过我是菜鸟我有话要说。我在做这个问题的时候查阅了好多资料,其实这个问题不能算解决,这篇文章你将会看到一段比较长的代码,其实这段代码不是我写的,是网上一个比较有名的人(人称MJ)写的,据说这段代码是通过360文件粉碎机逆向出来的。
我查了好多资料,发现能够实现标题所说的功能大概有两种常用的方法,一个是本文提到的直接发送IRP给目标文件的设备驱动强删文件,还有一种就是挂钩MmFlushImageSection函数,很遗憾的是后一种方法没有什么实质性的源码可以参考(不过哪位大神写一段的话可以拿来分享一下),MmFlushImageSection不是一个系统服务,SSDT的方法当然不行,因为SSDT表没有导出这个函数,我记忆不错的话按照“列宁”大神的说法MmFlushImageSection函数更加底层,是由内核导出的一个内核函数。以我的才疏学浅的知识不明白如何挂钩这样的函数。如果有哪位大神看见了本菜鸟的疑惑还请不吝赐教。
另外还想提到的一点是,之前被一个论坛的好友迷惑了一下,他说只要使用NtDeleteFile这个系统服务就可以实现这样的功能,这个系统服务有这么一个功能:
在《The Undocumented Functions》一书中可以看到它对NtDeleteFile的解释如下:
It's very interesting NT System Call... Normally, file deletion is realised as FileDispositionInformation class in a call to NtSetInformationFile. When you use NtDeleteFile, file will be deleted immediatly after call (system isn't waiting for close last HANDLE to file).
从上述说明可以看出,如果我们直接调用NtDeleteFile,目标文件将会被立即删除而不会等到所有句柄都被关闭。
原文在此
于是就试了一下,诶?果然能删除文件,我是用一个记事本试的,比如aa.txt。其实这种方式是不正确的,为什么呢?仔细想想,aa.txt是自己打开的吗?不是,是由记事本程序打开的,也就是notepad.exe,你删除了文件并不能表示你可以删除正在运行的exe文件,果然,事实证明这样写不能删除正在运行的exe文件。下面也附上我写的这段代码吧,虽然方法上是不正确的。
#include "windows.h"typedef struct _UNICODE_STRING {USHORT Length;USHORT MaximumLength;PWSTR Buffer;} UNICODE_STRING, *PUNICODE_STRING;typedef struct _OBJECT_ATTRIBUTES { ULONG Length; HANDLE RootDirectory; PUNICODE_STRING ObjectName; ULONG Attributes; PVOID SecurityDescriptor; PVOID SecurityQualityOfService;} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;static VOID InitializeObjectAttributes ( OUT POBJECT_ATTRIBUTES InitializedAttributes, IN PUNICODE_STRING ObjectName, IN ULONG Attributes, IN HANDLE RootDirectory, IN PSECURITY_DESCRIPTOR SecurityDescriptor ) { InitializedAttributes->Length = sizeof( OBJECT_ATTRIBUTES ); InitializedAttributes->RootDirectory = RootDirectory; InitializedAttributes->Attributes = Attributes; InitializedAttributes->ObjectName = ObjectName; InitializedAttributes->SecurityDescriptor = SecurityDescriptor; InitializedAttributes->SecurityQualityOfService = NULL; return; }//extern "C" __declspec(dllimport) long __stdcall NtDeleteFile(POBJECT_ATTRIBUTES ObjectAttribtues);typedef ULONG (__stdcall *_NtDeleteFile)(IN POBJECT_ATTRIBUTES ObjectAttributes);_NtDeleteFile NtDeleteFile;void main(){HMODULE m_handle=LoadLibrary("ntdll.dll");UNICODE_STRING uniname ;WCHAR m_file_name[]={L"\\??\\e:\\aa.txt"};uniname.Buffer=m_file_name;uniname.Length = sizeof(m_file_name) - sizeof(WCHAR);uniname.MaximumLength = sizeof(uniname);OBJECT_ATTRIBUTES oba ;if (m_handle!=NULL){InitializeObjectAttributes(&oba , &uniname , 0x40 , 0 , 0 );NtDeleteFile=(_NtDeleteFile)GetProcAddress(m_handle,"NtDeleteFile");NtDeleteFile(&oba);}}
这是一个用户态的程序,直接从ntdll中导出了NtDeleteFile。
然后我也附上Mj大神的发送IRP强删文件的方法:
#include <ntddk.h>#define NT_DEVICE_NAME L"\\Device\\360SuperKill"#define DOS_DEVICE_NAME L"\\DosDevices\\360SuperKill"NTSTATUS NTAPI VfatBuildRequest (PDEVICE_OBJECT DeviceObject, PIRP Irp);VOID SKillUnloadDriver( IN PDRIVER_OBJECT DriverObject ){ PDEVICE_OBJECT deviceObject = DriverObject->DeviceObject; UNICODE_STRING uniSymLink; RtlInitUnicodeString(&uniSymLink, DOS_DEVICE_NAME); IoDeleteSymbolicLink(&uniSymLink); IoDeleteDevice(deviceObject);}HANDLESkillIoOpenFile(IN PCWSTR FileName,IN ACCESS_MASK DesiredAccess,IN ULONG ShareAccess){ NTSTATUS ntStatus; UNICODE_STRING uniFileName; OBJECT_ATTRIBUTES objectAttributes; HANDLE ntFileHandle; IO_STATUS_BLOCK ioStatus; if (KeGetCurrentIrql() > PASSIVE_LEVEL) { return 0; } RtlInitUnicodeString(&uniFileName, FileName); InitializeObjectAttributes(&objectAttributes, &uniFileName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL); ntStatus = IoCreateFile(&ntFileHandle, DesiredAccess, &objectAttributes, &ioStatus, 0, FILE_ATTRIBUTE_NORMAL, ShareAccess, FILE_OPEN, 0, NULL, 0, 0, NULL, IO_NO_PARAMETER_CHECKING); if (!NT_SUCCESS(ntStatus)) { return 0; } return ntFileHandle;}//回调函数NTSTATUSSkillSetFileCompletion( 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);//释放IRP return STATUS_MORE_PROCESSING_REQUIRED;}BOOLEAN SKillDeleteFile(IN HANDLE FileHandle){ NTSTATUS ntStatus = STATUS_SUCCESS; PFILE_OBJECT fileObject; PDEVICE_OBJECT DeviceObject; PIRP Irp; KEVENT event; FILE_DISPOSITION_INFORMATION FileInformation; IO_STATUS_BLOCK ioStatus; PIO_STACK_LOCATION irpSp; PSECTION_OBJECT_POINTERS pSectionObjectPointer; ntStatus = ObReferenceObjectByHandle(FileHandle, DELETE, *IoFileObjectType, KernelMode, &fileObject, NULL);//打开文件的设备对象 if (!NT_SUCCESS(ntStatus)) { return FALSE; } DeviceObject = IoGetRelatedDeviceObject(fileObject); //返回打开的对象指针 Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE); //分配一个该设备对象的IRP if (Irp == NULL) { ObDereferenceObject(fileObject); return FALSE; } KeInitializeEvent(&event, SynchronizationEvent, FALSE);//初始化IRP的信号状态 FileInformation.DeleteFile = TRUE;//设置IRP Irp->AssociatedIrp.SystemBuffer = &FileInformation; Irp->UserEvent = &event; Irp->UserIosb = &ioStatus; Irp->Tail.Overlay.OriginalFileObject = fileObject; Irp->Tail.Overlay.Thread = (PETHREAD)KeGetCurrentThread(); Irp->RequestorMode = KernelMode; 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;//设置完成IPR请求的回调函数 IoSetCompletionRoutine( Irp, SkillSetFileCompletion, &event, TRUE, TRUE, TRUE); pSectionObjectPointer = fileObject->SectionObjectPointer; pSectionObjectPointer->ImageSectionObject = 0; pSectionObjectPointer->DataSectionObject = 0; IoCallDriver(DeviceObject, Irp); //发送IRP KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, NULL); ObDereferenceObject(fileObject); //关闭设备对象 return TRUE;}NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ){ UNICODE_STRING uniDeviceName; UNICODE_STRING uniSymLink; NTSTATUS ntStatus; PDEVICE_OBJECT deviceObject = NULL; HANDLE hFileHandle; RtlInitUnicodeString(&uniDeviceName, NT_DEVICE_NAME); RtlInitUnicodeString(&uniSymLink, DOS_DEVICE_NAME); //创建设备对象 ntStatus = IoCreateDevice( DriverObject, 0, &uniDeviceName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &deviceObject); if (!NT_SUCCESS(ntStatus)) { return ntStatus; } //设置设备对象的名称 ntStatus = IoCreateSymbolicLink(&uniSymLink, &uniDeviceName); if (!NT_SUCCESS(ntStatus)) { IoDeleteDevice(deviceObject); return ntStatus; } DriverObject->DriverUnload = SKillUnloadDriver; //打开文件 hFileHandle = SkillIoOpenFile(L"\\??\\c:\\calc.exe", FILE_READ_ATTRIBUTES, FILE_SHARE_DELETE); DbgPrint("hFileHandle:%08X/n",hFileHandle); if (hFileHandle!=NULL) { SKillDeleteFile(hFileHandle); //删除文件 ZwClose(hFileHandle); } return STATUS_SUCCESS;}
这是一段驱动代码,需要DDK编译成驱动文件。大题的思路我已经用注释说明,细节部分还有待仔细研究。
菜鸟言论,仅供娱乐。
- 关于不结束进程强删文件一点点看法
- 关于不结束进程强删文件一点点看法
- 关于技术交流的一点点看法
- 关于技术交流的一点点看法
- 关于三层架构的一点点看法
- 关于程序员面试的一点点看法
- C++强杀进程,可结束IceSword
- 关于软件质量和软件测试的一点点看法
- 关于软件质量和软件测试的一点点看法
- 关于软件质量和软件测试的一点点看法 zz
- 不结束进程卸载关键进程中DLL文件的方法
- 关于结束进程的语句
- 关于文件结束标志
- 关于tarjan求强联通的一点小看法
- 关于文件结束符EOF
- 关于文件结束符EOF
- 关于结束进程的问题,高手请进。
- C# 保护进程不被结束(源代码)防任务管理器结束进程
- 11.09.18 ~ 11.09.24
- 学习java编程思想
- http长连接与短连接
- proFTPd的使用配置
- 调用约定,名字修饰约定
- 关于不结束进程强删文件一点点看法
- C语言中的floor函数与cei函数
- 搭建Android开发环境详述
- 2路插入排序
- Perl语言中的变量类型
- c模拟内存管理
- 利用等概率Rand5产生等概率Rand3
- JDK7新特性之G1 GC(转)
- HttpWebRequest的标头和Heanders集合的区别