【半原創】Irp佔坑保護檔案不被刪除
阿新 • • 發佈:2018-11-10
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.找跟控制代碼、物件無關的刪除方法~