關於不結束進程強刪檔案一點點看法

來源:互聯網
上載者:User

這也是好久以前的代碼了。我是菜鳥,在這個問題上研究的不夠深,說錯了還請大牛指正。

 

這個問題也是一個老問題,不過我是菜鳥我有話要說。我在做這個問題的時候查閱了好多資料,其實這個問題不能算解決,這篇文章你將會看到一段比較長的代碼,其實這段代碼不是我寫的,是網上一個比較有名的人(人稱MJ)寫的,據說這段代碼是通過360檔案粉碎機逆向出來的。

 

我查了好多資料,發現能夠實現標題所說的功能大概有兩種常用的方法,一個是本文提到的直接發送IRP給目標檔案的裝置驅動強刪檔案,還有一種就是掛鈎MmFlushImageSection函數,很遺憾的是後一種方法沒有什麼實質性的源碼可以參考(不過哪位大神寫一段的話可以拿來分享一下),MmFlushImageSection不是一個系統服務,SSDT的方法當然不行,因為SSDT表沒有匯出這個函數,我記憶不錯的話按照“列寧”大神的說法MmFlushImageSection函數更加底層,是由核心匯出的一個核心功能。以我的才疏學淺的知識不明白如何掛鈎這樣的函數。如果有哪位大神看見了本菜鳥的疑惑還請不吝賜教。

 

另外還想提到的一點是,之前被一個論壇的好友迷惑了一下,他說只要使用NtDeleteFile這個系統服務就可以實現這樣的功能,這個系統服務有這麼一個功能:

在《The Undocumented Functions》一書中可以看到它對NtDeleteFile的解釋如下:
      It's very interesting NT System Call... Normally, file deletion is realised as FileDispositionInformation class in a call to NtSetInformationFile. When you use NtDeleteFile, file will be deleted immediatly after call (system
isn't waiting for close last HANDLE to file).

      從上述說明可以看出,如果我們直接調用NtDeleteFile,目標檔案將會被立即刪除而不會等到所有控制代碼都被關閉。

原文在此

於是就試了一下,誒?果然能刪除檔案,我是用一個記事本試的,比如aa.txt。其實這種方式是不正確的,為什麼呢?仔細想想,aa.txt是自己開啟的嗎?不是,是由記事本程式開啟的,也就是notepad.exe,你刪除了檔案並不能表示你可以刪除正在啟動並執行exe檔案,果然,事實證明這樣寫不能刪除正在啟動並執行exe檔案。下面也附上我寫的這段代碼吧,雖然方法上是不正確的。

#include "windows.h"typedef struct _UNICODE_STRING {USHORT Length;USHORT MaximumLength;PWSTR Buffer;} UNICODE_STRING, *PUNICODE_STRING;typedef struct _OBJECT_ATTRIBUTES {   ULONG Length;   HANDLE RootDirectory;   PUNICODE_STRING ObjectName;   ULONG Attributes;   PVOID SecurityDescriptor;   PVOID SecurityQualityOfService;} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;static VOID InitializeObjectAttributes ( OUT POBJECT_ATTRIBUTES InitializedAttributes, IN PUNICODE_STRING ObjectName, IN ULONG Attributes, IN HANDLE RootDirectory, IN PSECURITY_DESCRIPTOR SecurityDescriptor ) { InitializedAttributes->Length = sizeof( OBJECT_ATTRIBUTES ); InitializedAttributes->RootDirectory = RootDirectory; InitializedAttributes->Attributes = Attributes; InitializedAttributes->ObjectName = ObjectName; InitializedAttributes->SecurityDescriptor = SecurityDescriptor; InitializedAttributes->SecurityQualityOfService = NULL; return; }//extern "C" __declspec(dllimport) long __stdcall NtDeleteFile(POBJECT_ATTRIBUTES ObjectAttribtues);typedef ULONG (__stdcall *_NtDeleteFile)(IN POBJECT_ATTRIBUTES ObjectAttributes);_NtDeleteFile NtDeleteFile;void main(){HMODULE m_handle=LoadLibrary("ntdll.dll");UNICODE_STRING uniname ;WCHAR   m_file_name[]={L"\\??\\e:\\aa.txt"};uniname.Buffer=m_file_name;uniname.Length = sizeof(m_file_name) - sizeof(WCHAR);uniname.MaximumLength = sizeof(uniname);OBJECT_ATTRIBUTES oba ;if (m_handle!=NULL){InitializeObjectAttributes(&oba , &uniname , 0x40 , 0 , 0 );NtDeleteFile=(_NtDeleteFile)GetProcAddress(m_handle,"NtDeleteFile");NtDeleteFile(&oba);}}

這是一個使用者態的程式,直接從ntdll中匯出了NtDeleteFile。

 

然後我也附上Mj大神的發送IRP強刪檔案的方法:

