首页
社区
课程
招聘
[分享]发一块代码段(删除正在运行的程序文件)
发表于: 2007-5-25 16:59 26200

[分享]发一块代码段(删除正在运行的程序文件)

2007-5-25 16:59
26200

先声明一下,本文的代码其实也是从别人的工具里A出来的(A=逆向+还原),所以也不敢称是原创,有同好的朋友自然知道是哪个工具里的:),另外,由于本人不太会写文章,看不明白的地方还请大家多多谅解。

回到正题,通过分析得知,删除正在运行的程序文件的关键在于hook MmFlushImageSection这个函数,该函数原型BOOLEAN MmFlushImageSection(
                                                                 PSECTION_OBJECT_POINTERS SectionObjectPointer,
                                                                 MMFLUSH_TYPE FlushType),其流程大概如下:
1.打开要删除的文件,如:调用IoCreateFile
2.把要删除的文件属性设为Normal
3.Hook ntfs和fatfast内的引入函数MmFlushImageSection
4.发送删除IRP

大概代码如下(比较简单的一个Demo):

void ForceDeleteFile(PVOID ThreadContext)
{
        int krResult = FALSE;
        int krRetCode = FALSE;
        //NTSTATUS rc;
        HANDLE hFile = NULL, hFileSystem = NULL, SectionHandle = NULL;
        CHAR *FileName = (CHAR*)ThreadContext;
        CHAR szFileSystem[MAX_PATH_LEN];
        PUCHAR        pMap = NULL;
        ULONG        uMapSize = 0;
        PVOID        OrgFunc = NULL, OrgFunc_Ptr = NULL;
        KFile        ntfs, fastfat, del;
       

        //UNICODE_STRING usFileName;
        //PFILE_OBJECT pFileObject = NULL;
        //OBJECT_ATTRIBUTES ob;
        DEBUG_BREAK;
        krRetCode = del.OpenFile(FileName, GENERIC_READ);
        PROCESS_ERROR(krRetCode);
        dprintf("Open %s successful.\n", FileName);
        krResult = del.SetFileAttributeToNormal();
        PROCESS_ERROR(krResult);
        strcpy(szFileSystem, DRIVERS_PATH);
        strcat(szFileSystem, "ntfs.sys");
        krRetCode = ntfs.OpenFile(szFileSystem, GENERIC_READ);
        PROCESS_ERROR(krRetCode);
        g_Deleted = TRUE;
        krRetCode = ntfs.MapFile(&pMap, &uMapSize);
        PROCESS_ERROR(krRetCode);
       
        krRetCode = HookIAT(
                "MmFlushImageSection",
                "ntfs.sys",
                pMap,
                uMapSize,
                (PVOID)MmFlushImageSection_New,
                (PVOID*)&_MmFlushImageSection,
                &OrgFunc_Ptr
                );
        PROCESS_ERROR(krRetCode);

        krRetCode = ntfs.UnMapFile();
        PROCESS_ERROR(krRetCode);

        strcpy(szFileSystem, DRIVERS_PATH);
        strcat(szFileSystem, "fastfat.sys");
        krRetCode = fastfat.OpenFile(szFileSystem, GENERIC_READ);
        PROCESS_ERROR(hFileSystem);

        krRetCode = fastfat.MapFile( &pMap, &uMapSize);
        PROCESS_ERROR(krRetCode);

        krRetCode = HookIAT(
                "MmFlushImageSection",
                "fastfat.sys",
                pMap,
                uMapSize,
                (PVOID)MmFlushImageSection_New,
                (PVOID*)&_MmFlushImageSection,
                &OrgFunc_Ptr
                );
        PROCESS_ERROR(krRetCode);

        krRetCode = ntfs.UnMapFile();
        PROCESS_ERROR(krRetCode);

        krResult = Rd_DeleteFile(del.GetFileHandle());
        PROCESS_ERROR(krResult);

        krResult = TRUE;
Exit0:
        g_Deleted = FALSE;
        if (OrgFunc && OrgFunc_Ptr)
        {
                UnHookIAT(_MmFlushImageSection, OrgFunc_Ptr);
        }
        ntfs.Close();
        fastfat.Close();
        del.Close();
        return;
}

Rd_DeleteFile代码如下:

