强删文件--->构建IRP---->独占--->正在运行 以及磁盘读写(思路)

个人比较崇拜360 一个小小的按钮下面蕴含着很多的原理 要有多么强大才能1天搞定偏移
-------致敬360 致敬MJ-001
无奈本人学业不精 只能说说“独占”和“正在运行”
打开文件 一般使用ZwCreateFile NtCreateFile 但这些函数还不够底层 使用IoCreateFile会好一些
被其它程序独占
枚举句柄表 ZwQuerySystemInformation --->复制句柄 ZwDuplicateObject --->ZwClose 然后再ZwDuplicateObject 一次 这次使用DUPLICATE_CLOSE_SOURCE -->ZwClose


正在运行 这个涉及构建IRP 最下面会说
将ImageSectionObject 和 DataSectionObject设为0就可以解决了
 NtfsSetDispositionInfoMmFlushImageSection
 pSectionObjectPointer = fileObject->SectionObjectPointer;
 pSectionObjectPointer->ImageSectionObject = 0;
 pSectionObjectPointer->DataSectionObject = 0;

 核心代码代码:

 NTSTATUS
dfSkillSetFileCompletion(
    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;
}

BOOLEAN dfDelFile(WCHAR* name)
{
    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;
    HANDLE handle;

    ntStatus = dfOpenFile(name, &handle, FILE_READ_ATTRIBUTES|DELETE,FILE_SHARE_DELETE);
	if (ntStatus == STATUS_OBJECT_NAME_NOT_FOUND ||
		ntStatus == STATUS_OBJECT_PATH_NOT_FOUND )
	{
		KdPrint(("No such file"));
		return FALSE;
	}
	else if (!NT_SUCCESS(ntStatus))
	{
		if (dfCloseFileHandle(name))
		{
			ntStatus = dfOpenFile(name, &handle, FILE_READ_ATTRIBUTES|DELETE,FILE_SHARE_DELETE);
			if (!NT_SUCCESS(ntStatus))
				return FALSE;
		}
		else
		{
			return FALSE;
		}
	}

    ntStatus = ObReferenceObjectByHandle(handle,
        DELETE,
        *IoFileObjectType,
        KernelMode,
        &fileObject,
        NULL);

    if (!NT_SUCCESS(ntStatus))
    {
    	DbgPrint("ObReferenceObjectByHandle()");
		ZwClose(handle);
        return FALSE;
    }  

    DeviceObject = IoGetRelatedDeviceObject(fileObject);
    Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);

    if (Irp == NULL)
    {
        ObDereferenceObject(fileObject);
		ZwClose(handle);
        return FALSE;
    }

    KeInitializeEvent(&event, SynchronizationEvent, FALSE);
   
    FileInformation.DeleteFile = TRUE;

    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;

    IoSetCompletionRoutine(
            Irp,
            dfSkillSetFileCompletion,
            &event,
            TRUE,
            TRUE,
            TRUE);
    pSectionObjectPointer = fileObject->SectionObjectPointer;
    if(pSectionObjectPointer)
	{
		pSectionObjectPointer->ImageSectionObject = 0;
		pSectionObjectPointer->DataSectionObject = 0;
	}
    ntStatus = IoCallDriver(DeviceObject, Irp); 
    if (!NT_SUCCESS(ntStatus))
    {
    	 ObDereferenceObject(fileObject);
		 ZwClose(handle);
         return FALSE;
    }  

    KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, NULL);
	//IoFreeIrp(Irp);
    ObDereferenceObject(fileObject);
    ZwClose(handle);
    return TRUE;

}


整个工程代码:

DelFile.c

#include <ntddk.h>
#include <ntimage.h>
#include <ntdef.h>
#include "DelFile.h"

PDEVICE_OBJECT	g_HookDevice;


