|
[已解决] minifilter最近在做文件保护 win10 shift+delete删除搞不定
petersonhz 你试过用minifilter获取所有文件创建事件么? 这带来的系统开销大么[em_1]我没有捕获过所有的文件创建,不过我觉得这就是一个过滤,不写内容的话,开销不大 |
|
|
|
[原创]WFP网络流量监控系统
老是提示服务创建失败…… |
|
[讨论]窝了几年,10年都做windows客户端安全方向的产品,发现工作不好找了。
只要windows操作系统不淘汰,windows开发永远有市场 |
|
[求助]FltUnregisterFilter导致的minifilter服务挂起有没有好的方法知道是什么资源没释放
首先肯定是你的资源没有释放, 你可以测试一下是哪个资源没有释放,比如:流句柄;文件对象等 |
|
[求助]关于删除文件夹的一点疑问
这种我个人觉得没法解决 |
|
|
|
|
|
[求助]minifilter 线程重入
tsoo FltCreateFile 参数肯定传错了. 自己检查下.确实是FltCreateFile的参数传错了,第二个参数不应该写成NULL,应该写操作文件的实例。一语中的呀 |
|
[求助]minifilter 线程重入
VOID StartThread1(COPYTHREAD Copy) { NTSTATUS status = STATUS_SUCCESS; HANDLE hThread = NULL; KEVENT kEvent = {0}; // KdPrint(("jinle \n")); //初始化参数 KeInitializeEvent(&kEvent,SynchronizationEvent,FALSE); Copy.PKE = &kEvent; // KdPrint(("Copy.PKE \n")); status = PsCreateSystemThread(&hThread, //创建新线程 0, NULL, NULL,//NtCurrentProcess(),线程所在地址空间的进程的handle NULL, (PKSTART_ROUTINE)ThreadProc1, (PVOID)&Copy); //PVOID StartContext 对应ThreadProc中的参数 if (!NT_SUCCESS(status)) { KdPrint(("创建失败 \n")); ZwClose(hThread); return ; } KdPrint(("创建成功 \n")); //等待线程返回 KeWaitForSingleObject(&kEvent,Executive,KernelMode,FALSE,NULL); ZwClose(hThread); return ; } VOID ThreadProc1(IN PVOID pContext) { PCOPYTHREAD copyThread; copyThread = (PCOPYTHREAD)pContext; dfDeleteDirectory(copyThread->Data,copyThread->FltObjects,L"\\??\\d:\\Backup"); KeSetEvent(copyThread->PKE,IO_NO_INCREMENT,FALSE); KdPrint(("线程函数结束\n")); PsTerminateSystemThread(STATUS_SUCCESS); return ; } NTSTATUS dfDeleteDirectory(PFLT_CALLBACK_DATA Data,PCFLT_RELATED_OBJECTS FltObjects,const WCHAR * directory) { OBJECT_ATTRIBUTES objAttributes = { 0 }; IO_STATUS_BLOCK iosb = { 0 }; HANDLE handle = NULL; FILE_DISPOSITION_INFORMATION disInfo = { 0 }; PVOID buffer = NULL; ULONG bufferLength = 0; BOOLEAN restartScan = FALSE; PFILE_DIRECTORY_INFORMATION dirInfo = NULL; PWSTR nameBuffer = NULL; //记录文件夹 UNICODE_STRING nameString = { 0 }; NTSTATUS status = 0; LIST_ENTRY listHead = { 0 }; //链表,用来存放删除过程中的目录 PFILE_LIST_ENTRY tmpEntry = NULL; //链表结点 PFILE_LIST_ENTRY preEntry = NULL; UNICODE_STRING uDirName = { 0 }; RtlInitUnicodeString(&uDirName, directory); nameBuffer = (PWSTR)ExAllocatePoolWithTag(NonPagedPool, uDirName.Length + sizeof(WCHAR), 'DRID'); if (!nameBuffer) { return STATUS_INSUFFICIENT_RESOURCES; } tmpEntry = (PFILE_LIST_ENTRY)ExAllocatePoolWithTag(NonPagedPool, sizeof(FILE_LIST_ENTRY), 'DRID'); if (!tmpEntry) { ExFreePool(nameBuffer); return STATUS_INSUFFICIENT_RESOURCES; } RtlCopyMemory(nameBuffer, uDirName.Buffer, uDirName.Length); nameBuffer[uDirName.Length / sizeof(WCHAR)] = L'\0'; InitializeListHead(&listHead); //初始化链表 tmpEntry->NameBuffer = nameBuffer; InsertHeadList(&listHead, &tmpEntry->Entry); //将要删除的文件夹首先插入链表 //listHead里初始化为要删除的文件夹。 //之后遍历文件夹下的文件和目录,判断是文件,则立即删除;判断是目录,则放进listHead里面 //每次都从listHead里拿出一个目录来处理 while (!IsListEmpty(&listHead)) { //先将要删除的文件夹和之前打算删除的文件夹比较一下,如果从链表里取下来的还是之前的Entry,表明没有删除成功,说明里面非空 //否则,已经成功删除,不可能是它自身;或者还有子文件夹,在前面,也不可能是它自身。 tmpEntry = (PFILE_LIST_ENTRY)RemoveHeadList(&listHead); if (preEntry == tmpEntry) { status = STATUS_DIRECTORY_NOT_EMPTY; break; } preEntry = tmpEntry; InsertHeadList(&listHead, &tmpEntry->Entry); //放进去,等删除了里面的内容,再移除。如果移除失败,则说明还有子文件夹或者目录非空 RtlInitUnicodeString(&nameString, tmpEntry->NameBuffer); InitializeObjectAttributes(&objAttributes, &nameString, OBJ_CASE_INSENSITIVE, NULL, NULL); //打开文件夹,进行查询 status = FltCreateFile( FltObjects->Filter, NULL, &handle, DELETE, //开始写的所有会失败 &objAttributes, &iosb, NULL, 0, 0, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0, 0); if (!NT_SUCCESS(status)) { KdPrint(("2 FltCreateFile(%ws) failed(%x)\n", tmpEntry->NameBuffer, status)); // KdPrint(("2ZwCreateFilefailed(%x)\n", status)); break; } //从第一个扫描 restartScan = TRUE; PFILE_OBJECT fileObject = NULL; while (TRUE) { buffer = NULL; bufferLength = 64; status = STATUS_BUFFER_OVERFLOW; while ((status == STATUS_BUFFER_OVERFLOW) || (status == STATUS_INFO_LENGTH_MISMATCH)) { if (buffer) { ExFreePool(buffer); } bufferLength *= 2; buffer = ExAllocatePoolWithTag(NonPagedPool, bufferLength, 'DRID'); if (!buffer) { KdPrint(("ExAllocatePool failed\n")); status = STATUS_INSUFFICIENT_RESOURCES; break; } // 通过文件句柄得到文件对象传给FltQueryDirectoryFile status = ObReferenceObjectByHandle(handle, 0, NULL, KernelMode, reinterpret_cast<void **>(&fileObject), NULL); if (!NT_SUCCESS(status)) { KdPrint(("ObReferenceObjectByHandle 1 fail \n")); } status = FltQueryDirectoryFile(FltObjects->Instance, fileObject, buffer, bufferLength, FileDirectoryInformation, FALSE, NULL, restartScan, NULL); if (fileObject) { ObDereferenceObject(fileObject); } } if (status == STATUS_NO_MORE_FILES) { ExFreePool(buffer); status = STATUS_SUCCESS; break; } restartScan = FALSE; if (!NT_SUCCESS(status)) { KdPrint(("FltQueryDirectoryFile(%ws) failed(%x),\n", tmpEntry->NameBuffer, status)); if (buffer) { ExFreePool(buffer); } break; } dirInfo = (PFILE_DIRECTORY_INFORMATION)buffer; nameBuffer = (PWSTR)ExAllocatePoolWithTag( NonPagedPool, wcslen(tmpEntry->NameBuffer) * sizeof(WCHAR) + dirInfo->FileNameLength + 4, 'DRID'); if (!nameBuffer) { KdPrint(("ExAllocatePool failed\n")); ExFreePool(buffer); status = STATUS_INSUFFICIENT_RESOURCES; break; } //tmpEntry->NameBuffer是当前文件夹路径 //下面的操作在拼接文件夹下面的文件路径 RtlZeroMemory(nameBuffer, wcslen(tmpEntry->NameBuffer) * sizeof(WCHAR) + dirInfo->FileNameLength + 4); wcscpy(nameBuffer, tmpEntry->NameBuffer); wcscat(nameBuffer, L"\\"); RtlCopyMemory(&nameBuffer[wcslen(nameBuffer)], dirInfo->FileName, dirInfo->FileNameLength); RtlInitUnicodeString(&nameString, nameBuffer); if (dirInfo->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) { //如果是非'.'和'..'两个特殊的目录,则将目录放入listHead if ((dirInfo->FileNameLength == sizeof(WCHAR)) && (dirInfo->FileName[0] == L'.')) { } else if ((dirInfo->FileNameLength == sizeof(WCHAR) * 2) && (dirInfo->FileName[0] == L'.') && (dirInfo->FileName[1] == L'.')) { } else { //将文件夹插入listHead中 PFILE_LIST_ENTRY localEntry; localEntry = (PFILE_LIST_ENTRY)ExAllocatePoolWithTag( NonPagedPool, sizeof(FILE_LIST_ENTRY), 'DRID'); if (!localEntry) { KdPrint(("ExAllocatePool failed\n")); ExFreePool(buffer); ExFreePool(nameBuffer); status = STATUS_INSUFFICIENT_RESOURCES; break; } localEntry->NameBuffer = nameBuffer; nameBuffer = NULL; InsertHeadList(&listHead, &localEntry->Entry); //插入头部,先把子文件夹里的删除 } } else { //文件,直接删除 // KdPrint(("文件路径:%S\n",nameBuffer)); //在删除前恢复 status = CopyFileBeforeDel(Data,FltObjects,nameBuffer); if (!NT_SUCCESS(status)) { KdPrint(("CopyFileBeforeDel(%wZ) failed(%x)\n", &nameString, status)); ExFreePool(buffer); ExFreePool(nameBuffer); break; } } ExFreePool(buffer); if (nameBuffer) { ExFreePool(nameBuffer); }//继续在循环里处理下一个子文件或者子文件夹 }// while (TRUE) ,一直弄目录里的文件和文件夹 if (NT_SUCCESS(status)) { //删除目录 /*PFILE_OBJECT fileObject1 = NULL; status = ObReferenceObjectByHandle(handle, 0, NULL, KernelMode, reinterpret_cast<void **>(&fileObject1), NULL); if (!NT_SUCCESS(status)) { KdPrint(("ObReferenceObjectByHandle 1 fail \n")); } disInfo.DeleteFile = TRUE; status = FltSetInformationFile( FltObjects->Instance, fileObject1, &disInfo, sizeof(disInfo), FileDispositionInformation); if (NT_SUCCESS(status)) { if (fileObject1) { ObDereferenceObject(fileObject1); } } else { KdPrint(("3 FltSetInformationFile(%ws) failed(%x)\n", tmpEntry->NameBuffer, status)); } */ } FltClose(handle); if (NT_SUCCESS(status)) { //删除成功,从链表里移出该目录 RemoveEntryList(&tmpEntry->Entry); ExFreePool(tmpEntry->NameBuffer); ExFreePool(tmpEntry); } //如果失败,则表明在文件夹还有子文件夹,继续先删除子文件夹 }// while (!IsListEmpty(&listHead)) while (!IsListEmpty(&listHead)) { tmpEntry = (PFILE_LIST_ENTRY)RemoveHeadList(&listHead); ExFreePool(tmpEntry->NameBuffer); ExFreePool(tmpEntry); } return status; } 完整代码如上,第一个FltCreateFile就返回拒绝了 |
|
|
|
[求助]用 ZwTerminateProcess 结束进程时卡死,杀不掉要结束的进程
MaMy try catch 什么鬼..自己调阿,不行开个workitem试试ZwTerminateProcess这个函数里面卡死了 |
操作理由
RANk
{{ user_info.golds == '' ? 0 : user_info.golds }}
雪币
{{ experience }}
课程经验
{{ score }}
学习收益
{{study_duration_fmt}}
学习时长
基本信息
荣誉称号:
{{ honorary_title }}
能力排名:
No.{{ rank_num }}
等 级:
LV{{ rank_lv-100 }}
活跃值:
在线值:
浏览人数:{{ visits }}
最近活跃:{{ last_active_time }}
注册时间:{{ user_info.create_date_jsonfmt }}
勋章
兑换勋章
证书
证书查询 >
能力值