int Rd_DeleteFile(HANDLE hFile)
{
        int krResult = FALSE;
        DEVICE_OBJECT *pRealObject = NULL;
        DEVICE_OBJECT *pDeviceObject = NULL;
    PIRP irp;
    NTSTATUS rc;
    KEVENT event;
    PIO_STACK_LOCATION irpSp;
    IO_STATUS_BLOCK localIoStatus;
        PFILE_OBJECT pFileObject = NULL;
        FILE_DISPOSITION_INFORMATION disp;
        ULONG Length = sizeof(FILE_DISPOSITION_INFORMATION);

        disp.DeleteFile = TRUE;

        rc = ObReferenceObjectByHandle(
                hFile,
                0,
                *IoFileObjectType,
                0,
                (PVOID*)&pFileObject,
                0);
       
        PROCESS_DDK_ERROR(rc);

        pDeviceObject = GetRealDeviceObject(pFileObject, &pRealObject);
        PROCESS_ERROR(pDeviceObject);
       
        KeInitializeEvent(&event, SynchronizationEvent, FALSE);

        irp = IoAllocateIrp(pDeviceObject->StackSize, 0);

        if (!irp)
        {
                goto Exit0;
        }

        irp->UserEvent = &event;
        irp->UserIosb = &localIoStatus;
        irp->Overlay.AsynchronousParameters.UserApcRoutine= (PIO_APC_ROUTINE) NULL;
        irp->RequestorMode = 0;
        irp->Tail.Overlay.Thread = PsGetCurrentThread();
        irp->Tail.Overlay.OriginalFileObject = pFileObject;
        irp->Flags = IRP_BUFFERED_IO;

        irpSp = IoGetNextIrpStackLocation( irp );
    irpSp->MajorFunction = IRP_MJ_SET_INFORMATION;
    irpSp->FileObject = pFileObject;
        irpSp->DeviceObject = pDeviceObject;

    irp->UserBuffer = NULL;
    irp->AssociatedIrp.SystemBuffer = NULL;
    irp->MdlAddress = (PMDL) NULL;
       
    __try {

        irp->AssociatedIrp.SystemBuffer = ExAllocatePoolWithQuota( NonPagedPool,
                                                                   Length );
        RtlCopyMemory( irp->AssociatedIrp.SystemBuffer,
                       &disp,
                       Length );

    }
        __except(EXCEPTION_EXECUTE_HANDLER)
        {

        //
        // An exception was incurred while allocating the intermediary
        // system buffer or while copying the caller's data into the
        // buffer. Cleanup and return an appropriate error status code.
        //

        IopExceptionCleanup( pFileObject,
                             irp,
                             (PKEVENT) NULL,
                             &event );

        return GetExceptionCode();

    }

    irp->Flags |= IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER | IRP_DEFER_IO_COMPLETION;

    irpSp->Parameters.SetFile.DeleteHandle = hFile;
        irpSp->Parameters.SetFile.Length = Length;
    irpSp->Parameters.SetFile.FileInformationClass = FileDispositionInformation;
       
        irpSp->Control = 0xE0;
        irpSp->CompletionRoutine = (PIO_COMPLETION_ROUTINE)Io_Completion_Routine;
       
        if (rc == STATUS_PENDING)
        {
                rc = KeWaitForSingleObject(
                        &event,
                        Executive,
                        0,
                        1,
                        0);
               
        }       
       

        krResult = TRUE;
Exit0:
        return krResult;
}

原理:
该IRP最后会调用Ntfs内的NtfsSetDispositionInfo函数或Fastfat内的FatSetPositionInfo函数(这区别于你的硬盘分区是什么文件系统),而这两个函数都会调用Ntoskrnl内的MmFlushImageSection函数,由于我们 hook了这两驱动内的MmFlushImageSection调用,所以当它自己发送IRP时,Hook_MmFlushImageSection就能截获请求,然后在该函数内判断SectionObjectPointer参数是否等于需要删除文件的SectionObjectPointer,如果相等则调用原来的MmFlushImageSection并返回True(返回True表示正在被操作的FileObject的Section不存在或没有被Map进内存),如果不相等,则返回原来的MmFlushImageSection的调用结果。
                                                               