NTSTATUS dfQuerySymbolicLink(
	IN PUNICODE_STRING SymbolicLinkName,
	OUT PUNICODE_STRING LinkTarget
	)                                  
{
    OBJECT_ATTRIBUTES oa;
    NTSTATUS status;
    HANDLE handle;
   
    InitializeObjectAttributes(
		&oa, 
		SymbolicLinkName,
		OBJ_CASE_INSENSITIVE,
        0, 
		0);
   
    status = ZwOpenSymbolicLinkObject(&handle, GENERIC_READ, &oa);
    if (!NT_SUCCESS(status))
    {
        return status;
    }
   
    LinkTarget->MaximumLength = 1024*sizeof(WCHAR);
    LinkTarget->Length = 0;
    LinkTarget->Buffer = ExAllocatePoolWithTag(PagedPool, LinkTarget->MaximumLength, 'A0');
    if (!LinkTarget->Buffer)
    {
        ZwClose(handle);
        return STATUS_INSUFFICIENT_RESOURCES;
    }


    RtlZeroMemory(LinkTarget->Buffer, LinkTarget->MaximumLength);
   
    status = ZwQuerySymbolicLinkObject(handle, LinkTarget, NULL);
    ZwClose(handle);
   
    if (!NT_SUCCESS(status))
    {
        ExFreePool(LinkTarget->Buffer);
    }
   
    return status;
}


