NTFS文件系统解析(三)

news2024/11/29 1:29:02

1、引言

对于NTFS文件系统而言,无论文件内容本身,抑或真实的文件属性,都被称之为属性。
而正如前文说到的,NTFS预定义了16种属性用于文件系统的管理。
而通常情况下,往往只需要关注其中的某些属性即可。

2、属性头

为了便于管理,NTFS文件系统为所有的属性定义了统一的头部结构,可以称之为属性头。
而由于每种属性的长度不一,因此又额外定义了常驻属性和非常驻属性。

// 长度:0x10
typedef struct {
  b32 attr_type;  // 当前属性类型
  b32 length;     // 属性长度
  b8 non_resident;  // 常驻属性标识:0 - 常驻属性, 1 - 非常驻属性
  b8 name_length;   // 属性名长度:0 - 无名属性
  ub16 name_offset; // 属性名偏移:0x18
  ub16 flags;    //  
  ub16 attr_id;  // 
} AttributeHeader;

// 长度:0x8 + 0x10
typedef struct {
  AttributeHeader header;  // 属性头
  b32 length;              // 属性体长度
  ub16 offset;             // 属性偏移
  b8 index_flag;           // Indexed flag
  b8 padding;              // Padding
} ResidentAttrHeader;

// 长度:0x30 + 0x10
typedef struct {
  AttributeHeader header;  // 属性头
  b64 vcn_begin;           // 起始VCN号
  b64 vcn_end;             // 结束VCN号
  ub16 data_run_offset;    // Data Runs偏移
  ub16 compression_size;   // Compression unit size
  b32 padding;             // Padding
  b64 byte_alloc;          // 分配大小
  b64 byte_use;            // 实际使用大小
  b64 init_size;           // Initialized data size of the stream
} NonResidentAttrHeader;

3、$STANDARD_INFORMATION

$STANDARD_INFORMATION
常驻属性。通常情况下我们可以通过本属性获取文件时间和文件访问属性。

// 文件属性
typedef enum {
  READONLY = 0x0001,
  HIDDEN = 0x0002,
  SYSTEM = 0x0004,
  ARCHIVE = 0x0020,
  DEVICE = 0x0040,
  NORMAL = 0x0080,
  TEMPORARY = 0x0100,
  SPARSEFILE = 0x0200,
  REPARES_Point = 0x0400,
  COMPRESSED = 0x0800,
  OFFLINE = 0x1000,
  NOT_CONTENT_INDEXED = 0x2000,
  ENCRYPTED = 0x4000,
  DIRECTORY = 0x10000000,   //(copy from corresponding bit in MFT record)
  INDEX_VIEW = 0x20000000,  //(copy from corresponding bit in MFT record)
} FileAttrFlags;

// STANDARD_INFORMATION = 0x10,
typedef struct {
  b64 time_create;      // 文件创建时间
  b64 time_update;      // 文件修改时间
  b64 time_mft_change;  // 文件记录修改时间
  b64 time_access;      // 文件访问时间
  b32 file_attribute;   // 文件属性
  b32 max_version;      // 文件最大版本
  b32 version;          // 当前文件版本
  b32 class_id;         // Class Id
  b32 owner_id;         // Owner Id
  b32 security_id;      // Security Id
  b64 quota_charged;    // Quota charged
  b64 usn;              // USN Journel
} StdInformation;

4、$ATTRIBUTE_LIST

常驻/非常驻属性。

当一个文件或者文件夹存在多个文件记录时,主文件记录中会生成一个或多个ATTRIBUTE_LIST属性。在这种情况下,需要通过遍历ATTRIBUTE_LIST属性读取base_record_ref对应的文件记录。

// ATTRIBUTE_LIST = 0x20,
typedef struct {
  b32 attr_type;  // Attribute Type
  ub16 record_length;
  b8 name_length;
  b8 name_offset;
  b64 start_vcn;
  b64 base_record_ref;  // 文件记录号
  ub16 attr_id;
} AttrList;

5、$FILE_NAME

$FILE_NAME