#include <ntddk.h>#define NT_DEVICE_NAME              L"\\Device\\360SuperKill"#define DOS_DEVICE_NAME             L"\\DosDevices\\360SuperKill"NTSTATUS NTAPI VfatBuildRequest (PDEVICE_OBJECT DeviceObject,                                   PIRP Irp);VOID SKillUnloadDriver(     IN PDRIVER_OBJECT  DriverObject     ){    PDEVICE_OBJECT  deviceObject = DriverObject->DeviceObject;    UNICODE_STRING  uniSymLink;    RtlInitUnicodeString(&uniSymLink, DOS_DEVICE_NAME);        IoDeleteSymbolicLink(&uniSymLink);    IoDeleteDevice(deviceObject);}HANDLESkillIoOpenFile(IN PCWSTR FileName,IN ACCESS_MASK DesiredAccess,IN ULONG ShareAccess){    NTSTATUS            ntStatus;    UNICODE_STRING      uniFileName;    OBJECT_ATTRIBUTES   objectAttributes;    HANDLE              ntFileHandle;    IO_STATUS_BLOCK     ioStatus;    if (KeGetCurrentIrql() > PASSIVE_LEVEL)    {        return 0;    }    RtlInitUnicodeString(&uniFileName, FileName);    InitializeObjectAttributes(&objectAttributes, &uniFileName,        OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);    ntStatus = IoCreateFile(&ntFileHandle,        DesiredAccess,        &objectAttributes,        &ioStatus,        0,        FILE_ATTRIBUTE_NORMAL,        ShareAccess,        FILE_OPEN,        0,        NULL,        0,        0,        NULL,        IO_NO_PARAMETER_CHECKING);    if (!NT_SUCCESS(ntStatus))    {        return 0;    }    return ntFileHandle;}//回呼函數NTSTATUSSkillSetFileCompletion(    IN PDEVICE_OBJECT DeviceObject,    IN PIRP Irp,    IN PVOID Context    ){    Irp->UserIosb->Status = Irp->IoStatus.Status;    Irp->UserIosb->Information = Irp->IoStatus.Information;    KeSetEvent(Irp->UserEvent, IO_NO_INCREMENT, FALSE);    IoFreeIrp(Irp);//釋放IRP    return STATUS_MORE_PROCESSING_REQUIRED;}BOOLEAN SKillDeleteFile(IN HANDLE  FileHandle){    NTSTATUS        ntStatus = STATUS_SUCCESS;    PFILE_OBJECT    fileObject;    PDEVICE_OBJECT  DeviceObject;    PIRP            Irp;    KEVENT          event;    FILE_DISPOSITION_INFORMATION  FileInformation;    IO_STATUS_BLOCK ioStatus;    PIO_STACK_LOCATION irpSp;    PSECTION_OBJECT_POINTERS pSectionObjectPointer;     ntStatus = ObReferenceObjectByHandle(FileHandle,        DELETE,        *IoFileObjectType,        KernelMode,        &fileObject,        NULL);//開啟檔案的裝置對象    if (!NT_SUCCESS(ntStatus))    {        return FALSE;    }       DeviceObject = IoGetRelatedDeviceObject(fileObject);  //返回開啟的對象指標    Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);  //分配一個該裝置對象的IRP    if (Irp == NULL)    {        ObDereferenceObject(fileObject);        return FALSE;    }    KeInitializeEvent(&event, SynchronizationEvent, FALSE);//初始化IRP的訊號狀態        FileInformation.DeleteFile = TRUE;//設定IRP    Irp->AssociatedIrp.SystemBuffer = &FileInformation;    Irp->UserEvent = &event;    Irp->UserIosb = &ioStatus;    Irp->Tail.Overlay.OriginalFileObject = fileObject;    Irp->Tail.Overlay.Thread = (PETHREAD)KeGetCurrentThread();    Irp->RequestorMode = KernelMode;        irpSp = IoGetNextIrpStackLocation(Irp);    irpSp->MajorFunction = IRP_MJ_SET_INFORMATION;    irpSp->DeviceObject = DeviceObject;    irpSp->FileObject = fileObject;    irpSp->Parameters.SetFile.Length = sizeof(FILE_DISPOSITION_INFORMATION);    irpSp->Parameters.SetFile.FileInformationClass = FileDispositionInformation;    irpSp->Parameters.SetFile.FileObject = fileObject;//設定完成IPR請求的回呼函數    IoSetCompletionRoutine(            Irp,            SkillSetFileCompletion,            &event,            TRUE,            TRUE,            TRUE);    pSectionObjectPointer = fileObject->SectionObjectPointer;    pSectionObjectPointer->ImageSectionObject = 0;    pSectionObjectPointer->DataSectionObject = 0;    IoCallDriver(DeviceObject, Irp);         //發送IRP    KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, NULL);    ObDereferenceObject(fileObject);          //關閉裝置對象    return TRUE;}NTSTATUS DriverEntry(        IN PDRIVER_OBJECT DriverObject,        IN PUNICODE_STRING RegistryPath        ){        UNICODE_STRING                uniDeviceName;        UNICODE_STRING                uniSymLink;        NTSTATUS                        ntStatus;        PDEVICE_OBJECT                deviceObject = NULL;      HANDLE              hFileHandle;            RtlInitUnicodeString(&uniDeviceName, NT_DEVICE_NAME);    RtlInitUnicodeString(&uniSymLink, DOS_DEVICE_NAME);     //建立裝置對象        ntStatus = IoCreateDevice(                DriverObject,                0,                &uniDeviceName,                FILE_DEVICE_UNKNOWN,                FILE_DEVICE_SECURE_OPEN,                FALSE,                &deviceObject);        if (!NT_SUCCESS(ntStatus))        {                return ntStatus;        }     //設定裝置對象的名稱    ntStatus = IoCreateSymbolicLink(&uniSymLink, &uniDeviceName);    if (!NT_SUCCESS(ntStatus))    {        IoDeleteDevice(deviceObject);        return ntStatus;    }    DriverObject->DriverUnload = SKillUnloadDriver;    //開啟檔案    hFileHandle = SkillIoOpenFile(L"\\??\\c:\\calc.exe",                         FILE_READ_ATTRIBUTES,                        FILE_SHARE_DELETE);        DbgPrint("hFileHandle:%08X/n",hFileHandle);   if (hFileHandle!=NULL)   {        SKillDeleteFile(hFileHandle);    //刪除檔案        ZwClose(hFileHandle);   }   return STATUS_SUCCESS;}

這是一段驅動代碼,需要DDK編譯成驅動檔案。大題的思路我已經用注釋說明,細節部分還有待仔細研究。

菜鳥言論,僅供娛樂。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.