BOOLEAN dfCloseFileHandle(WCHAR *name)
{
	
	NTSTATUS					 status;
	PVOID						 buf   = NULL;
	PSYSTEM_HANDLE_INFORMATION 	 pSysHandleInfo;
	SYSTEM_HANDLE_TABLE_ENTRY_INFO handleTEI;


	ULONG						size  = 1;
	ULONG						NumOfHandle = 0;
	ULONG						i;
	CLIENT_ID 					cid;
	HANDLE						hHandle;
	HANDLE						hProcess;
	HANDLE 						hDupObj;
	HANDLE						hFile;
	HANDLE						link_handle;
	OBJECT_ATTRIBUTES 			oa;
	ULONG						FileType; 
	ULONG						processID;
	UNICODE_STRING 				uLinkName;
	UNICODE_STRING				uLink;
	OBJECT_ATTRIBUTES 			objectAttributes;
	IO_STATUS_BLOCK 		 	IoStatus;
	ULONG 						ulRet;
    PVOID    			 		fileObject;
	POBJECT_NAME_INFORMATION 	pObjName;
	UNICODE_STRING				delFileName = {0};
	int							length;
	WCHAR						wVolumeLetter[3];
	WCHAR						*pFilePath;
	UNICODE_STRING				uVolume;
	UNICODE_STRING				uFilePath;
	UNICODE_STRING 				NullString = RTL_CONSTANT_STRING(L"");
	BOOLEAN					bRet = FALSE;




	for ( size = 1; ; size *= 2 )
	{
		if ( NULL == ( buf = ExAllocatePoolWithTag(NonPagedPool,size, 'FILE') ) )
		{
			DbgPrint(("alloc mem failed\n"));
			goto Exit;
		}
		RtlZeroMemory( buf ,size );
		status = ZwQuerySystemInformation( SystemHandleInformation, buf, size, NULL );
		if ( !NT_SUCCESS( status ) )
		{
			if ( STATUS_INFO_LENGTH_MISMATCH == status )
			{
				ExFreePool( buf );
				buf = NULL;
			}
			else
			{
				DbgPrint(( "ZwQuerySystemInformation() failed"));
				goto Exit;
			}
		}
		else
		{
			break;
		}
	}


	pSysHandleInfo = (PSYSTEM_HANDLE_INFORMATION)buf;
	NumOfHandle = pSysHandleInfo->NumberOfHandles;


	


	/* Get the volume character like C: */


	wVolumeLetter[0] = name[4];
	wVolumeLetter[1] = name[5];
	wVolumeLetter[2] = 0;
	uLinkName.Buffer = ExAllocatePoolWithTag(NonPagedPool, 256 + sizeof(ULONG), 'A1');
	uLinkName.MaximumLength = 256;
	RtlInitUnicodeString(&uVolume, wVolumeLetter);
	RtlInitUnicodeString( &uLink, L"\\DosDevices\\");
	RtlCopyUnicodeString(&uLinkName, &uLink);
	
	status = RtlAppendUnicodeStringToString(&uLinkName, &uVolume);
	if (!NT_SUCCESS(status))
	{
		KdPrint(("RtlAppendUnicodeStringToString() failed"));
		return FALSE;
	}
	
	dfQuerySymbolicLink(&uLinkName, &delFileName);
	RtlFreeUnicodeString(&uLinkName);
	KdPrint(("delFileName:%wZ", &delFileName));


	pFilePath = (WCHAR *) &name[6];
	RtlInitUnicodeString( &uFilePath, pFilePath);


	RtlAppendUnicodeStringToString(&delFileName, &uFilePath);
	if (!NT_SUCCESS(status))
	{
		KdPrint(("RtlAppendUnicodeStringToString() failed"));
		return FALSE;
	}


	KdPrint(("delFile:%wZ", &delFileName));


	for(i = 0; i < NumOfHandle ;i++)
	{
		handleTEI = pSysHandleInfo->Handles[i];
		if (handleTEI.ObjectTypeIndex != 25 && handleTEI.ObjectTypeIndex != 28)//28文件,25设备对象
			continue;
		processID = (ULONG) handleTEI.UniqueProcessId;
		cid.UniqueProcess = (HANDLE)processID;
		cid.UniqueThread = (HANDLE)0;
		hHandle = (HANDLE)handleTEI.HandleValue;
		InitializeObjectAttributes( &oa ,NULL ,0 ,NULL ,NULL );
		status = ZwOpenProcess( &hProcess ,PROCESS_DUP_HANDLE ,&oa ,&cid );
		if ( !NT_SUCCESS( status ) )
		{
			KdPrint(( "ZwOpenProcess:%d Fail ", processID));
			continue;
		}


		status = ZwDuplicateObject( hProcess ,hHandle ,NtCurrentProcess() ,&hDupObj ,\
		 PROCESS_ALL_ACCESS ,0 ,DUPLICATE_SAME_ACCESS );
		if ( !NT_SUCCESS( status ) )
		{
			DbgPrint(( "ZwDuplicateObject1 : Fail " ));
			continue;
		}
		status = ObReferenceObjectByHandle(
			  hDupObj,
			  FILE_ANY_ACCESS,
			  0,
			  KernelMode,
			  &fileObject,
			  NULL);
		
		if (!NT_SUCCESS(status))
		{
			DbgPrint(( "ObReferenceObjectByHandle : Fail " ));
			continue;
		}  


		pObjName = (POBJECT_NAME_INFORMATION) ExAllocatePoolWithTag(NonPagedPool, \
		    sizeof (OBJECT_NAME_INFORMATION) + 1024 * sizeof (WCHAR), 'A1');


		if (STATUS_SUCCESS != (status = ObQueryNameString(fileObject, pObjName, \
		    sizeof (OBJECT_NAME_INFORMATION) + 1024 * sizeof (WCHAR), &ulRet)))
		{
		   ObDereferenceObject(fileObject);
		   continue;
		}
		if (RtlCompareUnicodeString(&pObjName->Name, &delFileName, TRUE) == 0)
		{


			ObDereferenceObject(fileObject);
			ZwClose(hDupObj);


			status = ZwDuplicateObject( hProcess ,hHandle ,NtCurrentProcess() ,&hDupObj ,\
			 PROCESS_ALL_ACCESS ,0 ,DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE );
			if ( !NT_SUCCESS( status ) )
			{
				DbgPrint(( "ZwDuplicateObject2 : Fail " ));
				//return FALSE;
			}
			else
			{
				ZwClose(hDupObj);
				bRet = TRUE;
				//return TRUE;
			}
			break;


		}
			
		ExFreePool(pObjName);
		pObjName = NULL;


		ObDereferenceObject(fileObject);
		ZwClose( hDupObj );
		ZwClose( hProcess );


	}


Exit:
	if (pObjName != NULL)
	{
		ExFreePool(pObjName);
		pObjName = NULL;
	}
	if (delFileName.Buffer != NULL)
	{
		ExFreePool(delFileName.Buffer);	
	}
	if ( buf != NULL )
	{
		ExFreePool( buf );
		buf = NULL;
	}
	return(bRet);


}


