c# - 如何在 C# 中以编程方式读取 Windows NTFS $Secure 文件(和/或 $SDS 流)
问题描述
.NET 平台的 DirectorySecurity 命名空间中的方法(例如 GetAccessRules())对于我的目的来说太慢了。相反,我希望直接查询 NTFS $Secure 元文件(或者,$SDS 流),以便检索每个文件系统对象的本地帐户列表及其相关权限。
我的计划是首先读取 $MFT 元文件(我已经知道如何去做) - 然后,对于其中的每个条目,在元文件(或流)中查找适当的安全描述符。
理想的代码块如下所示:
//I've already successfully written code for MFTReader:
var mftReader = new MFTReader(driveToAnalyze, RetrieveMode.All);
IEnumerable<INode> nodes = mftReader.GetNodes(driveToAnalyze.Name);
foreach (NodeWrapper node in nodes)
{
//Now I wish to return security information for each file system object
//WITHOUT needing to traverse the directory tree.
//This is where I need help:
var securityInfo = GetSecurityInfoFromMetafile(node.FullName, node.SecurityID);
yield return Tuple.Create(node.FullName, securityInfo.PrincipalName, DecodeAccessMask(securityInfo.AccessMask));
}
我希望我的输出看起来像这样:
c:\Folder1\File1.txt jane_smith Read, Write, Execute
c:\Folder1\File1.txt bill_jones Read, Execute
c:\Folder1\File2.txt john_brown Full Control
etc.
我在 Windows 10 上运行 .NET 版本 4.7.1。
解决方案
没有 API 可以直接从 $Secure 读取,就像没有 API 可以直接从 $MFT 读取一样。(有 FSCTL_QUERY_FILE_LAYOUT 但这只是为您提供了对 MFT 内容的抽象解释。)
既然你说你可以读取 $MFT,听起来你必须使用卷句柄直接从卷中读取,就像 chkdsk 和类似工具一样。只要您知道如何解释磁盘结构,就可以阅读您想要的任何内容。因此,您的问题归结为如何正确解释 $Secure 文件。
我不会给你代码片段或确切的数据结构,但我会给你一些非常好的提示。实际上有两种可能的方法。
第一种方法是您可以在 $SDS 中向前扫描。所有安全描述符都在那里,按 SecurityId 顺序排列。您会发现有各种 16 字节对齐的偏移量,将有一个 20 字节的标头,其中包括 SecurityId 以及其他信息,然后是序列化形式的安全描述符。SecurityId 值将按升序显示在 $SDS 中。此外,$SDS 中的每个备用 256K 区域都是前一个 256K 区域的镜像。要将工作减半,只需考虑 0..256K-1、512K..768K-1 等区域。
第二种方法是利用 $SII 索引,它也是 $Secure 文件的一部分。它的结构是一个 B 树,与 NTFS 中目录的结构非常相似。$SII 中的索引条目将 SecurityId 作为查找的索引,还包含您可以在 $SDS 中查找相应标头和安全描述符的字节偏移量。这种方法将比扫描 $SDS 更高效,但需要您知道如何解释更多结构。
推荐阅读
- r - 如何计算小计并将其添加到同一数据框中?
- javascript - Redux 未捕获类型错误:调度的操作不是函数
- asp.net-mvc - 验证不适用于 mvc5 中的下拉菜单
- python - 如何在python中的mysql查询中使用like百分比(like %)
- javascript - Javascript 代码在 Safari 浏览器中不起作用
- outlook - 使用 Visualforce 电子邮件模板上的 ics 附件发送日历邀请时,Outlook 使用电子邮件主题作为事件标题
- serverless-framework - 如何在无服务器框架中将 CF 资源定义为函数事件源
- php - PHP - 从唯一验证中排除当前电子邮件
- apache-kafka - Kafka:从 Windows 机器向 kerberized 集群发送消息
- sql - 如何通过 ID 连接一个表中的 2 行