if(!irp)
{
DbgPrint("allocate irp 2 is error\n");
ZwClose(hfile);
}
filedispotion.DeleteFile=TRUE; //表示删除该文件
irp->AssociatedIrp.SystemBuffer=&filedispotion;
irp->UserIosb=&iostatus;
irp->UserEvent=&event2;
irp->Tail.Overlay.OriginalFileObject=fileobject;
irp->Tail.Overlay.Thread=(PETHREAD)KeGetCurrentThread();
irp->RequestorMode=KernelMode;
irpsp=IoGetNextIrpStackLocation(irp);
irpsp->DeviceObject=deviceobject;
irpsp->FileObject=fileobject;
irpsp->MajorFunction=IRP_MJ_SET_INFORMATION;
irpsp->Parameters.SetFile.Length=sizeof(FILE_DISPOSITION_INFORMATION);
irpsp->Parameters.SetFile.FileInformationClass=FileDispositionInformati
on; //表示处理文件,前面设置DELETE为TRUE
irpsp->Parameters.SetFile.FileObject=fileobject;
SectionOjbect=fileobject->SectionObjectPointer;
SectionOjbect->DataSectionObject=0;
SectionOjbect->ImageSectionObject=0;
IoSetCompletionRoutine(irp,SetInformationComplete,&event2,TRUE,TRUE,TRUE);
IoCallDriver(deviceobject,irp);
[/code]
其中
SectionOjbect->DataSectionObject=0;
SectionOjbect->ImageSectionObject=0;
这2条代码很重要。
在MmFlushImageSection会检测DataSectionObject和ImageSectionObject,如果都为0,则
表示文件不在运行,可以删除。
打开my.exe
加载deletefile.sys驱动.
发现my.exe被删除了,而且my.exe并没有被关闭。下面介绍一种hardlink硬链接的技
术。NTFS文件系统才支持的特性。Hard link 硬链接技术,它和原文件名指向的是存储设备
上同一个文件内容。就好像这个文件内容有多个文件名一样,每个文件名有相等地位。删除
其中任何一个之后,事实上文件内容并不会被删除掉,仍然可以用其他的名称来访问这个文
件。只有当最后一个指向这个文件内容的文件名被删除掉之后,文件内容才被删除。我们建
立硬链接后,我们createfile打开一个文件名后,另一个文件名也会被占坑,但是在系统中
不会有另一个文件的句柄。
我们在建立个c:\my.txt,并且为它建立个c:\1.txt的硬链接, 建立硬链接可以用系统
自带的工具fsutil hardlink create c:\my.txt c:\1.txt就OK了。
然后占坑1.txt,看看有什么惊喜。发现my.txt和1.txt都无法删除。
用句柄查看工具,可以看到有1.txt的句柄,却没有my.txt的句柄。
这样,我们枚举系统所有句柄就失效了,因为你无法找到my.txt的句柄,也就无法关闭
my.txt的句柄,这样就删除不了my.txt。只有关闭1.txt的句柄才可以删除my.txt,但是你
并不知道1.txt与my.txt建立硬链接了。
下面介绍一种强大的文件解锁方法:XCB解锁(国内一款软件就是用该方法)。
本文只实现XP SP3 NTFS的XCB解锁,FAT和其他系统的请不要测试本文的XCB代码。会蓝屏的
XCB解锁的原理是:
在发送IRP删除文件的时候,如果文件被占坑,文件系统则会设置
XCB_STATE_DELETE_ON_CLOSE标志,然后,我们设置该文件的SCB(Stream Control
Block),FCB(File Control Blokc),CCB(Context Control Block)的cleanupcount为1,然后
调用ZwClose。系统在关闭句柄的时候,如果检测到_STATE_DELETE_ON_CLOSE就会删除文件
(具体的代码有兴趣可以看看nt_4src)。篇幅有限不多介绍。
在FILE_OBJECT结构体中,有2个域, FsContext,FsContext2,其中 FsContext指向SCB,SCB
中有个域是FCB的指针, FsContext2指向CCB。由于 SCB,FCB,CCB都是windows没有公开的结构,
所有偏移只有通过逆向得到,且每个系统都不一样。
发送IRP去除只读属性和设置DELETE的代码已经讲过。下面看修改cleanupcount的代码。
(附件中的xcb工程)
[code]
//定义偏移,这只是XP SP3 ntfs的偏移。
#define cleanup_ob_scb_offset 0x58
#define pfcb_of_scb_offset 0x48
#define cleanup_of_fcb_offset 0x10
#define ccb_of_offset 0x20
#define cleanup_of_ccb_offset 0x7c
…..
… …..
pscb=fileobject->FsContext;
pccb=fileobject->FsContext2;
if(pscb)
{
*(PULONG)(pscb+cleanup_ob_scb_offset)=1; //scb->cleanupcount=1
pfcb=(PCHAR)*(PULONG)(pscb+pfcb_of_scb_offset); |