NTSTATUS
dfOpenFile(WCHAR* name,PHANDLE phFileHandle, ACCESS_MASK access,ULONG share)
{


   IO_STATUS_BLOCK iosb;
   NTSTATUS stat;
   OBJECT_ATTRIBUTES oba;
   UNICODE_STRING nameus;


   if(KeGetCurrentIrql()>PASSIVE_LEVEL){return 0;}
   RtlInitUnicodeString(&nameus,name);
   InitializeObjectAttributes(
		&oba,
		&nameus,
		OBJ_KERNEL_HANDLE|OBJ_CASE_INSENSITIVE,
		0,
		0);
   stat=IoCreateFile(
		phFileHandle,
		access,
		&oba,
		&iosb,
		0,
		FILE_ATTRIBUTE_NORMAL,
		share,
		FILE_OPEN,
		0,
		NULL,
		0,
		0,
		NULL,
		IO_NO_PARAMETER_CHECKING);


	return stat;
}


NTSTATUS
dfSkillSetFileCompletion(
    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;
}


BOOLEAN dfDelFile(WCHAR* name)
{
    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;
    HANDLE handle;


    ntStatus = dfOpenFile(name, &handle, FILE_READ_ATTRIBUTES|DELETE,FILE_SHARE_DELETE);
	if (ntStatus == STATUS_OBJECT_NAME_NOT_FOUND ||
		ntStatus == STATUS_OBJECT_PATH_NOT_FOUND )
	{
		KdPrint(("No such file"));
		return FALSE;
	}
	else if (!NT_SUCCESS(ntStatus))
	{
		if (dfCloseFileHandle(name))
		{
			ntStatus = dfOpenFile(name, &handle, FILE_READ_ATTRIBUTES|DELETE,FILE_SHARE_DELETE);
			if (!NT_SUCCESS(ntStatus))
				return FALSE;
		}
		else
		{
			return FALSE;
		}
	}


    ntStatus = ObReferenceObjectByHandle(handle,
        DELETE,
        *IoFileObjectType,
        KernelMode,
        &fileObject,
        NULL);


    if (!NT_SUCCESS(ntStatus))
    {
    	DbgPrint("ObReferenceObjectByHandle()");
		ZwClose(handle);
        return FALSE;
    }  


    DeviceObject = IoGetRelatedDeviceObject(fileObject);
    Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);


    if (Irp == NULL)
    {
        ObDereferenceObject(fileObject);
		ZwClose(handle);
        return FALSE;
    }


    KeInitializeEvent(&event, SynchronizationEvent, FALSE);
   
    FileInformation.DeleteFile = TRUE;


    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;


    IoSetCompletionRoutine(
            Irp,
            dfSkillSetFileCompletion,
            &event,
            TRUE,
            TRUE,
            TRUE);
    pSectionObjectPointer = fileObject->SectionObjectPointer;
    if(pSectionObjectPointer)
	{
		pSectionObjectPointer->ImageSectionObject = 0;
		pSectionObjectPointer->DataSectionObject = 0;
	}
    ntStatus = IoCallDriver(DeviceObject, Irp); 
    if (!NT_SUCCESS(ntStatus))
    {
    	 ObDereferenceObject(fileObject);
		 ZwClose(handle);
         return FALSE;
    }  


    KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, NULL);
	//IoFreeIrp(Irp);
    ObDereferenceObject(fileObject);
    ZwClose(handle);
    return TRUE;


}




NTSTATUS OnUnload(IN PDRIVER_OBJECT DriverObject)
{
	UNICODE_STRING          deviceLinkUnicodeString;
	PDEVICE_OBJECT	   p_NextObj;




	DbgPrint("OnUnload called\n");


	p_NextObj = DriverObject->DeviceObject;


	if (p_NextObj != NULL)
	{


		RtlInitUnicodeString( &deviceLinkUnicodeString, deviceLinkBuffer );
		IoDeleteSymbolicLink( &deviceLinkUnicodeString );


		IoDeleteDevice( DriverObject->DeviceObject );
	}
	return STATUS_SUCCESS;
}


NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
	NTSTATUS                ntStatus;
	UNICODE_STRING          deviceNameUnicodeString;
    UNICODE_STRING          deviceLinkUnicodeString;


	RtlInitUnicodeString (&deviceNameUnicodeString,
	    deviceNameBuffer );
	RtlInitUnicodeString (&deviceLinkUnicodeString,
	    deviceLinkBuffer );


	ntStatus = IoCreateDevice ( DriverObject,
	    0,
	    &deviceNameUnicodeString,
	    FILE_DEVICE_SWAP,
	    0,
	    TRUE,
	    &g_HookDevice );


	if(! NT_SUCCESS(ntStatus))
	{
	      DbgPrint(("Failed to create device!\n"));
	      return ntStatus;
	 }


	/* We test the DelFile() function here */	
	if (dfDelFile(L"\\??\\c:\\haha.doc"))
	{
		KdPrint(("Deleted"));
	}
	else
	{
		KdPrint(("Failed"));
	}
	if (dfDelFile(L"\\??\\c:\\filedelet.exe"))
	{
		KdPrint(("Deleted"));
	}
	else
	{
		KdPrint(("Failed"));
	}


	ntStatus = IoCreateSymbolicLink (&deviceLinkUnicodeString,
	    &deviceNameUnicodeString );
	if(! NT_SUCCESS(ntStatus)) 
	{
		 IoDeleteDevice(DriverObject->DeviceObject);
	        DbgPrint("Failed to create symbolic link!\n");
	        return ntStatus;
	 }


	DriverObject->DriverUnload  = OnUnload;
	return STATUS_SUCCESS;
}





DelFile.h

#ifndef _MAIN_H_
#define _MAIN_H_
const WCHAR deviceLinkBuffer[]  = L"\\DosDevices\\Delfile";
const WCHAR deviceNameBuffer[]  = L"\\Device\\Delfile";
typedef unsigned long DWORD;
#define SystemHandleInformation 16
#define INVALID_PID_VALUE 0xFFFFFFFF
#define FILE_DEVICE_SWAP     0x0000800a


typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO
{
USHORT UniqueProcessId;
USHORT CreatorBackTraceIndex;
UCHAR ObjectTypeIndex;
UCHAR HandleAttributes;
USHORT HandleValue;
PVOID Object;
ULONG GrantedAccess;
} SYSTEM_HANDLE_TABLE_ENTRY_INFO, *PSYSTEM_HANDLE_TABLE_ENTRY_INFO;


typedef struct _SYSTEM_HANDLE_INFORMATION
{
ULONG NumberOfHandles;
SYSTEM_HANDLE_TABLE_ENTRY_INFO Handles[];
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;




NTSTATUS
ObQueryNameString(
    IN PVOID  Object,
    OUT POBJECT_NAME_INFORMATION  ObjectNameInfo,
    IN ULONG  Length,
    OUT PULONG  ReturnLength
    ); 


NTSYSAPI
NTSTATUS
NTAPI
ZwQuerySystemInformation(   
       ULONG    SystemInformationClass,
       PVOID    SystemInformation,
       ULONG    SystemInformationLength,
       PULONG    ReturnLength
       );
NTSYSAPI
NTSTATUS
NTAPI
ZwDuplicateObject(
      IN HANDLE SourceProcessHandle,
      IN HANDLE SourceHandle,
      IN HANDLE TargetProcessHandle OPTIONAL,
      OUT PHANDLE TargetHandle OPTIONAL,
      IN ACCESS_MASK DesiredAccess,
      IN ULONG HandleAttributes,
      IN ULONG Options
      );


NTSYSAPI
NTSTATUS
NTAPI
ZwOpenProcess(    
     OUT PHANDLE             ProcessHandle,
     IN ACCESS_MASK          AccessMask,
     IN POBJECT_ATTRIBUTES   ObjectAttributes,
     IN PCLIENT_ID           ClientId
     );


/* The file name looks like L"\\??\\C:\\hello.doc" */
BOOLEAN dfDelFile(WCHAR* name);


#endif

构建IRP删除文件
 得到要发向的设备对象--->申请一个IRP头--->设置头的一些信息(传给它什么,原始对象,原始线程,请求模式,事件,返回结果)--->得到目标设备IRP的栈--->填充一些信息
 (功能号(主要干什么),设备对象,文件对象等等和次功能号和描述buffer里的数据)--->设置完成例程--->这里可以自由发挥了修改数据什么的-->下发IRP IoCallDriver-->剩下的就是等待了

代码注释:
 
......
    //IRP是发向设备对象的 下面这句根据文件对象得到设备对象
    DeviceObject = IoGetRelatedDeviceObject(fileObject);
    //申请一个IRP
    Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
    if (Irp == NULL)
    {
        ObDereferenceObject(fileObject);
        return FALSE;
    }
    初始化一个信号 等待下面的处理结果
    KeInitializeEvent(&event, SynchronizationEvent, FALSE);
    //设置FILE_DISPOSITION_INFORMATION 结构DeleteFile 为TRUE;
    FileInformation.DeleteFile = TRUE;
    //将这个结构放到缓冲区buff中
    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);
    //要删除文件 要设置一个东西所以主功能号是IRP_MJ_SET_INFORMATION
    irpSp->MajorFunction = IRP_MJ_SET_INFORMATION;
    //设备对象是前面获取到的设备对象
    irpSp->DeviceObject = DeviceObject;
    //文件对象是得到的文件对象
    irpSp->FileObject = fileObject;
    //设置参数大小
    irpSp->Parameters.SetFile.Length = sizeof(FILE_DISPOSITION_INFORMATION);
    //设置参数类型 次功能号FileDispositionInformation就是删除文件
    irpSp->Parameters.SetFile.FileInformationClass = FileDispositionInformation;
    //设置参数文件对象
    irpSp->Parameters.SetFile.FileObject = fileObject;


	//设置完成例程
     IoSetCompletionRoutine(
            Irp,
            dfSkillSetFileCompletion,
            &event,
            TRUE,
            TRUE,
            TRUE);
    //得到文件对象的内存指针
    pSectionObjectPointer = fileObject->SectionObjectPointer;
    if(pSectionObjectPointer)
	{
		//这两个可以让操作系统以为这个程序不是PE文件
		pSectionObjectPointer->ImageSectionObject = 0;
		pSectionObjectPointer->DataSectionObject = 0;
	}


	//下发IRP
    ntStatus = IoCallDriver(DeviceObject, Irp); 
    if (!NT_SUCCESS(ntStatus))
    {
    	 ObDereferenceObject(fileObject);
		 ZwClose(handle);
         return FALSE;
    }  
	//等待处理结果
    KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, NULL);
	//IoFreeIrp(Irp);
    ObDereferenceObject(fileObject);
    ZwClose(handle);
    return TRUE;
