小默

发送IRP删除正在运行文件学习笔记zz

在网上看到了北极星2003写的这篇文章,代码写的很好,注释也很清楚,方便了我这个大菜鸟的学习,对他的无私奉献非常非常感谢。

强制删除文件的思路就是,把SECTION_OBJECT_POINTERS结构的DataSectionObjectImageSectionObject两个域清空即可删除正在运行的文件。如果不清空就不能删除运行中的文件。正在运行的文件的这两个域值不为0而文件系统正在根据这两个域决定该文件是否可以删除。如果文件系统检测这两个值为0,就理解为文件没有被使用,可以删除。接下去,就是直接发IRP,初始化IRP,设置IRP堆栈信息,设置完成例程,派发IRP

一、获得文件内核句柄

RtlInitUnicodeString ( &FileName, L” \\DosDevices\\C:\\test.exe” ) ;

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);

打开文件应该传入这个文件的路径。但是实际上这个函数IoCreateFile并不直接接受一个字符串。使用者必须首先填写一个OBJECT_ATTRIBUTES 结构。

用到一个宏:InitializeObjectAttributes用来初始化对象属性

我们是对c:\test.exe,这是个固定的文件了,属性应该也固定了,为什么还要初始化属性呢?

其实这里的初始化属性,主要是为了包含文件的对象路径,然后在指明该代码对该文件的一些要求,如获得内核句柄,不区分文件名的大小写,而不是对文件的操作。即将FileName,OBJ_KERNEL_HANDLE|OBJ_CASE_INSENSITIVE,全放入objectAttributes这个结构中。

typedef struct _OBJECT_ATTRIBUTES {

    ULONG Length;

    HANDLE RootDirectory;

    PUNICODE_STRING ObjectName;

    ULONG Attributes;

    PVOID SecurityDescriptor;

    PVOID SecurityQualityOfService;

} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;

要说明2点:

1objectAttributes结构中的ObjectName要求的是对象的路径名,因此不能写成c:\test,

c:是一个符号链接对象,内核模式下,符号链接要写成\\??\\C:或者\\DosDevices\\C:

因此对象路径名为:\\DosDevices\\C:\\test.exe\\??\\C:\\test.exe

2InitializeObjectAttributes 只需要填写OBJ_CASE_INSENSITIVE| OBJ_KERNEL_HANDLE即可

OBJ_CASE_INSENSITIVE意味着名字字符串是 不区分大小写的

OBJ_KERNEL_HANDLE表明打开的文件句柄一个“内核句柄”

二、发送IRP去除文件的只读属性

对文件的任何操作,最终都是通过IRP请求,然后文件系统驱动对该IRP进行处理,完成对文件的指定操作。

驱动程序,则可以自己创建IRP,初始化IRP,设置IRP堆栈信息,设置完成例程,派发IRP。这里我们采用的就是这种方法。

三、发送IRP删除文件

Windows API中的DeleteFile实现文件删除功能的内部实现:

DeleteFile 通过 IRP_MJ_SET_INFORMATION请求的IRP,并且将pIrpStack->Parameters.SetFile.FileInformationClass设为FileDispositionInformation((PFILE_DISPOSITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer)->DeleteFile设为TRUE来达到删除文件。

所以我们有:

FILE_DISPOSITION_INFORMATION    FileInformation;

FileInformation.DeleteFile = TRUE;

// 初始化IRP  

Irp->AssociatedIrp.SystemBuffer          = &FileInformation;  

// 设置IRP堆栈  

irpSp->Parameters.SetFile.FileInformationClass   = FileDispositionInformation;

由上,我们可以删除这个文件,但是如果文件在运行,则不能删除,需要加上如下代码:

// 如果没有这4行,就无法删除正在运行的文件  

PSECTION_OBJECT_POINTERS        pSectionObjectPointer;

    pSectionObjectPointer = fileObject->SectionObjectPointer;  

    pSectionObjectPointer->ImageSectionObject = 0;  

    pSectionObjectPointer->DataSectionObject = 0;  

对于如何创建IRP,初始化IRP,设置IRP堆栈信息,设置完成例程,派发IRP,这里先不写了,等再整理整理后再写吧。

posted on 2010-02-06 00:18 小默 阅读(1142) 评论(0)  编辑 收藏 引用 所属分类: Windows


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


导航

统计

留言簿(13)

随笔分类(287)

随笔档案(289)

漏洞

搜索

积分与排名

最新评论

阅读排行榜