常驻属性。通常情况下,一个文件只存在一个FILE_NAME属性,这种情况下,文件的基本属性与STANDARD_INFORMATION是保持一致的。

但是当文件系统结构变化时,如上图所示。或者当文件产生硬链接时,FILE_NAME属性都会增加。这种情况下,就需要对本属性做特殊处理。

// 文件名命名空间
typedef enum {
  POSIX_STYLE = 0,
  WIN32_STYLE,
  DOS_STYLE,
  WIN_DOS_STYLE,
} FileNameSpace;

// FILE_NAME = 0x30,
typedef struct {
  b64 parent_ref;       // 低6位存储当前文件记录号
  b64 time_create;      // 文件创建时间
  b64 time_update;      // 文件修改时间
  b64 time_mft_change;  // 文件记录修改时间
  b64 time_access;      // 文件访问时间
  b64 byte_alloc;       // 分配大小
  b64 byte_use;         // 实际使用大小
  b32 flags;            // 文件属性
  b32 ea_flags;         // 文件EA属性
  ub8 filename_length;  // 文件名长度(单位):字符 
  b8 name_space;        // 命名空间
} FileName;

6、$VOLUME_INFORMATION

常驻属性。通常情况下,卷信息属性只存储在Volume中。不需要特殊处理

// VOLUME_INFORMATION = 0x70,
typedef struct {
  b8 resv1[8];   // 00
  b8 major_ver;  // major version 1--winNT, 3--Win2000/XP
  b8 minor_ver;  // minor version 0--win2000, 1--WinXP/7
  ub16 flag;     // mark
  b8 resv2[4];   // 00
} VolumeInformation;

7、$DATA

常驻/非常驻属性。DATA属性用于存储文件本身的数据。当文件内容较少时,数据直接存储在DATA中。
当数据长度超过一定时,DATA中存储Data Runs,数据本身则异地存储。
注意:文件内容数据只存储在有名DATA属性中,因此通过DATA读取文件内容时需要对name_length进行判断。

8、$INDEX_ROOT

$INDEX_ROOT
常驻属性。索引根节点通常由标准属性头,索引根属性头,索引属性头和索引属性组成。
索引根属性头决定当前块存储的索引类型。通常情况下,索引中存储的都是0x30文件名属性。
正如上图所示,绿色部分代表IndexEntry的头部,紧接着的红色部分和黄色部分就是去除了标准属性头之后的0x30属性,而最后的紫色部分则存储着子节点的VCN号。

typedef enum {
  ENTRY_SUBNODE = 1,  // 存在子节点
  ENTRY_LAST = 2,     // 叶子节点
} IdxEntryTypes;

// INDEX_ROOT = 0x90,
typedef struct {
  // Index Root Header
  b32 attr_type;          // 属性类型
  b32 collation_rule;
  b32 index_size;         // 索引块大小
  b8 clusters_per_index;  // Clusters per index block (same as Bpb?)
  b8 padding[3];          // Padding
  // Index Header
  b32 entry_offset;  // 第一个索引的偏移
  b32 total_size;    // 索引数据的总大小
  b32 alloc_size;    // Allocated size of the index entries
  b8 flags;          // 索引标志
  b8 padding2[3];    // Padding
} IndexRoot;

typedef struct {
  b64 mft_ref;
  ub16 size;         // 索引大小
  ub16 stream_size;  // 数据流长度
  b8 flags;          // 索引标志
  b8 padding[3];     // Padding
  // copy of body(without header) of attribute
  /* Name | Index Of              | Used By
   * --------------------------------------
   * $I30 | Filenames	            | 目录
   * $SDH | Security Descriptors  | $Secure
   * $SII | Security Ids	        | $Secure
   * $O   | Object Ids	          | $ObjId
   * $O   | Owner Ids	            | $Quota
   * $Q   | Quotas	              | $Quota
   * $R   | Reparse Points	      | $Reparse
   */
  b8 stream[1];  // align to 8
  // VCN of the sub-node in the Index Allocation
} IndexEntry;

9、$INDEX_ALLOCATION

$INDEX_ALLOCATION

