如何在驱动中删除目录,这里给个例子供大家参考
在内核中要实现删除目录,删除单个文件还好一点,利用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期)