后记:
    自己构造IRP直接与FSD通信已经是老生常谈的话题了,有兴趣的朋友可以网上找找。


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 7
支持
分享
最新回复 (28)
雪    币: 47147
活跃值: (20460)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
2
潜水的大牛出来了
2007-5-25 17:04
0
雪    币: 232
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
不得不顶的精华
向牛人致敬
2007-5-25 17:13
0
雪    币: 218
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
NaX
4
好文章,学习了。嘿 楼主潜得也太深了!
2007-5-25 17:20
0
雪    币: 163
活跃值: (60)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
5
各位兄弟的UP让我觉得脸红 有时间再整理一些小碎块出来
2007-5-25 17:30
0
雪    币: 305
活跃值: (36)
能力值: ( LV12,RANK:250 )
在线值:
发帖
回帖
粉丝
6
弄个完整的可以不?
2007-5-25 17:32
0
雪    币: 319
活跃值: (2459)
能力值: ( LV12,RANK:980 )
在线值:
发帖
回帖
粉丝
7
楼主的工具我一直在用呢
2007-5-25 17:35
0
雪    币: 208
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
2007-5-25 20:35
0
雪    币: 7309
活跃值: (3788)
能力值: (RANK:1130 )
在线值:
发帖
回帖
粉丝
9
IceSword1.20?
2007-5-25 21:25
0
雪    币: 225
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
10
我等菜鸟还不知这等奥妙,只能收藏膜拜
2007-5-25 22:58
0
雪    币: 538
活跃值: (460)
能力值: ( LV9,RANK:290 )
在线值:
发帖
回帖
粉丝
11
向大牛学习。。。。
2007-5-26 08:35
0
雪    币: 55
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
360FileKill
2007-5-26 11:00
0
雪    币: 405
活跃值: (10)
能力值: ( LV9,RANK:1130 )
在线值:
发帖
回帖
粉丝
13
哈哈,这个代码极品啦。不要抢啊~~~~~~~~~

黑客比较喜欢这东西

原来是360
2007-5-26 11:12
0
雪    币: 716
活跃值: (162)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
14
越多越好,
2007-5-26 14:28
0
雪    币: 241
活跃值: (35)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
15
好东西,这下可以搞破坏了。
2007-5-27 01:19
0
雪    币: 1593
活跃值: (811)
能力值: ( LV13,RANK:370 )
在线值:
发帖
回帖
粉丝
16
没猜错的话搂主应该是dhl和xmy?
2007-5-27 06:12
0
雪    币: 220
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
360也是抄IceSword的
不过估计IceSword没用IoCreateFile要强点.
2007-5-27 09:59
0
雪    币: 163
活跃值: (60)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
18
2007-5-27 10:27
0
雪    币: 1324
活跃值: (5179)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
19
好东西!!!!!!!
2007-5-28 22:06
0
雪    币: 314
活跃值: (15)
能力值: ( LV12,RANK:410 )
在线值:
发帖
回帖
粉丝
20
既然是大牛就应多写点教程,供我等学习
2007-5-29 14:27
0
雪    币: 299
活跃值: (25)
能力值: ( LV10,RANK:170 )
在线值:
发帖
回帖
粉丝
21
似乎没有必要搞这么复杂吧?
发Irp之前把
pSectionObjectPointer->ImageSectionObject和pSectionObjectPointer->DataSectionObject清零就行了。
俺这个也是360那里搞来的。
#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);
}

HANDLE
SkillIoOpenFile(
    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;
}
NTSTATUS
SkillSetFileCompletion(
    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);

    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);

    if (Irp == NULL)
    {
        ObDereferenceObject(fileObject);
        return FALSE;
    }

    KeInitializeEvent(&event, SynchronizationEvent, FALSE);
   
    FileInformation.DeleteFile = TRUE;

    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;

    IoSetCompletionRoutine(
            Irp,
            SkillSetFileCompletion,
            &event,
            TRUE,
            TRUE,
            TRUE);
    pSectionObjectPointer = fileObject->SectionObjectPointer;
    pSectionObjectPointer->ImageSectionObject = 0;
    pSectionObjectPointer->DataSectionObject = 0;

    IoCallDriver(DeviceObject, 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;
}
2007-11-2 15:26
0
雪    币: 332
活跃值: (30)
能力值: ( LV12,RANK:460 )
在线值:
发帖
回帖
粉丝
22
LZ给个完整源代码,也让菜鸟学习一下
2007-11-4 08:45
0
雪    币: 334
活跃值: (22)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
23
大大牛,拜一个
2007-11-4 09:28
0
雪    币: 252
活跃值: (14)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
must be IceSword
force delete
2007-11-10 12:21
0
雪    币: 207
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
25
现在还看不懂,以后再来学习下
2007-11-13 13:44
0
游客
登录 | 注册 方可回帖
返回
//