UID 2 精华 积分 7982 威望  点 
宅币  个 
贡献  次 
宅之契约  份 
最后登录 1970-1-1 
在线时间  小时 
 
 
 
 
 
 
 本帖最后由 元始天尊 于 2015-5-31 17:19 编辑  DeleteFile -> NtSetInformationFile FileInformationClass = FileDispositionInformation:         函数结构如下:(参考wrk)         CurrentThread = PsGetCurrentThread();         requestorMode = KeGetPreviousModeByThread(&CurrentThread->Tcb);         status = ObReferenceObjectByHandle(FileHandle,                 IopQueryOperationAccess[FileInformationClass],IoFileObjectType,                 requestorMode,(PVOID *)&fileObject,&handleInformation);         if (!(fileObject->Flags & FO_DIRECT_DEVICE_OPEN)) {                 deviceObject = IoGetRelatedDeviceObject(fileObject);         }         else {                 deviceObject = IoGetAttachedDevice(fileObject->DeviceObject);         }         fastIoDispatch = deviceObject->DriverObject->FastIoDispatch;         if (fileObject->Flags & FO_SYNCHRONOUS_IO) {                 BOOLEAN interrupted;                 if (!IopAcquireFastLock(fileObject)) {                         status = IopAcquireFileObjectLock(fileObject,                                 requestorMode,                                 (BOOLEAN)((fileObject->Flags & FO_ALERTABLE_IO) != 0),                                 &interrupted);                         if (interrupted) {                                 ObDereferenceObject(fileObject);                                 return status;                         }                 }                 event = ExAllocatePool(NonPagedPool, sizeof(KEVENT));                 if (event == NULL) {                         ObDereferenceObject(fileObject);                         return STATUS_INSUFFICIENT_RESOURCES;                 }                 KeInitializeEvent(event, SynchronizationEvent, FALSE);                 synchronousIo = FALSE;         }         KeClearEvent(&fileObject->Event);         irp = IoAllocateIrp(deviceObject->StackSize, FALSE);         if (!irp) {                 if (!(fileObject->Flags & FO_SYNCHRONOUS_IO)) {                         ExFreePool(event);                 }                 IopAllocateIrpCleanup(fileObject, (PKEVENT)NULL);                 return STATUS_INSUFFICIENT_RESOURCES;         }         irp->Tail.Overlay.OriginalFileObject = fileObject;         irp->Tail.Overlay.Thread = CurrentThread;         irp->RequestorMode = requestorMode;         if (synchronousIo) {                 irp->UserEvent = (PKEVENT)NULL;                 irp->UserIosb = IoStatusBlock;         }         else {                 irp->UserEvent = event;                 irp->UserIosb = &localIoStatus;                 irp->Flags = IRP_SYNCHRONOUS_API;         }         irp->Overlay.AsynchronousParameters.UserApcRoutine = (PIO_APC_ROUTINE)NULL;         irpSp = IoGetNextIrpStackLocation(irp);         irpSp->MajorFunction = IRP_MJ_SET_INFORMATION;         irpSp->FileObject = fileObject;         irp->UserBuffer = FileInformation;         irp->AssociatedIrp.SystemBuffer = (PVOID)NULL;         irp->MdlAddress = (PMDL)NULL;         try {                 irp->AssociatedIrp.SystemBuffer = ExAllocatePoolWithQuota(NonPagedPool,                         Length);         } except(EXCEPTION_EXECUTE_HANDLER) {                 IopExceptionCleanup(fileObject,                         irp,                         (PKEVENT)NULL,                         event);                 return GetExceptionCode();         }         irp->Flags |= IRP_BUFFERED_IO |                 IRP_DEALLOCATE_BUFFER |                 IRP_INPUT_OPERATION |                 IRP_DEFER_IO_COMPLETION;         irpSp->Parameters.QueryFile.Length = Length;         irpSp->Parameters.QueryFile.FileInformationClass = FileInformationClass;         IopQueueThreadIrp(irp);         IopUpdateOtherOperationCount();         if (FileInformationClass == FileDispositionInformation){                 PFILE_DISPOSITION_INFORMATION disposition = irp->AssociatedIrp.SystemBuffer;                 if (disposition->DeleteFile) {                         irpSp->Parameters.SetFile.DeleteHandle = FileHandle;                 }                 status = IoCallDriver(deviceObject, irp); windbg查看deviceObject内存,得到driverObject内存,发现Call的Driver是\FileSystem\Ntfs, 现在反汇编该文件查看IRP_MJ_SET_INFORMATION派遣,用windbg下断:Ntfs!NtfsFsdSetInformation NtfsFsdSetInformation->NtfsCommonSetInformation->NtfsSetDispositionInfo: nt!MmFlushImageSection  该函数返回空 -> nt!MiCheckControlAreaStatus BOOLEAN MmFlushImageSection (__in PSECTION_OBJECT_POINTERS SectionPointer,__in MMFLUSH_TYPE FlushType) {     PLIST_ENTRY Next;     PCONTROL_AREA ControlArea;     PLARGE_CONTROL_AREA LargeControlArea;     KIRQL OldIrql;     LOGICAL state;     if (FlushType == MmFlushForDelete) {         LOCK_PFN (OldIrql);         ControlArea = (PCONTROL_AREA)(SectionPointer->DataSectionObject);         if (ControlArea != NULL) {             if ((ControlArea->NumberOfUserReferences != 0) ||                 (ControlArea->u.Flags.BeingCreated)) {                 UNLOCK_PFN (OldIrql);                 return FALSE;             }         }         UNLOCK_PFN (OldIrql);     }     state = MiCheckControlAreaStatus (CheckImageSection,SectionPointer,FALSE,&ControlArea,&OldIrql);     if (ControlArea == NULL) {         return (BOOLEAN) state;     }     do {         ControlArea->u.Flags.BeingDeleted = 1;         ControlArea->NumberOfMappedViews = 1;         LargeControlArea = NULL;         if (ControlArea->u.Flags.GlobalOnlyPerSession == 0) {             NOTHING;         }         else if (IsListEmpty(&((PLARGE_CONTROL_AREA)ControlArea)->UserGlobalList)) {             ASSERT (ControlArea ==(PCONTROL_AREA)SectionPointer->ImageSectionObject);         }         else {             ASSERT (ControlArea->u.Flags.GlobalOnlyPerSession == 1);             Next = ((PLARGE_CONTROL_AREA)ControlArea)->UserGlobalList.Flink;             LargeControlArea = CONTAINING_RECORD (Next,LARGE_CONTROL_AREA,UserGlobalList);             ASSERT (LargeControlArea->u.Flags.GlobalOnlyPerSession == 1);             LargeControlArea->NumberOfSectionReferences += 1;         }         UNLOCK_PFN (OldIrql);         MiCleanSection (ControlArea, TRUE);         if (LargeControlArea != NULL) {             state = MiCheckControlAreaStatus (CheckImageSection,SectionPointer,FALSE, &ControlArea,&OldIrql);             if (!ControlArea) {                 LOCK_PFN (OldIrql);                 LargeControlArea->NumberOfSectionReferences -= 1;                 MiCheckControlArea ((PCONTROL_AREA)LargeControlArea,OldIrql);             }             else {                 LargeControlArea->NumberOfSectionReferences -= 1;                 MiCheckControlArea ((PCONTROL_AREA)LargeControlArea,OldIrql);                 LOCK_PFN (OldIrql);             }         }         else {             state = TRUE;             break;         }     } while (ControlArea);     return (BOOLEAN) state; } LOGICAL MiCheckControlAreaStatus (IN SECTION_CHECK_TYPE SectionCheckType,IN PSECTION_OBJECT_POINTERS SectionObjectPointers,IN ULONG DelayClose, OUT PCONTROL_AREA *ControlAreaOut, OUT PKIRQL PreviousIrql) {     PKTHREAD CurrentThread;     PEVENT_COUNTER IoEvent;     PEVENT_COUNTER SegmentEvent;     LOGICAL DeallocateSegmentEvent;     PCONTROL_AREA ControlArea;     ULONG SectRef;     KIRQL OldIrql;     *ControlAreaOut = NULL;     do {         SegmentEvent = MiGetEventCounter ();         if (SegmentEvent != NULL) {             break;         }         KeDelayExecutionThread (KernelMode,                                 FALSE,                                 (PLARGE_INTEGER)&MmShortTime);     } while (TRUE);     LOCK_PFN (OldIrql);     if (SectionCheckType != CheckImageSection) {         ControlArea = ((PCONTROL_AREA)(SectionObjectPointers->DataSectionObject));     }     else {         ControlArea = ((PCONTROL_AREA)(SectionObjectPointers->ImageSectionObject));     }     if (ControlArea == NULL) {         if (SectionCheckType != CheckBothSection) {             UNLOCK_PFN (OldIrql);             MiFreeEventCounter (SegmentEvent);             return TRUE;         }         else {             ControlArea = ((PCONTROL_AREA)(SectionObjectPointers->ImageSectionObject));             if (ControlArea == NULL) {                 UNLOCK_PFN (OldIrql);                 MiFreeEventCounter (SegmentEvent);                 return TRUE;             }         }     }     if (SectionCheckType != CheckUserDataSection) {         SectRef = ControlArea->NumberOfSectionReferences;     }     else {         SectRef = ControlArea->NumberOfUserReferences;     }     if ((SectRef != 0) ||         (ControlArea->NumberOfMappedViews != 0) ||         (ControlArea->u.Flags.BeingCreated)) {         if (DelayClose) {             ControlArea->u.Flags.DeleteOnClose = 1;         }         UNLOCK_PFN (OldIrql);         MiFreeEventCounter (SegmentEvent);         return FALSE;     }     if (ControlArea->u.Flags.BeingDeleted) {         if (ControlArea->WaitingForDeletion == NULL) {             DeallocateSegmentEvent = FALSE;             ControlArea->WaitingForDeletion = SegmentEvent;             IoEvent = SegmentEvent;         }         else {             DeallocateSegmentEvent = TRUE;             IoEvent = ControlArea->WaitingForDeletion;             IoEvent->RefCount += 1;         }         CurrentThread = KeGetCurrentThread ();         KeEnterCriticalRegionThread (CurrentThread);         UNLOCK_PFN_AND_THEN_WAIT(OldIrql);         KeWaitForSingleObject(&IoEvent->Event,                               WrPageOut,                               KernelMode,                               FALSE,                               (PLARGE_INTEGER)NULL);         KeLeaveCriticalRegionThread (CurrentThread);         MiFreeEventCounter (IoEvent);         if (DeallocateSegmentEvent == TRUE) {             MiFreeEventCounter (SegmentEvent);         }         return TRUE;     }     ASSERT (SegmentEvent->RefCount == 1);     ASSERT (SegmentEvent->ListEntry.Next == NULL);     InterlockedPushEntrySList (&MmEventCountSListHead,                                (PSLIST_ENTRY)&SegmentEvent->ListEntry);     *ControlAreaOut = ControlArea;     *PreviousIrql = OldIrql;     return FALSE; } 复制代码 NTSTATUS DriverIoctl(PDEVICE_OBJECT pDevObj,PIRP pIrp) {         NTSTATUS status = STATUS_SUCCESS;         KdPrint(("Driver Ioctl\n"));         PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp);         ULONG cbin = pStack->Parameters.DeviceIoControl.InputBufferLength;         ULONG cbout = pStack->Parameters.DeviceIoControl.OutputBufferLength;         PVOID buffer = pIrp->AssociatedIrp.SystemBuffer;         ULONG ulOutputLen=0;         switch(pStack->Parameters.DeviceIoControl.IoControlCode)         {         case IOCTL_IO_DELFILE:                 {                         PFILE_OBJECT pObject;                         status = ObReferenceObjectByHandle(*(HANDLE*)buffer,GENERIC_READ,*IoFileObjectType,KernelMode,(PVOID*)&pObject,NULL);                          if(NT_SUCCESS(status))                         {                                 __try                                 {                                         PSCB Scb = (PSCB)pObject->FsContext;//NtfsDecodeFileObject                                         if(Scb)                                         {                                                 Scb->Fcb->Info.FileAttributes &= ~FILE_ATTRIBUTE_READONLY;//IsReadOnly                                                 PSECTION_OBJECT_POINTERS pop=&Scb->NonpagedScb->SegmentObject;                                                 pop->ImageSectionObject = NULL;                                         }                                 }                                 __except(1)                                 {                                 }                                 ObDereferenceObject(pObject);                         }                 }                 break;         }         pIrp->IoStatus.Status = status;         pIrp->IoStatus.Information = ulOutputLen;         IoCompleteRequest(pIrp,IO_NO_INCREMENT);         return status; } #include <iostream> #include <windows.h> using namespace std; #define IOCTL_IO_DELFILE CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS)//获取驱动加载信息 int _tmain(int argc, _TCHAR* argv[]) {         if (argc != 2)         {                 cout << "参数不够" << endl;         }         HANDLE hFile = CreateFileW(argv[1], 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);         if (hFile != INVALID_HANDLE_VALUE)         {                 HANDLE hDev = CreateFileW(L"\\\\.\\NtMem", GENERIC_ALL, 0, NULL, OPEN_EXISTING, 0, NULL);                 if (hDev != INVALID_HANDLE_VALUE)                 {                         DWORD nop = 0;                         DeviceIoControl(hDev, IOCTL_IO_DELFILE, (LPVOID)&hFile, sizeof(HANDLE), (LPVOID)&hFile, 0, &nop, NULL);                         CloseHandle(hDev);                 }                 else                 {                         cout << "无法打开设备!" << endl;                 }                 CloseHandle(hFile);         }         else         {                 cout << "无法打开文件!" << endl;         }         return 0; } 复制代码