非常驻属性。INDEX_ALLOCATION的结构与INDEX_ROOT基本一致。唯一的差别在于一个是常驻属性,另一个是非常驻属性。

typedef struct {
  // Index Record Header
  b32 magic;        // "INDX"
  ub16 usn_offset;  // offset of update sequence number
  ub16 usn_size;    // size of update sequence number and array, by words
  b64 lsn;          // $LogFile sequence number
  b64 vcn;          // vcn of this index block in the index allocation
  // Index Header
  b32 entry_offset;  // Offset to the first index entry
  b32 total_size;    // Total size of the index entries
  b32 alloc_size;    // Allocated size of the index entries
  b8 flags;          // Non-leaf node Flag
  b8 padding[3];     // Padding
} IndexBlock;

typedef struct {
  b64 mft_ref;
  ub16 size;         // 索引大小
  ub16 stream_size;  // 数据流长度
  b8 flags;          // 索引标志
  b8 padding[3];     // Padding
  // copy of body(without header) of attribute
  /* Name | Index Of              | Used By
   * --------------------------------------
   * $I30 | Filenames	            | 目录
   * $SDH | Security Descriptors  | $Secure
   * $SII | Security Ids	        | $Secure
   * $O   | Object Ids	          | $ObjId
   * $O   | Owner Ids	            | $Quota
   * $Q   | Quotas	              | $Quota
   * $R   | Reparse Points	      | $Reparse
   */
  b8 stream[1];  // align to 8
  // VCN of the sub-node in the Index Allocation
} IndexEntry;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1174761.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

用户自定义消息及层次划分

有些人对术语 WM_USER 表示消息范围基的名称有不同的意见,因为 WM_USER 是由窗口类的实现者来定义的。他们抱怨的是,用户不能使用它们,因为它们属于窗口类定义的一部分。 但是,问题是,”这里的用户是谁?”…

【Mybatis小白从0到90%精讲】10:Mybatis动态SQL:foreach、choose标签

文章目录 前言一、foreach 标签二、choose、when、otherwise 标签前言 动态SQL 是 Mybatis的亮点功能之一,如果你经历过 拼接SQL 的繁琐痛苦,那么你就能切身感受到动态SQL到底有多爽!真香哈~ 另外,Mybatis将动态SQL设计的如此自然,让人看看就能理解和接受,我想这也是My…

谁说 Linux 不能玩游戏?

在上个世纪最早推出视频游戏的例子是托马斯戈德史密斯(Thomas T. Goldsmith Jr.)于1947年开发的“「Cathode Ray Tube Amusement Device」”,它已经显着发展,并且已成为人类生活中必不可少的一部分。 通过美国游戏行业的统计数据&…

【iOS】知乎日报前三周总结

这几天一直在进行知乎日报的仿写,仿写过程中积累了许多实用的开发经验,并对MVC有了更深的了解,特撰此篇作以总结 目录 第一周将网络请求封装在一个单例类Manager中SDWebImage库的简单使用运用时间戳处理当前时间自定义NavigationBar 第二周在…

求极限Lim x->0 (x-sinx)*e-²x / (1-x)⅓

题目如下: 解题思路: 这题运用了无穷小替换、洛必达法则、求导法则 具体解题思路如下: 1、首先带入x趋近于0,可以得到(0*1)/0,所以可以把e的-x的平方沈略掉 然后根据无穷小替换,利用t趋近于0时&#xf…

容器核心技术-Namespace

一、容器 基于Linux 内核的 Cgroup, Namespace,以及Union FS等技术,对进程进行封装隔离,属于操作系统层面的虚拟化技术,由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。 1.1 容器主要特性…

皮肤病辅助诊断软件,基于Android编写

1.系统介绍 编写的皮肤病辅助诊断软件,包括皮肤病识别、皮肤病区域分割、皮肤病信息介绍、识别历史记录查询、简单图像处理操作以及本机信息查询等功能 2.登录界面 运行之后首先显示登录界面 3.注册界面 注册一个账号 4.主界面 输入用户名密码点击登录按钮…

C语言——通讯录管理系统2.0版

