首页
社区
课程
招聘
[原创]如何在驱动中删除目录,这里给个例子供大家参考
发表于: 2013-3-27 22:42 6851

[原创]如何在驱动中删除目录,这里给个例子供大家参考

2013-3-27 22:42
6851

如何在驱动中删除目录,这里给个例子供大家参考

在内核中要实现删除目录,删除单个文件还好一点,利用ZwDeleteFile一下就完事,针对删除目录就得发点时间纠结一下了。

谁让驱动程序启动早,开发应用层的同事哥总想着偷懒,

删除个目录还要求在驱动层中实现,真是吃力不讨好,

不过还是有些场景需要呢,比如一些比较重要的目录需要开机前删除,或者PC不小心断电软件来不及自己删除时但又不想让用户看到的数据,此时就需要在开机删除。

主要思路是:在内核中创建一个线程,在线程里实现删除给定的目录功能。

完整代码在附件中。。。。

/////////////////////////////////////////////////////////////////////////////////////////

NTSTATUS BeginDeletefileThread(PUNICODE_STRING usPath)
{
        NTSTATUS status = STATUS_UNSUCCESSFUL;
        HANDLE hThread = NULL;
        OBJECT_ATTRIBUTES oaThread;
        CLIENT_ID ThreadID;
        PWCHAR pPathPtoThread = NULL;

        if (KeGetCurrentIrql() >= APC_LEVEL)
        {
                return STATUS_UNSUCCESSFUL;
        }

        if (usPath == NULL) return STATUS_UNSUCCESSFUL;

        pPathPtoThread = (PWCHAR)ExAllocatePoolWithTag( NonPagedPool,(usPath->Length + sizeof(WCHAR)),'tSpR');//这里申请空间,在线程里释放
        if (pPathPtoThread == NULL)
        {
                return STATUS_UNSUCCESSFUL;
        }

        RtlZeroMemory(pPathPtoThread,(usPath->Length + sizeof(WCHAR)));
        RtlCopyMemory(pPathPtoThread,usPath->Buffer,usPath->Length);

        //启动线程
        InitializeObjectAttributes(&oaThread, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
       
        status = PsCreateSystemThread(&hThread, THREAD_ALL_ACCESS, &oaThread, NULL/*NtCurrentProcess()*/, &ThreadID, (PKSTART_ROUTINE)DelCachefile, (PVOID)pPathPtoThread);
        if (NT_SUCCESS(status))
        {
                ZwClose(hThread);
        }
        else
        {
                if (pPathPtoThread != NULL) ExFreePoolWithTag(pPathPtoThread,'tSpR');
        }

        return status;
}

void DelCachefile(IN PVOID pContext)
{
        UNICODE_STRING usPath;
        PWCHAR pPathPtoThread = (PWCHAR)pContext;
        LARGE_INTEGER liTime;
       
        if (pContext == NULL)
        {
                return;
        }
       
        RtlInitUnicodeString(usPath,pPathPtoThread);
       
        if (usPath.Length <= 0)
        {
                ExFreePoolWithTag(pPathPtoThread,'tSpR');
                return;
        }
       
        liTime =RtlConvertLongToLargeInteger(-(LONG)1000 * 1000 * 20);//-1000 * 1000 -> 100ms
        KeDelayExecutionThread(KernelMode,TRUE,&liTime);//延时
       
        //删除目录
        deldirfile(&usPath);
        deldir(&usPath);

        ExFreePoolWithTag(pPathPtoThread,'tSpR');
}

NTSTATUS delfile(IN PUNICODE_STRING pusFile)
{
        NTSTATUS status = STATUS_UNSUCCESSFUL;
        OBJECT_ATTRIBUTES attributes;

        HANDLE hFile = NULL;
        IO_STATUS_BLOCK iosb;
        FILE_BASIC_INFORMATION fbi;

        UNREFERENCED_PARAMETER(pusFile);
        if (pusFile == NULL || pusFile->Length <= 0)
        {
                return status;
        }

        InitializeObjectAttributes(&attributes,
                pusFile,
                OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                NULL,
                NULL);
        try
        {
                status = ZwDeleteFile(&attributes);
                if (!NT_SUCCESS(status))
                {
                        //无法删除 去除文件只读属性再删除
                        status = ZwCreateFile(&hFile,DELETE | SYNCHRONIZE,&attributes,&iosb,NULL,0,
                                FILE_SHARE_DELETE,FILE_OPEN,FILE_SYNCHRONOUS_IO_NONALERT,NULL,0);
                        if (!NT_SUCCESS(status))
                        {
                                return STATUS_UNSUCCESSFUL;
                        }

                        status = ZwQueryInformationFile(hFile,&iosb,&fbi,sizeof(FILE_BASIC_INFORMATION),FileBasicInformation);
                        if (!NT_SUCCESS(status))
                        {
                                return STATUS_UNSUCCESSFUL;
                        }

                        if (fbi.FileAttributes & FILE_ATTRIBUTE_READONLY == FILE_ATTRIBUTE_READONLY)
                        {
                                fbi.FileAttributes = fbi.FileAttributes & (~FILE_ATTRIBUTE_READONLY);
                                status = ZwSetInformationFile(hFile,&iosb,&fbi,sizeof(FILE_BASIC_INFORMATION),FileBasicInformation);
                                if (!NT_SUCCESS(status))
                                {
                                        return STATUS_UNSUCCESSFUL;
                                }
                               
                                status = ZwDeleteFile(&attributes);
                                if (NT_SUCCESS(status))
                                {
                                        return STATUS_SUCCESS;
                                }
                        }

                        return STATUS_UNSUCCESSFUL;
                }
                else
                {
                        return STATUS_SUCCESS;
                }
        }
        finally
        {
                if (hFile != NULL) ZwClose(hFile);
        }
}

NTSTATUS deldir(IN PUNICODE_STRING pusDir)
{
        NTSTATUS status = STATUS_UNSUCCESSFUL;
        OBJECT_ATTRIBUTES attributes;

        UNREFERENCED_PARAMETER(pusDir);
        if (pusDir == NULL || pusDir->Length <= 0) return status;

        InitializeObjectAttributes(&attributes,
                pusDir,
                OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                NULL,
                NULL);

        status = ZwDeleteFile(&attributes);
        if (!NT_SUCCESS(status))
        {
                return status;
        }

        return status;
}

NTSTATUS deldirfile(IN PUNICODE_STRING pusDir)
{
        NTSTATUS status = STATUS_UNSUCCESSFUL;
        OBJECT_ATTRIBUTES attributes;
        HANDLE hDir = NULL;
        IO_STATUS_BLOCK iosb;
        PFILE_DIRECTORY_INFORMATION pfdi = NULL;
        UNICODE_STRING usTemp;
        WCHAR sFilebuff[300] = {0};
        UNICODE_STRING usFile;

        UNREFERENCED_PARAMETER(pusDir);

        if (pusDir == NULL || pusDir->Length <= 0)
        {
                return status;
        }

        InitializeObjectAttributes(&attributes,
                pusDir,
                OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                NULL,
                NULL);

        RtlInitEmptyUnicodeString(&usFile,sFilebuff,sizeof(sFilebuff));
        status = ZwOpenFile(&hDir,FILE_LIST_DIRECTORY | SYNCHRONIZE,&attributes,&iosb,
                FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
        if (NT_SUCCESS(status))
        {
                pfdi = (PFILE_DIRECTORY_INFORMATION)ExAllocatePoolWithTag( NonPagedPool,(sizeof(FILE_DIRECTORY_INFORMATION)+520),'tSpR');
                if (pfdi != NULL)
                {
                        RtlInitUnicodeString(&usTemp,L"*");
                        status = ZwQueryDirectoryFile(hDir,NULL,NULL,NULL,&iosb,pfdi,(sizeof(FILE_DIRECTORY_INFORMATION)+520),
                                FileDirectoryInformation,TRUE,&usTemp,TRUE);

                        while(status != STATUS_NO_MORE_FILES)
                        {
                                if (status == STATUS_SUCCESS && (pusDir->Length+pfdi->FileNameLength+2) <= usFile.MaximumLength)
                                {
                                        usFile.Length = 0;
                                        RtlZeroMemory(usFile.Buffer,usFile.MaximumLength);
                                        RtlCopyUnicodeString(&usFile,pusDir);
                                        RtlAppendUnicodeToString(&usFile,L"\\");
                                        RtlCopyMemory(((PCHAR)usFile.Buffer+usFile.Length),pfdi->FileName,pfdi->FileNameLength);
                                        usFile.Length += (USHORT)pfdi->FileNameLength;

                                        if ((pfdi->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY)
                                        {
                                                //删除目录枚举中的目录
                                                deldirfile(&usFile);
                                                deldir(&usFile);
                                        }
                                        else
                                        {
                                                //删除目录枚举中的文件
                                                status = delfile(&usFile);
                                        }

                                        status = ZwQueryDirectoryFile(hDir,NULL,NULL,NULL,&iosb,pfdi,(sizeof(FILE_DIRECTORY_INFORMATION)+520),
                                                FileDirectoryInformation,TRUE,NULL,FALSE);
                                }
                        }

                        if (pfdi != NULL) ExFreePoolWithTag(pfdi,'tSpR');
                }

                if (hDir != NULL) ZwClose(hDir);
        }
        return status;
}


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 6
支持
分享
最新回复 (7)
雪    币: 86
活跃值: (60)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
2
附件:内核删除目录源码.rar
上传的附件:
2013-3-27 22:50
0
雪    币: 134
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
不错。沙发支持。
2013-3-27 22:58
0
雪    币: 3366
活跃值: (1358)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
4
顶一个。字符++
2013-3-28 08:15
0
雪    币: 306
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
先顶下楼主吧
2013-3-28 08:28
0
雪    币: 61
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
楼主有木有,强制删除正在运行程序的文件的文章啊。
2013-3-28 10:53
0
雪    币: 79
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
感谢楼主,已经收藏了,以后可以借鉴
2013-3-28 11:16
0
雪    币: 154
活跃值: (22)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
没测试。但是看码有问题,栈内存绝对不在递归中使用,上面代码一次600字节,几个循环就蓝屏了,指出一下
2020-5-7 19:02
0
游客
登录 | 注册 方可回帖
返回
//