NTSTATUS IrpCreateFile(
OUT PFILE_OBJECT *ppFileObject,
IN ACCESS_MASK DesiredAccess,
IN PUNICODE_STRING pustrFilePath,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PLARGE_INTEGER AllocationSize OPTIONAL,
IN ULONG FileAttributes,
IN ULONG ShareAccess,
IN ULONG CreateDisposition,
IN ULONG CreateOptions,
IN PVOID EaBuffer OPTIONAL,
IN ULONG EaLength)
{
NTSTATUS status = STATUS_SUCCESS;
ULONG ulFileNameMaxSize = 512;
WCHAR wszName[100] = { 0 };
UNICODE_STRING ustrRootPath;
OBJECT_ATTRIBUTES objectAttributes = { 0 };
HANDLE hRootFile = NULL;
PFILE_OBJECT pRootFileObject = NULL, pFileObject = NULL;
PDEVICE_OBJECT RootDeviceObject = NULL, RootRealDevice = NULL;
PIRP pIrp = NULL;
KEVENT kEvent = { 0 };
ACCESS_STATE accessData = { 0 };
AUX_ACCESS_DATA auxAccessData = { 0 };
IO_SECURITY_CONTEXT ioSecurityContext = { 0 };
PIO_STACK_LOCATION pIoStackLocation = NULL;
// 打开磁盘根目录并获取句柄
wcscpy(wszName, L"\\??\\A:\\");
wszName[4] = pustrFilePath->Buffer[0];
RtlInitUnicodeString(&ustrRootPath, wszName);
DbgPrint("RootPath:%wZ\n", &ustrRootPath);
InitializeObjectAttributes(&objectAttributes, &ustrRootPath, OBJ_KERNEL_HANDLE, NULL, NULL);
status = IoCreateFile(&hRootFile, GENERIC_READ | SYNCHRONIZE,
&objectAttributes, IoStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0, CreateFileTypeNone,
NULL, IO_NO_PARAMETER_CHECKING);
if (!NT_SUCCESS(status))
{
DbgPrint("IoCreateFile Error[0x%X]", status);
return status;
}
// 获取磁盘根目录文件对象
status = ObReferenceObjectByHandle(hRootFile, FILE_READ_ACCESS, *IoFileObjectType, KernelMode, &pRootFileObject, NULL);
if (!NT_SUCCESS(status))
{
ZwClose(hRootFile);
DbgPrint("ObReferenceObjectByHandle Error[0x%X]\n", status);
return status;
}
// 获取磁盘根目录设备对象
RootDeviceObject = pRootFileObject->Vpb->DeviceObject;
RootRealDevice = pRootFileObject->Vpb->RealDevice;
// 关闭磁盘根目录句柄和对象
ObDereferenceObject(pRootFileObject);
ZwClose(hRootFile);
// 创建IRP
pIrp = IoAllocateIrp(RootDeviceObject->StackSize, FALSE);
if (NULL == pIrp)
{
ObDereferenceObject(pFileObject);
DbgPrint("IoAllocateIrp Error!\n");
return STATUS_UNSUCCESSFUL;
}
// 创建事件
KeInitializeEvent(&kEvent, SynchronizationEvent, FALSE);
// 创建空文件对象
InitializeObjectAttributes(&objectAttributes, NULL, OBJ_CASE_INSENSITIVE, NULL, NULL);
status = ObCreateObject(KernelMode, *IoFileObjectType, &objectAttributes, KernelMode, NULL, sizeof(FILE_OBJECT), 0, 0, &pFileObject);
if (!NT_SUCCESS(status))
{
DbgPrint("ObCreateObject Error[0x%X]\n", status);
return status;
}
// 设置创建的文件对象 FILE_OBJECT
RtlZeroMemory(pFileObject, sizeof(FILE_OBJECT));
pFileObject->Type = IO_TYPE_FILE;
pFileObject->Size = sizeof(FILE_OBJECT);
pFileObject->DeviceObject = RootRealDevice;
pFileObject->Flags = FO_SYNCHRONOUS_IO;
// FILE_OBJECT中的FileName最好动态创建, 否则ObDereferenceObject文件句柄的时候会蓝屏
pFileObject->FileName.Buffer = (PWCHAR)ExAllocatePool(NonPagedPool, ulFileNameMaxSize);
pFileObject->FileName.MaximumLength = (USHORT)ulFileNameMaxSize;
pFileObject->FileName.Length = pustrFilePath->Length - 4;
RtlZeroMemory(pFileObject->FileName.Buffer, ulFileNameMaxSize);
RtlCopyMemory(pFileObject->FileName.Buffer, &pustrFilePath->Buffer[2], pFileObject->FileName.Length);
DbgPrint("pFileObject->FileName:%wZ\n", &pFileObject->FileName);
KeInitializeEvent(&pFileObject->Lock, SynchronizationEvent, FALSE);
KeInitializeEvent(&pFileObject->Event, NotificationEvent, FALSE);
// 创建权限状态
RtlZeroMemory(&auxAccessData, sizeof(auxAccessData));
status = SeCreateAccessState(&accessData, &auxAccessData, DesiredAccess, IoGetFileObjectGenericMapping());
if (!NT_SUCCESS(status))
{
IoFreeIrp(pIrp);
ObDereferenceObject(pFileObject);
DbgPrint("SeCreateAccessState Error[0x%X]\n", status);
return status;
}
// 设置安全内容 IO_SECURITY_CONTEXT
ioSecurityContext.SecurityQos = NULL;
ioSecurityContext.AccessState = &accessData;
ioSecurityContext.DesiredAccess = DesiredAccess;
ioSecurityContext.FullCreateOptions = 0;
// 设置IRP
RtlZeroMemory(IoStatusBlock, sizeof(IO_STATUS_BLOCK));
pIrp->MdlAddress = NULL;
pIrp->AssociatedIrp.SystemBuffer = EaBuffer;
pIrp->Flags = IRP_CREATE_OPERATION | IRP_SYNCHRONOUS_API;
pIrp->RequestorMode = KernelMode;
pIrp->UserIosb = IoStatusBlock;
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 = pFileObject;
// 获取下一个IRP的IO_STACK_LOCATION并设置
pIoStackLocation = IoGetNextIrpStackLocation(pIrp);
pIoStackLocation->MajorFunction = IRP_MJ_CREATE;
pIoStackLocation->DeviceObject = RootDeviceObject;
pIoStackLocation->FileObject = pFileObject;
pIoStackLocation->Parameters.Create.SecurityContext = &ioSecurityContext;
pIoStackLocation->Parameters.Create.Options = (CreateDisposition << 24) | CreateOptions;
pIoStackLocation->Parameters.Create.FileAttributes = (USHORT)FileAttributes;
pIoStackLocation->Parameters.Create.ShareAccess = (USHORT)ShareAccess;
pIoStackLocation->Parameters.Create.EaLength = EaLength;
// 设置完成实例, 以便通知IRP处理完成, 释放资源
IoSetCompletionRoutine(pIrp, MyCompleteRoutine, NULL, TRUE, TRUE, TRUE);
// 发送IRP
status = IoCallDriver(RootDeviceObject, pIrp);
// 等待IRP的处理
if (STATUS_PENDING == status)
{
KeWaitForSingleObject(&kEvent, Executive, KernelMode, TRUE, NULL);
}
// 判断IRP处理结果
status = IoStatusBlock->Status;
if (!NT_SUCCESS(status))
{
ObDereferenceObject(pFileObject);
DbgPrint("IRP FAILED!\n");
return status;
}
InterlockedIncrement(&pFileObject->DeviceObject->ReferenceCount);
if (pFileObject->Vpb)
{
InterlockedIncrement(&pFileObject->Vpb->ReferenceCount);
}
// 返回文件对象
*ppFileObject = pFileObject;
return status;
}
IRP管理文件
最新推荐文章于 2021-01-10 23:03:07 发布