对比之前C语言——通讯录管理系统初始版本,2.0版本有以下优化: 1.采用链表实现(之前版本是顺序表实现的,导致通讯录容量有限,现在使用链表实,实现了动态开辟空间,不浪费空间,也不会出…

用于3D Visual Grounding的多模态场景图

文章目录 引言方法1. Language Scene Graph Module Paper:《Free-form Description Guided 3D Visual Graph Network for Object Grounding in Point Cloud》【ICCV’2021】 Code:https://github.com/PNXD/FFL-3DOG 引言 3DVG任务有以下三个挑战&#x…

关于笔记平台的使用感受分享

关于笔记平台的使用感受分享 前言我用过的笔记平台笔记平台简单评价巴拉巴拉WPS文档/OneNote/TowerNotion/语雀各种博客平台 个人使用率最高的平台 前言 最近也有部分同学问我平常用的笔记平台是什么,以及我比较推荐的平台是什么。这里不是广告哈,因为我…

Spring AOP 简介

一、Spring AOP AOP 是一种思想,而 Spring AOP 是一个框架,提供了一种对 AOP 思想的实现。 1、什么是 AOP? AOP(Aspect Oriented Programming):是一种编程思想,表示面向切面编程。指的是对某…

<Vue>使用依赖注入的方式共享数据

什么是vue依赖注入? Vue是一个用于构建用户界面的渐进式框架。 它提供了一种简单而灵活的方式来管理组件之间的数据流,即依赖注入(Dependency Injection,DI)。 依赖注入是一种设计模式,它允许一个组件从另一…

【数组】有序数组的平方

## 977.有序数组的平方 力扣题目链接 (opens new window) 给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。 示例 1: 输入:nums [-4,-1,0,3,10]输出:[0,…

升级Python版本后,anaconda navigator启动失败

anaconda navigator启动失败,尤其是重装不解决问题的,大概率是库冲突 1.通过anaconda-navigator的图标启动,没有反应 2.在命令窗口,输入anaconda-navigator,报错如下 anaconda-navigator 3.错误来自这里 File &quo…

基于单片机的胎压监测系统的设计

收藏和点赞,您的关注是我创作的动力 文章目录 概要 一、系统整体设计方案二、 系统设计4.1 主流程图 三 系统仿真5.1 系统仿真调试实物 四、 结论 概要 本文以STC89C52单片机为控制核心,通过气压传感器模块对汽车各轮胎的胎压进行实时数据的采集与处理&…

AD教程 (七)元件的放置

AD教程 (七)元件的放置 第一种放置方法 点击右下角Panels,选择SCH Library,调出原理图库器件列表选中想要放置的元件,点击放置,就会自动跳转到原理图,然后放置即可这种方法需要不断打开元件库…

【源码解析】Spring Bean定义常见错误

案例1 隐式扫描不到Bean的定义 RestController public class HelloWorldController {RequestMapping(path "/hiii",method RequestMethod.GET)public String hi() {return "hi hellowrd";}}SpringBootApplication RestController public class Applicati…

立创eda专业版学习笔记(7)(阻焊开窗)

阻焊开窗是什么? 在介绍阻焊开窗之前,我们首先要知道阻焊层是什么。阻焊层是指印刷电路板子上要上油墨的部分,用于覆盖走线和敷铜,以保护PCB上的金属元素和防止短路。阻焊开窗是指在阻焊层上开一个口,以便在开口的位置…

前馈神经网络自动梯度计算和预定义算子

目录 1 自动梯度计算和预定义算子 1.1 利用预定义算子重新实现前馈神经网络 1.2 完善Runner类 1.3 模型训练 1.4 性能评价 1.5 增加一个3个神经元的隐藏层,再次实现二分类,并与1.1.1做对比. 1.6 自定义隐藏层层数和每个隐藏层中的神经元个数&#xf…

【网络安全技术】公钥密码体制

一、两种基本模型 1.加密模型 A要给B发信息,那就拿B的公钥加密,传给B,B收到后会拿他自己的私钥解密得到明文。 2.认证模型(数字签名) A用自己的私钥加密,传输之后,别人拿A的公钥解密&#xff…