Irp操作出自125096的博客
http://blog.csdn.net/qq125096885/article/details/53033896
这里提下 博主的例子中使用irpclose文件对象,这可能会造成蓝屏。
见链接:https://bbs.pediy.com/thread-215269.htm
所以这里把IrpCloseFile改为ObDereferenceObject即可
但是如果是需要实现无法删除,那么就不需要调用ObDereferenceObject
原因你猜~
此方法使用Irp去删除是无法删除的~
见代码~
#include <ntddk.h>
#ifndef MAX_PATH
#define MAX_PATH 260
#endif
NTSTATUS ObOpenObjectByPointer(PVOID Object, ULONG HandleAttributes, PACCESS_STATE PassedAccessState, ACCESS_MASK DesiredAccess, POBJECT_TYPE ObjectType, KPROCESSOR_MODE AccessMode, PHANDLE Handle);
NTSTATUS ObCreateObject(KPROCESSOR_MODE ProbeMode, POBJECT_TYPE ObjectType, POBJECT_ATTRIBUTES ObjectAttributes, KPROCESSOR_MODE OwnershipMode, PVOID ParseContext, ULONG ObjectBodySize, ULONG PagedPoolCharge, ULONG NonPagedPoolCharge, PVOID *Object);
NTSTATUS SeCreateAccessState(PACCESS_STATE AccessState, PVOID AuxData, ACCESS_MASK DesiredAccess, PGENERIC_MAPPING GenericMapping);
typedef struct _AUX_ACCESS_DATA {
PPRIVILEGE_SET PrivilegesUsed;
GENERIC_MAPPING GenericMapping;
ACCESS_MASK AccessesToAudit;
ACCESS_MASK MaximumAuditMask;
ULONG Unknown[256];
} AUX_ACCESS_DATA, *PAUX_ACCESS_DATA;
//获取设备对象
NTSTATUS GetDriveObject(PUNICODE_STRING pDriveName, PDEVICE_OBJECT *DeviceObject, PDEVICE_OBJECT *ReadDevice);
//IRP打开文件
NTSTATUS IrpCreateFile(PUNICODE_STRING pFilePath, ACCESS_MASK DesiredAccess, PIO_STATUS_BLOCK pIoStatusBlock, PFILE_OBJECT *pFileObject);
VOID DriverUnload(IN PDRIVER_OBJECT DriverObject)
{
return;
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
NTSTATUS status;
DriverObject->DriverUnload = DriverUnload;
UNICODE_STRING strFilePath;
IO_STATUS_BLOCK IoStatusBlock = { 0 };
PFILE_OBJECT pFileObject = NULL;
RtlInitUnicodeString(&strFilePath, L"\\??\\c:\\test.exe");
//打开文件
status = IrpCreateFile(&strFilePath, GENERIC_READ | DELETE, &IoStatusBlock, &pFileObject);
if (NT_SUCCESS(status))
{
//关闭文件 发irp close会触发内存重复释放 应使用ObDereferenceObject
// 如果不ObDereferenceObject 除关机.磁盘填0(怎么获取偏移是一个问题~)之外 无法删除文件
// ObDereferenceObject(pFileObject);
}
return STATUS_SUCCESS;
}
//完成历程
NTSTATUS IoCompletionRoutineEx(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
{
*Irp->UserIosb = Irp->IoStatus;
if (Irp->UserEvent)
KeSetEvent(Irp->UserEvent, IO_NO_INCREMENT, 0);
if (Irp->MdlAddress)
{
IoFreeMdl(Irp->MdlAddress);
Irp->MdlAddress = NULL;
}
IoFreeIrp(Irp);
return STATUS_MORE_PROCESSING_REQUIRED;
}
//获取设备对象
NTSTATUS GetDriveObject(PUNICODE_STRING pDriveName, PDEVICE_OBJECT *DeviceObject, PDEVICE_OBJECT *ReadDevice)
{
//定义变量
NTSTATUS status;
OBJECT_ATTRIBUTES objectAttributes;
HANDLE DeviceHandle = NULL;
IO_STATUS_BLOCK ioStatus;
PFILE_OBJECT pFileObject;
//参数效验
if (pDriveName == NULL || DeviceObject == NULL || ReadDevice == NULL)return STATUS_INVALID_PARAMETER;
// \\??\\C:
//打开设备
InitializeObjectAttributes(&objectAttributes, pDriveName, OBJ_CASE_INSENSITIVE, NULL, NULL);
status = IoCreateFile(&DeviceHandle, SYNCHRONIZE | FILE_ANY_ACCESS, &objectAttributes, &ioStatus, NULL, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT | FILE_DIRECTORY_FILE, NULL, 0, CreateFileTypeNone, NULL, IO_NO_PARAMETER_CHECKING);
if (!NT_SUCCESS(status))return status;
//获取文件对象
status = ObReferenceObjectByHandle(DeviceHandle, FILE_READ_DATA, *IoFileObjectType, KernelMode, &pFileObject, NULL);
if (!NT_SUCCESS(status))
{
ZwClose(DeviceHandle);
return status;
}
//效验结果
if (pFileObject->Vpb == 0 || pFileObject->Vpb->RealDevice == NULL)
{
ObDereferenceObject(pFileObject);
ZwClose(DeviceHandle);
return STATUS_UNSUCCESSFUL;
}
//设置变量
*DeviceObject = pFileObject->Vpb->DeviceObject;
*ReadDevice = pFileObject->Vpb->RealDevice;
ObDereferenceObject(pFileObject);
ZwClose(DeviceHandle);
return STATUS_SUCCESS;
}
//IRP打开文件
NTSTATUS IrpCreateFile(PUNICODE_STRING pFilePath, ACCESS_MASK DesiredAccess, PIO_STATUS_BLOCK pIoStatusBlock, PFILE_OBJECT *pFileObject)
{
NTSTATUS ntStatus;
PIRP pIrp;
KEVENT kEvent;
static ACCESS_STATE AccessState;
static AUX_ACCESS_DATA AuxData;
OBJECT_ATTRIBUTES ObjectAttributes;
PFILE_OBJECT pNewFileObject;
IO_SECURITY_CONTEXT SecurityContext;
PIO_STACK_LOCATION IrpSp;
PDEVICE_OBJECT pDeviceObject = NULL;
PDEVICE_OBJECT pReadDevice = NULL;
UNICODE_STRING DriveName;
wchar_t* pFileNameBuf = NULL;
static wchar_t szFilePath[MAX_PATH] = { 0 };
#define SYMBOLICLINKLENG 6 // \\??\\c: \\windows\\notepad.exe
if (pFilePath == NULL || pIoStatusBlock == NULL || pFileObject == NULL || pFilePath->Length <= SYMBOLICLINKLENG)return STATUS_INVALID_PARAMETER;
RtlZeroMemory(szFilePath, sizeof(szFilePath));
RtlCopyMemory(szFilePath, pFilePath->Buffer, (SYMBOLICLINKLENG + 1) * sizeof(wchar_t));
RtlInitUnicodeString(&DriveName, szFilePath);
ntStatus = GetDriveObject(&DriveName, &pDeviceObject, &pReadDevice);
if (!NT_SUCCESS(ntStatus))return ntStatus;
RtlZeroMemory(szFilePath, sizeof(szFilePath));
RtlCopyMemory(szFilePath, &pFilePath->Buffer[SYMBOLICLINKLENG], pFilePath->Length - SYMBOLICLINKLENG);
RtlInitUnicodeString(&DriveName, szFilePath);
pFileNameBuf = ExAllocatePool(NonPagedPool, DriveName.MaximumLength);
if (pFileNameBuf == NULL)return STATUS_UNSUCCESSFUL;
RtlZeroMemory(pFileNameBuf, DriveName.MaximumLength);
RtlCopyMemory(pFileNameBuf, DriveName.Buffer, DriveName.Length);
if (pDeviceObject == NULL || pReadDevice == NULL || pDeviceObject->StackSize <= 0)return STATUS_UNSUCCESSFUL;
InitializeObjectAttributes(&ObjectAttributes, NULL, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, 0, NULL);
ntStatus = ObCreateObject(KernelMode, *IoFileObjectType, &ObjectAttributes, KernelMode, NULL, sizeof(FILE_OBJECT), 0, 0, &pNewFileObject);
if (!NT_SUCCESS(ntStatus))return ntStatus;
pIrp = IoAllocateIrp(pDeviceObject->StackSize, FALSE);
if (pIrp == NULL)
{
ObDereferenceObject(pNewFileObject);
return STATUS_INSUFFICIENT_RESOURCES;
}
KeInitializeEvent(&kEvent, SynchronizationEvent, FALSE);
RtlZeroMemory(pNewFileObject, sizeof(FILE_OBJECT));
pNewFileObject->Type = IO_TYPE_FILE;
pNewFileObject->Size = sizeof(FILE_OBJECT);
pNewFileObject->DeviceObject = pReadDevice;
pNewFileObject->Flags = FO_SYNCHRONOUS_IO;
RtlInitUnicodeString(&pNewFileObject->FileName, pFileNameBuf);
KeInitializeEvent(&pNewFileObject->Lock, SynchronizationEvent, FALSE);
KeInitializeEvent(&pNewFileObject->Event, NotificationEvent, FALSE);
ntStatus = SeCreateAccessState(&AccessState, &AuxData, DesiredAccess, IoGetFileObjectGenericMapping());
if (!NT_SUCCESS(ntStatus))
{
IoFreeIrp(pIrp);
ObDereferenceObject(pNewFileObject);
return ntStatus;
}
SecurityContext.SecurityQos = NULL;
SecurityContext.AccessState = &AccessState;
SecurityContext.DesiredAccess = DesiredAccess;
SecurityContext.FullCreateOptions = 0;
pIrp->MdlAddress = NULL;
pIrp->AssociatedIrp.SystemBuffer = NULL;
pIrp->Flags = IRP_CREATE_OPERATION | IRP_SYNCHRONOUS_API;
pIrp->RequestorMode = KernelMode;
pIrp->UserIosb = pIoStatusBlock;
pIrp->UserEvent = &kEvent;
pIrp->PendingReturned = FALSE;
pIrp->Cancel = FALSE;
pIrp->CancelRoutine = NULL;
pIrp->Tail.Overlay.Thread = PsGetCurrentThread();
pIrp->Tail.Overlay.AuxiliaryBuffer = NULL;
pIrp->Tail.Overlay.OriginalFileObject = pNewFileObject;
IrpSp = IoGetNextIrpStackLocation(pIrp);
IrpSp->MajorFunction = IRP_MJ_CREATE;
IrpSp->DeviceObject = pDeviceObject;
IrpSp->FileObject = pNewFileObject;
IrpSp->Parameters.Create.SecurityContext = &SecurityContext;
IrpSp->Parameters.Create.Options = (FILE_OPEN_IF << 24) | 0;
IrpSp->Parameters.Create.FileAttributes = FILE_ATTRIBUTE_NORMAL;
IrpSp->Parameters.Create.ShareAccess = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
IrpSp->Parameters.Create.EaLength = 0;
IoSetCompletionRoutine(pIrp, IoCompletionRoutineEx, 0, TRUE, TRUE, TRUE);
ntStatus = IoCallDriver(pDeviceObject, pIrp);
if (ntStatus == STATUS_PENDING)
KeWaitForSingleObject(&kEvent, Executive, KernelMode, TRUE, 0);
ntStatus = pIoStatusBlock->Status;
if (!NT_SUCCESS(ntStatus))
{
pNewFileObject->DeviceObject = NULL;
ObDereferenceObject(pNewFileObject);
}
else
{
InterlockedIncrement(&pNewFileObject->DeviceObject->ReferenceCount);
if (pNewFileObject->Vpb)
InterlockedIncrement(&pNewFileObject->Vpb->ReferenceCount);
*pFileObject = pNewFileObject;
//ObDereferenceObject(pNewFileObject);
}
return ntStatus;
}
删除的思路
1.找到这个FileObject ObDereferenceObject~
2.找跟句柄、对象无关的删除方法~