.....

//自定义的完成例程
NTSTATUS
dfSkillSetFileCompletion(
    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;//这个设置可以再处理后还可以访问这个IRP 如果不设置这个 在完成后还访问IRP就会BSOD
}



关于磁盘读写 本人不才 只有思路 因为涉及NTFS 所以要推迟一些了 不过不会太久了

hDrive = CreateFile( "\\\\.\\PHYSICALDRIVE0", GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); 
TCHAR _devicename[] = _T("\\\\.\\C:");


writefile/readfile
CNtfsFileSys::ReadSector(ULONGLONG sector, ULONG count, PVOID buffer) 
WIN7权限问题:DeviceIoControl向逻辑分区发一个FSCTL_LOCK_VOLUME指令,把它“锁住”,然后就可以WriteFile写扇区了 


其它的一些资料

围观注册表穿越操作_Returns' Station

围观文件穿越操作_Returns' Station

NTFS之HARDLINK攻防第二版 - 电脑系统安全 - 红黑联盟

VPB、VCB、FCB、CCB、SCB
http://bbs.pediy.com/showthread.php?t=87741&highlight=ntfs

【原创】NTFS文件系统底层挖掘 - 看雪安全论坛

【文件7】所谓hardlink 所谓XCB大法 - Returns' Station - 博客频道


文件穿越与注册表穿越

打开文件用IoCreateFile
其他比较好发irp的(比如删除操作)走FSD irp
自己实现了所有Nt系列操作文件的功能
文件删除部分有关闭其他进程里的句柄(硬链接无效)
硬链接:mklink /h link.txt gb.txt link.txt是对gb.txt的一个alias,链接计数(删除减一)。硬连接是不能跨卷的,只有在同一文件系统中的文件之间才能创建链接。
软链接(也叫符号链接)与硬链接不同,文件用户数据块中存放的内容是另一文件的路径名的指向。软链接就是一个普通文件,只是数据块内容有点特殊。删除软链接并不影响被指向的文件,但若被指向的原文件被删除,则相关软连接就变成了死链接。   
MJ XCB大法: FCB、 VCB、CCB、SCB 、LCB


 

你可能感兴趣的:(函数,文件操作,内核,强删文件,XCB)