Minifilter驱动单文件文件夹下无法隐藏文件问题排查与修复
Minifilter驱动单文件文件夹隐藏失效问题修复
问题现象
一款用于隐藏文件的Minifilter驱动,在目标文件夹仅包含单个文件时无法完成隐藏操作,其余场景下功能正常。
错误定位
你怀疑的缓冲区清零代码确实是问题根源,具体原因如下:
当文件夹内只有单个文件时,代码会进入prevInfo == NULL且info->NextEntryOffset == 0的分支:
else { status = STATUS_NO_MORE_ENTRIES; retn = TRUE; RtlFillMemory(info, sizeof(InfoType), 0); DbgPrint("%wZ", fileName); }
存在两个核心问题:
- 仅清零当前
info结构体,但系统会同时检查返回状态和缓冲区内容。即使返回STATUS_NO_MORE_ENTRIES,若缓冲区残留不符合预期的数据,资源管理器等应用仍能解析到文件。 - 单文件场景下,需让系统认为目录无任何条目,而非仅清零单个结构体。
修复方案
核心修复:调整单文件场景的缓冲区处理
修改上述分支代码,确保缓冲区完全符合"无条目"的系统预期:
else { // 清零缓冲区头部(仅需覆盖到FileName字段偏移,无需整个结构体) RtlFillMemory(buff, FIELD_OFFSET(InfoType, FileName), 0); // 明确告知系统目录无更多条目 status = STATUS_NO_MORE_ENTRIES; retn = TRUE; DbgPrint("%wZ", fileName); }
附带修复:内存泄漏问题
当前代码中fullFileName的内存释放放在循环外,若循环内提前返回会导致内存泄漏,需将释放操作移到每次使用完成后:
// 循环内处理完fullFileName后立即释放 if (isInList(masks, fileName) || isInList(masks, fullFileName)) { // ...原有判断逻辑... ExFreePoolWithTag(fullFileName.Buffer, ALLOCATION_TAG); if (retn) return status; info = (InfoType*)((PCHAR)info + offset); continue; } // 正常流程下释放内存 ExFreePoolWithTag(fullFileName.Buffer, ALLOCATION_TAG); offset = info->NextEntryOffset; prevInfo = info; info = (InfoType*)((PCHAR)info + offset); if (offset == 0) return STATUS_SUCCESS;
可选优化
- 将
fullFileName的内存分配移到循环外,每次循环调整缓冲区大小复用,减少内存分配开销。 - 验证
compareNames函数的路径匹配逻辑,避免因路径拼接错误导致隐藏规则失效。
内容的提问来源于stack exchange,提问作者Олег Турик
相关产品推荐
相关产品推荐

