版权声明:本文为博主原创文章,未经博主允许不得转载。
- #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 IrpDeleteFileForce(PFILE_OBJECT pFileObject);
- //IRP删除文件
- NTSTATUS IrpDeleteFileEx(PFILE_OBJECT pFileObject);
- //IRP删除文件
- NTSTATUS IrpDeleteFile(PFILE_OBJECT pFileObject);
- //删除文件
- NTSTATUS ZwDeleteFile(PFILE_OBJECT pFileObject);
- //复制文件
- NTSTATUS CopyFileEx(PUNICODE_STRING lpExistingFileName, PUNICODE_STRING lpNewFileName);
- //IRP设置文件
- NTSTATUS irpSetFileAttributes(PFILE_OBJECT pFileObject, PIO_STATUS_BLOCK pIoStatusBlock,PVOID FileInformation,ULONG Length,FILE_INFORMATION_CLASS FileInformationClass,BOOLEAN ReplaceIfExists);
- //IRP打开文件
- NTSTATUS IrpCreateFile(PUNICODE_STRING pFilePath, ACCESS_MASK DesiredAccess, PIO_STATUS_BLOCK pIoStatusBlock, PFILE_OBJECT *pFileObject);
- //IRP读取文件
- NTSTATUS IrpReadFile(PFILE_OBJECT pFileObject, PLARGE_INTEGER pByteOffset, ULONG Length, PVOID pBuffer, PIO_STATUS_BLOCK pIoStatusBlock);
- //IRP写文件
- NTSTATUS IrpFileWrite(PFILE_OBJECT pFileObject, PLARGE_INTEGER ByteOffset, ULONG Length, PVOID Buffer, PIO_STATUS_BLOCK pIoStatusBlock);
- //IRP关闭文件
- NTSTATUS IrpClose(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;
- DbgBreakPoint();
- UNICODE_STRING strFilePath;
- IO_STATUS_BLOCK IoStatusBlock = {0};
- PFILE_OBJECT pFileObject = NULL;
- RtlInitUnicodeString(&strFilePath, L"\\??\\c:\\MyDriver1.sys");
- //打开文件
- status=IrpCreateFile(&strFilePath, DELETE, &IoStatusBlock, &pFileObject);
- if (NT_SUCCESS(status))
- {
- //删除文件
- //status=ZwDeleteFile(pFileObject);
- //status = IrpDeleteFile(pFileObject);
- //status=IrpDeleteFileForce(pFileObject);
- //KdPrint(("OK\n"));
- //status=IrpDeleteFileForce(pFileObject);
- //关闭文件
- status=IrpClose(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;
- }
- //IRP写文件
- NTSTATUS IrpFileWrite(PFILE_OBJECT pFileObject, PLARGE_INTEGER ByteOffset, ULONG Length, PVOID Buffer, PIO_STATUS_BLOCK pIoStatusBlock)
- {
- //定义变量
- NTSTATUS status;
- KEVENT event;
- PIRP irp;
- PIO_STACK_LOCATION irpSp;
- PDEVICE_OBJECT deviceObject;
- //参数效验
- if (pIoStatusBlock == NULL || pFileObject == NULL || Length <= 0 || Buffer == NULL)return STATUS_INVALID_PARAMETER;
- //参数效验
- if (ByteOffset == NULL)
- {
- if (!(pFileObject->Flags & FO_SYNCHRONOUS_IO))
- return STATUS_INVALID_PARAMETER;
- ByteOffset = &pFileObject->CurrentByteOffset;
- }
- //获取原始设备对象
- deviceObject = IoGetRelatedDeviceObject(pFileObject);
- if (deviceObject == NULL || deviceObject->StackSize <= 0)return STATUS_UNSUCCESSFUL;
- //分配IRP
- irp = IoAllocateIrp(deviceObject->StackSize, FALSE);
- if (irp == NULL)return STATUS_INSUFFICIENT_RESOURCES;
- //分配MDL缓冲区
- irp->MdlAddress = IoAllocateMdl(Buffer, Length, FALSE, FALSE, NULL);
- if (irp->MdlAddress == NULL)
- {
- IoFreeIrp(irp);
- return STATUS_INSUFFICIENT_RESOURCES;;
- }
- //更新MDL
- MmBuildMdlForNonPagedPool(irp->MdlAddress);
- //设置变量
- irp->Flags = IRP_WRITE_OPERATION; //IRP写操作
- irp->RequestorMode = KernelMode;
- irp->UserIosb = pIoStatusBlock;
- irp->UserEvent = &event;
- irp->Tail.Overlay.Thread = (PETHREAD)KeGetCurrentThread();
- irp->Tail.Overlay.OriginalFileObject = pFileObject;
- irpSp = IoGetNextIrpStackLocation(irp);
- irpSp->MajorFunction = IRP_MJ_WRITE;
- irpSp->MinorFunction = IRP_MN_NORMAL;
- irpSp->DeviceObject = deviceObject;
- irpSp->FileObject = pFileObject;
- irpSp->Parameters.Write.Length = Length;
- irpSp->Parameters.Write.ByteOffset = *ByteOffset;
- KeInitializeEvent(&event, SynchronizationEvent, FALSE);
- IoSetCompletionRoutine(irp, IoCompletionRoutineEx, NULL, TRUE, TRUE, TRUE);
- status = IoCallDriver(deviceObject, irp);
- if (status == STATUS_PENDING)
- status = KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, NULL);
- status = pIoStatusBlock->Status;
- #ifdef DBG
- KdPrint(("写入文件长度%d 文件状态%d\n", pIoStatusBlock->Information, pIoStatusBlock->Status));
- #endif
- return status;
- }
- //IRP删除文件
- NTSTATUS IrpDeleteFileEx(PFILE_OBJECT pFileObject)
- {
- //定义变量
- NTSTATUS status;
- PIRP pIrp;
- PIO_STACK_LOCATION irpSp;
- PDEVICE_OBJECT DeviceObject;
- IO_STATUS_BLOCK IoStatusBlock;
- KEVENT SycEvent;
- PSECTION_OBJECT_POINTERS pSectionObjectPointer;
- FILE_DISPOSITION_INFORMATION FileInformationDelete;
- static FILE_BASIC_INFORMATION FileInformationAttribute;
- //参数效验
- if (pFileObject == NULL)return STATUS_INVALID_PARAMETER;
- //设置文件属性
- memset(&FileInformationAttribute, 0, sizeof(FILE_BASIC_INFORMATION));
- FileInformationAttribute.FileAttributes = FILE_ATTRIBUTE_NORMAL;
- status = irpSetFileAttributes(pFileObject, &IoStatusBlock, &FileInformationAttribute, sizeof(FILE_BASIC_INFORMATION), FileBasicInformation, TRUE);
- if (!NT_SUCCESS(status))return status;
- //获取原始设备对象
- DeviceObject = IoGetRelatedDeviceObject(pFileObject);
- if (DeviceObject == NULL || DeviceObject->StackSize <= 0)return STATUS_UNSUCCESSFUL;
- // 创建IRP
- pIrp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
- if (pIrp == NULL)
- {
- //ObDereferenceObject(pFileObject);
- return STATUS_UNSUCCESSFUL;
- }
- //初始化同步事件对象
- KeInitializeEvent(&SycEvent, SynchronizationEvent, FALSE);
- //设置变量
- FileInformationDelete.DeleteFile = TRUE;
- //初始化IRP
- pIrp->AssociatedIrp.SystemBuffer = &FileInformationDelete;
- pIrp->UserEvent = &SycEvent;
- pIrp->UserIosb = &IoStatusBlock;
- pIrp->Tail.Overlay.OriginalFileObject = pFileObject;
- pIrp->Tail.Overlay.Thread = (PETHREAD)KeGetCurrentThread();
- pIrp->RequestorMode = KernelMode;
- // 设置IRP堆栈
- irpSp = IoGetNextIrpStackLocation(pIrp);
- irpSp->MajorFunction = IRP_MJ_SET_INFORMATION;
- irpSp->DeviceObject = DeviceObject;
- irpSp->FileObject = pFileObject;
- irpSp->Parameters.SetFile.Length = sizeof(FILE_DISPOSITION_INFORMATION);
- irpSp->Parameters.SetFile.FileInformationClass = FileDispositionInformation;
- irpSp->Parameters.SetFile.FileObject = pFileObject;
- // 设置完成例程
- IoSetCompletionRoutine(pIrp, IoCompletionRoutineEx, NULL, TRUE, TRUE, TRUE);
- //如果没有这3行,就无法删除正在运行的文件
- pSectionObjectPointer = pFileObject->SectionObjectPointer;
- pSectionObjectPointer->ImageSectionObject = 0;
- pSectionObjectPointer->DataSectionObject = 0;
- // 派发IRP
- status=IoCallDriver(DeviceObject, pIrp);
- if (status == STATUS_PENDING)
- KeWaitForSingleObject(&SycEvent, Executive, KernelMode, TRUE, NULL);
- status = IoStatusBlock.Status;
- // 递减引用计数
- //ObDereferenceObject(pFileObject);
- return status;
- }
- //IRP删除文件
- NTSTATUS IrpDeleteFileForce(PFILE_OBJECT pFileObject)
- {
- //定义变量
- NTSTATUS status;
- PIRP pIrp;
- PIO_STACK_LOCATION irpSp;
- PDEVICE_OBJECT DeviceObject;
- IO_STATUS_BLOCK IoStatusBlock;
- KEVENT SycEvent;
- PVOID pImageSectionObject = NULL;
- PVOID pDataSectionObject = NULL;
- PVOID pSharedCacheMap = NULL;
- PSECTION_OBJECT_POINTERS pSectionObjectPointer;
- FILE_DISPOSITION_INFORMATION FileInformationDelete;
- static FILE_BASIC_INFORMATION FileInformationAttribute;
- //参数效验
- if (pFileObject == NULL)return STATUS_INVALID_PARAMETER;
- //设置文件属性
- memset(&FileInformationAttribute, 0, sizeof(FILE_BASIC_INFORMATION));
- FileInformationAttribute.FileAttributes = FILE_ATTRIBUTE_NORMAL;
- status = irpSetFileAttributes(pFileObject, &IoStatusBlock, &FileInformationAttribute, sizeof(FILE_BASIC_INFORMATION), FileBasicInformation, TRUE);
- if (!NT_SUCCESS(status))return status;
- //获取原始设备对象
- DeviceObject = IoGetRelatedDeviceObject(pFileObject);
- if (DeviceObject == NULL || DeviceObject->StackSize <= 0)return STATUS_UNSUCCESSFUL;
- // 创建IRP
- pIrp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
- if (pIrp == NULL)return STATUS_UNSUCCESSFUL;
- //初始化同步事件对象
- KeInitializeEvent(&SycEvent, SynchronizationEvent, FALSE);
- //设置变量
- FileInformationDelete.DeleteFile = TRUE;
- //初始化IRP
- pIrp->AssociatedIrp.SystemBuffer = &FileInformationDelete;
- pIrp->UserEvent = &SycEvent;
- pIrp->UserIosb = &IoStatusBlock;
- pIrp->Tail.Overlay.OriginalFileObject = pFileObject;
- pIrp->Tail.Overlay.Thread = (PETHREAD)KeGetCurrentThread();
- pIrp->RequestorMode = KernelMode;
- // 设置IRP堆栈
- irpSp = IoGetNextIrpStackLocation(pIrp);
- irpSp->MajorFunction = IRP_MJ_SET_INFORMATION;
- irpSp->DeviceObject = DeviceObject;
- irpSp->FileObject = pFileObject;
- irpSp->Parameters.SetFile.Length = sizeof(FILE_DISPOSITION_INFORMATION);
- irpSp->Parameters.SetFile.FileInformationClass = FileDispositionInformation;
- irpSp->Parameters.SetFile.FileObject = pFileObject;
- // 设置完成例程
- IoSetCompletionRoutine(pIrp, IoCompletionRoutineEx, NULL, TRUE, TRUE, TRUE);
- //设置变量
- if (pFileObject->SectionObjectPointer)
- {
- //一个空值表明,可执行图像目前不在内存中
- //一个空值表示数据流当前不在内存中
- //空值的数据流是
- pImageSectionObject = pFileObject->SectionObjectPointer->ImageSectionObject;
- pDataSectionObject = pFileObject->SectionObjectPointer->DataSectionObject;
- pSharedCacheMap = pFileObject->SectionObjectPointer->SharedCacheMap;
- pFileObject->SectionObjectPointer->ImageSectionObject = NULL;
- pFileObject->SectionObjectPointer->DataSectionObject = NULL;
- pFileObject->SectionObjectPointer->SharedCacheMap = NULL;
- }
- // 派发IRP
- status = IoCallDriver(DeviceObject, pIrp);
- if (status == STATUS_PENDING)
- KeWaitForSingleObject(&SycEvent, Executive, KernelMode, TRUE, NULL);
- status = IoStatusBlock.Status;
- //还原变量
- if (pFileObject->SectionObjectPointer)
- {
- pFileObject->SectionObjectPointer->ImageSectionObject = pImageSectionObject;
- pFileObject->SectionObjectPointer->DataSectionObject = pDataSectionObject;
- pFileObject->SectionObjectPointer->SharedCacheMap = pSharedCacheMap;
- }
- return status;
- }
- //IRP删除文件
- NTSTATUS IrpDeleteFile(PFILE_OBJECT pFileObject)
- {
- //定义变量
- NTSTATUS ntStatus = STATUS_SUCCESS;
- PDEVICE_OBJECT DeviceObject;
- PIRP pIrp;
- KEVENT SycEvent;
- FILE_DISPOSITION_INFORMATION FileInformation;
- IO_STATUS_BLOCK ioStatus;
- PIO_STACK_LOCATION irpSp;
- //参数效验
- if (pFileObject == NULL)return STATUS_INVALID_PARAMETER;
- //获取原始设备对象
- DeviceObject = IoGetRelatedDeviceObject(pFileObject);
- if (DeviceObject == NULL || DeviceObject->StackSize <= 0)return STATUS_UNSUCCESSFUL;
- //分配IRP
- pIrp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
- if (pIrp == NULL)
- {
- //ObDereferenceObject(pFileObject);
- return ntStatus;
- }
- // 初始化同步事件对象
- KeInitializeEvent(&SycEvent, SynchronizationEvent, FALSE);
- //指示操作系统文件是否应在关闭该文件时删除该文件。将此成员设置为在关闭时删除该文件
- FileInformation.DeleteFile = TRUE;
- // 初始化IRP
- pIrp->AssociatedIrp.SystemBuffer = &FileInformation;
- pIrp->UserEvent = &SycEvent;
- pIrp->UserIosb = &ioStatus;
- pIrp->Tail.Overlay.OriginalFileObject = pFileObject;
- pIrp->Tail.Overlay.Thread = (PETHREAD)KeGetCurrentThread();
- pIrp->RequestorMode = KernelMode;
- // 设置IRP堆栈
- irpSp = IoGetNextIrpStackLocation(pIrp);
- irpSp->MajorFunction = IRP_MJ_SET_INFORMATION;
- irpSp->DeviceObject = DeviceObject;
- irpSp->FileObject = pFileObject;
- irpSp->Parameters.SetFile.Length = sizeof(FILE_DISPOSITION_INFORMATION);
- irpSp->Parameters.SetFile.FileInformationClass = FileDispositionInformation;
- irpSp->Parameters.SetFile.FileObject = pFileObject;
- IoSetCompletionRoutine(pIrp, IoCompletionRoutineEx, NULL, TRUE, TRUE, TRUE);
- // 派发IRP
- ntStatus = IoCallDriver(DeviceObject, pIrp);
- if (ntStatus == STATUS_PENDING)
- KeWaitForSingleObject(&SycEvent, Executive, KernelMode, TRUE, 0);
- ntStatus = ioStatus.Status;
- return ntStatus;
- }
- //删除文件
- NTSTATUS ZwDeleteFile(PFILE_OBJECT pFileObject)
- {
- //定义变量
- PDEVICE_OBJECT DeviceObject;
- HANDLE FileHandle;
- NTSTATUS ntStatus;
- IO_STATUS_BLOCK ioStatus;
- FILE_DISPOSITION_INFORMATION FileInformation;
- //参数效验
- if (pFileObject == NULL)return STATUS_INVALID_PARAMETER;
- // 获取文件句柄
- ntStatus = ObOpenObjectByPointer(pFileObject,0,NULL,DELETE,*IoFileObjectType,KernelMode,&FileHandle);
- if (!NT_SUCCESS(ntStatus))return ntStatus;
- ObDereferenceObject(pFileObject);
- FileInformation.DeleteFile = TRUE;
- ntStatus=ZwSetInformationFile(FileHandle, &ioStatus, &FileInformation, sizeof(FILE_DISPOSITION_INFORMATION), FileDispositionInformation);
- return ntStatus;
- }
- //IRP设置文件
- NTSTATUS irpSetFileAttributes(PFILE_OBJECT pFileObject, PIO_STATUS_BLOCK pIoStatusBlock, PVOID pFileInformation, ULONG FileInformationLength, FILE_INFORMATION_CLASS FileInformationClass, BOOLEAN ReplaceIfExists)
- {
- //定义变量
- NTSTATUS ntStatus = STATUS_SUCCESS;
- PDEVICE_OBJECT DeviceObject;
- PIRP Irp;
- KEVENT SycEvent;
- PIO_STACK_LOCATION irpSp;
- //参数效验
- if (pFileObject == NULL || pIoStatusBlock==NULL || pFileInformation ==NULL|| FileInformationLength <=0)return STATUS_INVALID_PARAMETER;
- //获取原始设备对象
- DeviceObject = IoGetRelatedDeviceObject(pFileObject);
- if (DeviceObject == NULL || DeviceObject->StackSize <= 0)return STATUS_UNSUCCESSFUL;
- // 创建IRP
- Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
- if (Irp == NULL)
- {
- //ObDereferenceObject(pFileObject);
- return STATUS_UNSUCCESSFUL;
- }
- // 初始化同步事件对象
- KeInitializeEvent(&SycEvent, SynchronizationEvent, FALSE);
- // 初始化IRP
- Irp->AssociatedIrp.SystemBuffer = pFileInformation; //设置属性
- Irp->UserEvent = &SycEvent;
- Irp->UserIosb = pIoStatusBlock;
- Irp->Tail.Overlay.OriginalFileObject = pFileObject;
- Irp->Tail.Overlay.Thread = (PETHREAD)KeGetCurrentThread();
- Irp->RequestorMode = KernelMode;
- // 设置IRP堆栈信息
- irpSp = IoGetNextIrpStackLocation(Irp);
- irpSp->MajorFunction = IRP_MJ_SET_INFORMATION;
- irpSp->DeviceObject = DeviceObject;
- irpSp->FileObject = pFileObject;
- irpSp->Parameters.SetFile.ReplaceIfExists = ReplaceIfExists; //是否替换
- irpSp->Parameters.SetFile.Length = FileInformationLength; //长度
- irpSp->Parameters.SetFile.FileInformationClass = FileInformationClass; //类型
- irpSp->Parameters.SetFile.FileObject = pFileObject;
- IoSetCompletionRoutine(Irp, IoCompletionRoutineEx, NULL, TRUE, TRUE, TRUE);
- ntStatus=IoCallDriver(DeviceObject, Irp);
- if (ntStatus == STATUS_PENDING)
- KeWaitForSingleObject(&SycEvent, Executive, KernelMode, TRUE, NULL);
- ntStatus = pIoStatusBlock->Status;
- //ObDereferenceObject(pFileObject);
- return ntStatus;
- }
- //获取设备对象
- 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;
- //pFilePath \\??\\c:\\456\\123.sys
- 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, FILE_ALL_ACCESS, IoGetFileObjectGenericMapping());
- if (!NT_SUCCESS(ntStatus))
- {
- IoFreeIrp(pIrp);
- ObDereferenceObject(pNewFileObject);
- return ntStatus;
- }
- SecurityContext.SecurityQos = NULL;
- SecurityContext.AccessState = &AccessState;
- SecurityContext.DesiredAccess = DesiredAccess; //FILE_ALL_ACCESS; // DELETE
- 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 = (USHORT)FILE_ATTRIBUTE_NORMAL;
- IrpSp->Parameters.Create.ShareAccess = NULL; //(USHORT)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(CreateFileObject);
- }
- return ntStatus;
- }
- //IRP读取文件
- NTSTATUS IrpReadFile(PFILE_OBJECT pFileObject,PLARGE_INTEGER pByteOffset,ULONG Length,PVOID pBuffer,PIO_STATUS_BLOCK pIoStatusBlock)
- {
- //定义变量
- PDEVICE_OBJECT DeviceObject;
- PIRP pirp;
- PIO_STACK_LOCATION irpSp;
- KEVENT event;
- NTSTATUS status;
- //参数效验
- if (pFileObject == NULL|| pByteOffset ==NULL || Length<=0 || pBuffer ==NULL|| pIoStatusBlock==NULL)return STATUS_INVALID_PARAMETER;
- //获取原始设备对象
- DeviceObject = IoGetRelatedDeviceObject(pFileObject);
- if (DeviceObject == NULL || DeviceObject->StackSize <= 0)return STATUS_UNSUCCESSFUL;
- //分配IRP
- pirp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
- if (pirp == NULL)return STATUS_INSUFFICIENT_RESOURCES;
- //分配MDL
- pirp->MdlAddress = IoAllocateMdl(pBuffer, Length, FALSE, FALSE, NULL);
- if (pirp->MdlAddress == NULL)
- {
- IoFreeIrp(pirp);
- return STATUS_INSUFFICIENT_RESOURCES;;
- }
- //更新MDL
- MmBuildMdlForNonPagedPool(pirp->MdlAddress);
- pirp->Flags = IRP_READ_OPERATION;
- pirp->RequestorMode = KernelMode;
- pirp->UserIosb = pIoStatusBlock;
- pirp->UserEvent = &event;
- pirp->Tail.Overlay.Thread = (PETHREAD)KeGetCurrentThread();
- pirp->Tail.Overlay.OriginalFileObject = pFileObject;
- irpSp = IoGetNextIrpStackLocation(pirp);
- irpSp->MajorFunction = IRP_MJ_READ;
- irpSp->MinorFunction = IRP_MN_NORMAL;
- irpSp->DeviceObject = DeviceObject;
- irpSp->FileObject = pFileObject;
- irpSp->Parameters.Read.Length = Length;
- irpSp->Parameters.Read.ByteOffset = *pByteOffset;
- KeInitializeEvent(&event, SynchronizationEvent, FALSE);
- IoSetCompletionRoutine(pirp, IoCompletionRoutineEx, NULL, TRUE, TRUE, TRUE);
- status = IoCallDriver(DeviceObject, pirp);
- if (status == STATUS_PENDING)
- status = KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, NULL);
- status = pIoStatusBlock->Status;
- return status;
- }
- //复制文件
- NTSTATUS CopyFileEx(PUNICODE_STRING lpExistingFileName, PUNICODE_STRING lpNewFileName)
- {
- //定义变量
- NTSTATUS Status = STATUS_UNSUCCESSFUL;
- OBJECT_ATTRIBUTES ObAttr = { 0 };
- HANDLE hFileSource = NULL;
- HANDLE hFileDest = NULL;
- IO_STATUS_BLOCK IoStatus = { 0 };
- char* pBuff = NULL;
- ULONG Leng = 0;
- LARGE_INTEGER Offset = { 0 };
- //参数效验
- if (lpExistingFileName == NULL || lpExistingFileName->Length <= 0 || lpNewFileName == NULL || lpNewFileName->Length <= 0)return STATUS_INVALID_PARAMETER;
- do
- {
- pBuff = ExAllocatePool(PagedPool, PAGE_SIZE);
- if (pBuff == NULL)break;
- InitializeObjectAttributes(&ObAttr, lpExistingFileName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
- Status = ZwOpenFile(&hFileSource, FILE_READ_DATA, &ObAttr, &IoStatus, FILE_SHARE_READ, FILE_NON_DIRECTORY_FILE | FILE_RANDOM_ACCESS | FILE_SYNCHRONOUS_IO_NONALERT);
- if (!NT_SUCCESS(Status))
- {
- hFileDest = NULL;
- break;
- }
- InitializeObjectAttributes(&ObAttr, lpNewFileName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
- Status = ZwCreateFile(&hFileDest, GENERIC_WRITE, &ObAttr, &IoStatus, NULL, FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, FILE_NON_DIRECTORY_FILE | FILE_RANDOM_ACCESS | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);
- if (NT_SUCCESS(Status))
- {
- hFileDest = NULL;
- break;
- }
- do
- {
- Status = ZwReadFile(hFileSource, NULL, NULL, NULL, &IoStatus, pBuff, PAGE_SIZE, &Offset, NULL);
- if (NT_ERROR(Status))
- {
- if (STATUS_END_OF_FILE == Status)
- {
- Status = STATUS_SUCCESS;
- }
- break;
- }
- Leng = (ULONG)IoStatus.Information;
- Status = ZwWriteFile(hFileDest, NULL, NULL, NULL, &IoStatus, pBuff, Leng, &Offset, NULL);
- if (Leng != IoStatus.Information)
- {
- Status = STATUS_UNSUCCESSFUL;
- break;
- }
- Offset.QuadPart += IoStatus.Information;
- } while (NT_SUCCESS(Status));
- } while (FALSE);
- if (pBuff)
- {
- ExFreePool(pBuff);
- pBuff = NULL;
- }
- if (hFileSource)
- {
- ZwClose(hFileSource);
- hFileSource = NULL;
- }
- if (hFileDest)
- {
- ZwClose(hFileDest);
- hFileDest = NULL;
- }
- return Status;
- }
- //IRP关闭文件
- NTSTATUS IrpClose(PFILE_OBJECT pFileObject)
- {
- //定义变量
- PDEVICE_OBJECT DeviceObject;
- NTSTATUS ntStatus;
- IO_STATUS_BLOCK IoStatusBlock;
- PIRP pIrp;
- KEVENT kEvent;
- PIO_STACK_LOCATION IrpSp;
- //参数效验
- if (pFileObject == NULL)return STATUS_INVALID_PARAMETER;
- //获取原始设备对象
- DeviceObject = IoGetRelatedDeviceObject(pFileObject);
- if (DeviceObject == NULL || DeviceObject->StackSize <= 0)return STATUS_UNSUCCESSFUL;
- //分配IRP
- pIrp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
- if (pIrp == NULL)return STATUS_INSUFFICIENT_RESOURCES;
- KeInitializeEvent(&kEvent, SynchronizationEvent, FALSE);
- pIrp->UserEvent = &kEvent;
- pIrp->UserIosb = &IoStatusBlock;
- pIrp->RequestorMode = KernelMode;
- pIrp->Flags = IRP_CLOSE_OPERATION | IRP_SYNCHRONOUS_API;
- pIrp->Tail.Overlay.Thread = PsGetCurrentThread();
- pIrp->Tail.Overlay.OriginalFileObject = pFileObject;
- IrpSp = IoGetNextIrpStackLocation(pIrp);
- IrpSp->MajorFunction = IRP_MJ_CLEANUP;
- IrpSp->FileObject = pFileObject;
- ntStatus = IoCallDriver(DeviceObject, pIrp);
- if (ntStatus == STATUS_PENDING)
- KeWaitForSingleObject(&kEvent, Executive, KernelMode, FALSE, NULL);
- ntStatus = IoStatusBlock.Status;
- if (!NT_SUCCESS(ntStatus))
- {
- IoFreeIrp(pIrp);
- return ntStatus;
- }
- KeClearEvent(&kEvent);
- IoReuseIrp(pIrp, STATUS_SUCCESS);
- pIrp->UserEvent = &kEvent;
- pIrp->UserIosb = &IoStatusBlock;
- pIrp->Tail.Overlay.OriginalFileObject = pFileObject;
- pIrp->Tail.Overlay.Thread = PsGetCurrentThread();
- pIrp->AssociatedIrp.SystemBuffer = (PVOID)NULL;
- pIrp->Flags = IRP_CLOSE_OPERATION | IRP_SYNCHRONOUS_API;
- IrpSp = IoGetNextIrpStackLocation(pIrp);
- IrpSp->MajorFunction = IRP_MJ_CLOSE;
- IrpSp->FileObject = pFileObject;
- if (pFileObject->Vpb && !(pFileObject->Flags & FO_DIRECT_DEVICE_OPEN))
- {
- InterlockedDecrement(&pFileObject->Vpb->ReferenceCount);
- pFileObject->Flags |= FO_FILE_OPEN_CANCELLED;
- }
- ntStatus = IoCallDriver(DeviceObject, pIrp);
- if (ntStatus == STATUS_PENDING)
- KeWaitForSingleObject(&kEvent, Executive, KernelMode, FALSE, NULL);
- IoFreeIrp(pIrp);
- ntStatus = IoStatusBlock.Status;
- return ntStatus;
- }