您的位置:首页 > 其它

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

2016-04-03 01:39 375 查看
个人比较崇拜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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: