NTFS文件系统文件寻址实操记录

news2024/11/15 20:27:48

前言

最近在学NTFS,发现网上的博客千篇一律,讲的不够通透,于是决定自己写一篇。

本文章通过寻找文件地址这个任务,讲述了NTFS文件系统$Boot文件、$MFT文件的结构,对$MFT文件中的A0、80属性进行了重点分析。

本文对于NTFS的具体每种属性的字段含义不会详细阐述,因此可以预先了解相关知识,或者在看到文中提到这些知识时使用搜索引擎详细查证一下。

个人认为讲的比较好的博客和资源:

  • https://www.cnblogs.com/lsh123/p/15789479.html
  • https://blog.csdn.net/enjoy5512/article/details/50935972
  • https://www.ntfs.com/ntfs-partition-boot-sector.htm
  • https://github.com/BigGan/Windows-Hack-Programming/issues/3
  • https://www.intohard.com/thread-61790-1-1.html

任务背景

在一块NTFS硬盘中存在如下文件:
在这里插入图片描述
其中demo文件夹中有如下文件:
在这里插入图片描述
目标是,通过解析NTFS底层数据,找到上述所有文件的源数据。

当然,无论是010 editor还是winhex还是各类工具,其实都能够很快的通过程序找到上述文件,但是为了探究系统文件寻址的底层流程,我们认为有必要在不使用解析程序的条件下走一遍这样的流程。

实验过程

使用winhex打开硬盘:
在这里插入图片描述
硬盘的前8个字节告诉我们这是一块NTFS的硬盘。

众所周知,NTFS包含了16个元文件和数据区,其结构如下:
在这里插入图片描述

其中最开头的Boot Sector则对应了$Boot元文件,它从0号扇区开始,向后占用16个扇区。Master File Table则对应了$MFT文件,其开始位置可以在$Boot元文件中找到。要找到硬盘文件的具体位置,主要就分析这两个文件。

1. 分析$Boot文件

$Boot文件(后简称Boot文件)在第一扇区(0号扇区),从偏移量为BH的位置开始,长度为73个字节的数据为文件内的BPB结果,该结构记录了有关文件系统的重要信息。

在样例中,Boot文件内容如下所示,图中勾选内容为其BPB字段。
在这里插入图片描述
BPB中比较重要的是如下几个字段:

Offsets数据含义
BH-CH00 02每个扇区512字节,0.5KB
DH08每个簇8个扇区,4096字节
30H-37H00 00 0C 00 00 00 00 00$MFT文件开始簇号为786432
40H-43HF6 00 00 00每个MFT记录占246簇
44H-47H01 00 00 00每个索引占1簇

此时可以通过上述数据计算$MFT文件所在扇区。由于一个簇8个扇区,因此$MFT文件所在扇区为786432x8=6291456,跳转到该扇区后数据内容如下所示:
在这里插入图片描述

2. 分析$MFT文件

$MFT文件(简称MFT文件)包含了多个文件目录项,每一个文件目录项占用2个扇区,以46 49 4C 45H(FILE)开头。并且,MFT文件中的第一个文件目录项必然是MFT元文件自身,第6个文件目录必然是根目录。为了找到具体的文件,我们需要找到根目录的文件目录项。由于MFT文件目录项所在扇区为786432x8=6291456,因此根目录文件目录项和MFT文件目录项相差5个扇区,在6291456+5x2=6291466扇区,数据内容如下。
在这里插入图片描述
一般而言,根目录的文件目录项中会存在10H、30H、40H、50H、90H、A0H、B0H几种属性,而根目录的具体内容则在A0H属性中解析。图中的A0H属性使用了run list。一般而言,属性的长度如果不够存数据,则会使用run list进行跳转,将数据存在另外的空间中。如果某属性只有1个run list的话,只需按照如下方式解析即可:
在这里插入图片描述
如果有多个run list,解析方式可以看这个链接:
https://github.com/BigGan/Windows-Hack-Programming/issues/3

基于这种方式,由于上图的run list为11 01 24H,解析结果说明run list指向的起始簇号为24H=36簇,即36x8=288扇区,且大小为1簇,即4KB。跳转到288扇区得到根目录的具体数据(索引缓冲区)如下:
在这里插入图片描述

3. 分析根目录索引缓冲区

文件目录索引缓冲区的阅读方法类似于单向链表的遍历方式,系统需要先从索引头开始,读取第一个索引项的起始位置,并且结合索引项的长度计算下一个索引项的起始位置。为了方便表述先假设上述缓冲区开始的偏移是0H(本来是24000H)。

索引缓冲区索引头以49 4E 44 58H(INDX)开头,在其偏移为18H处保存了第一个索引项的偏移地址,即图中的40H,因此得到第一个文件的索引项的开始位置为18H+40H=58H。从索引项的开头向后数的第9个字节,即偏移为8H的位置的一个字节,为该索引项的长度,图中为68H,因此得到该索引在68H+58H=C0H处结束,此时可以确定第一个文件的索引项内容如下:
在这里插入图片描述
以此类推,可以得到根目录中所有文件索引项的起始位置和大小:

文件ID开始位置索引项大小文件信息
158H68H
258H+68H=C0H68H
3C0H+68H=128H60H
134F0H68HCLEAN.PY
14558H60Hdemo文件夹
155B8H78Hpytorch_model.bin

解析根目录中索引项的目的在于读取文件的MFT参考号,这一数据项的含义在于确定该文件在MFT文件中是第几个文件记录。在索引项中,MFT参考号为索引项的第一个字节。以demo文件夹为例,其索引项如下所示:
在这里插入图片描述
得到其MFT参考号为29H,即41。这说明该文件夹是MFT文件中第41个文件记录。由于MFT文件在6291456扇区,而一个文件记录占用2个扇区,因此该文件夹的MFT文件记录在磁盘中的位置为6291456+41x2=6291538扇区,具体内容如下:
在这里插入图片描述

4.寻找demo文件夹和demo.txt

此时我们已经找到了demo文件夹的具体内容。为了找到demo文件夹中的demo.txt,我们需要解析其中的90H属性。

90H属性是索引根属性,A0H是索引分配属性。为什么之前根目录没有分析90H属性,而在demo文件夹这个目录中我们就要分析90H属性呢?
这和目录大小有关。当一个目录很小时,就可以完全存放在索引根属性(90H属性)中,这时该目录就只需要一个属性来描述。但是有的目录太大不能完全存放在索引根中时,这时就要用到$INDEX_ALLOCATION(A0H)索引分配属性来存放它的索引项。
而上面的demo文件夹中不存在A0H属性,说明90H属性足够存放目录内容

解析上述90H属性,发现其中只存在一个索引项,MFT参考号为2AH,即40,这意味着demo.txt存储在MFT文件的第40个文件记录中,计算得到该文件所在扇区编号为6291540,数据内容如下所示。
在这里插入图片描述
能很清楚的看到文本中的内容,说明数据读取无误。

5.寻找pytorch_mode.bin

在根目录索引缓冲区中,pytorch_model.bin的索引项如下所示:
在这里插入图片描述
其MFT参考号为为27H,用前文所述方法可以计算出文件的MFT目录项在6291534扇区,内容如下:
在这里插入图片描述
由于该文件是一个大文件,因此数据属性(80H属性)使用了run list。

第一个run list的内容为23 83 88 01 88 15,解析结果为,数据大小为018883H(100483),起始簇号为1588H(即5512簇,5512*8=44096扇区)。跳转到44096扇区,可以看到该文件的第一部分:

在这里插入图片描述
第二个run list为11 01 25,解析得出该文件在37簇,内容如下:

在这里插入图片描述

至此所有文件在底层的位置已经全部找到。

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

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

相关文章

k8s-pod详解

一、Pod基本概念: 1.pod介绍: Pod是kubernetes中最小的资源管理组件,Pod也是最小化运行容器化应用的资源对象。一个Pod代表着集群中运行的一个进程。kubernetes中其他大多数组件都是围绕着Pod来进行支撑和扩展Pod功能的,例如&am…

vs2013使用qt Linguist以及tr不生效问题

一、qt Linguist(语言家)步骤流程 1、创建翻译文件,在qt选项中 2.选择对应所需的语言,得到.ts后缀的翻译文件 3.创建.pro文件,并将.ts配置在.pro文件中 3.使用qt Linguist 打开创建好的以.ts为后缀的翻译文件,按图所示…

python中的条件语句

python中语句的执行顺序 默认情况下,python代码的执行顺序,是从上到下依次执行的,这个顺序是不会变的, python中的条件语句 电脑的CPU芯片是能够进行算术运算也能进行逻辑判断的。 条件语句能够表达“如果...否则...” 这样的语…

P451 try-Catch异常处理

//基本使用演示代码 public static void main(String[] args) { int num1 10; int num2 0; try { int res num1 / num2; }catch (Exception e) { System.out.println(e.getMessage()); } } public class TryCatchDetail { public static void main(String[] args) { //1. 如…

dubbo复习:(8)使用sentinel对服务进行降级

一、下载sentinel-dashboard控制台应用并在8080端口启动 二、项目添加springboot 和dubbo相关依赖(降级规则并未持久化,如果需要持久化,如果需要持久化降级规则,只需增加nacos相关依赖并在nacos中进行配置,然后配置app…

pyside6下没有designer.exe、pyside6-uic.exe等

使用conda安装的pyside6(conda install pyside6),发现pyside6目录下没有designer.exe、pyside6-uic.exe等;designer.exe在Miniconda3/Library/bin下 pyside6-uic.exe、pyside6-rcc.exe在Miniconda3\Scripts下 但是 使用pip安装…

前端nvm、nodejs、npm、cnpm、yarn安装教程(超详细图文,含卸载旧的nodejs,安装及环境变量配置)

最近换了新电脑,一开始在网上找了一个教程让下载nvm-noinstall.zip 压缩包解压使用,踩坑了,过程复杂最后报错无法用。 后来搜到下文教程,直接使用nvm。exe进行安装,方便快捷。下面这个文章写的很详细,从如何…

Spark搭建 Standalone模式详细步骤

Standalone模式概述: Standalone模式是Spark自带的一种集群模式(本地集群,不依赖与外部集群,比如Yarn),可以真实地在多个机器之间搭建Spark集群的环境。 Standalone是完整的Spark运行环境,其中: Master角…

失业潮中如何突围?优秀PPT案例助你职场逆袭

在这个变幻莫测的时代,失业潮像一场突如其来的暴风雨,许多人在职场的大海中迷失方向。但别担心,即使风浪再大,总有勇敢的航海者能够乘风破浪,找到属于自己的那片新大陆。 今天,我们就来聊聊,在…

leecode 1206|跳表的设计

跳表 跳表,一种链表数据结构,其增删改茶的效率能和平衡树相媲美 leecode1206 可以看上面的那个动画,动画效果很贴切。 我简单讲讲它的机制吧,每个节点不单单是一个,测试好几层,然后同一层的节点和统一节点…

软件杯 深度学习验证码识别 - 机器视觉 python opencv

文章目录 0 前言1 项目简介2 验证码识别步骤2.1 灰度处理&二值化2.2 去除边框2.3 图像降噪2.4 字符切割2.5 识别 3 基于tensorflow的验证码识别3.1 数据集3.2 基于tf的神经网络训练代码 4 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 &#x…

Hadoop3:客户端向HDFS写数据流的流程讲解(较枯燥)

一、场景描述 我们登陆HDFS的web端,上传一个大文件。 二、流程图 三、讲解 流程1(Client与NameNode交互) 1、HDFS client创建DistributedFileSystem,通过dfs与NameNode进行2次(一来一回4次)对话&#x…

MySQL多表关联查询习题

一、素材 -- Active: 1714203732007127.0.0.13306db_stu -- 1.创建student和score表 CREATE TABLE student ( id INT(10) NOT NULL UNIQUE PRIMARY KEY , name VARCHAR(20) NOT NULL , sex VARCHAR(4) , birth YEAR, department VARCHAR(20) , address VARCHAR(50) ); -- 创建…

langchain实战-从0到1搭建ai聊天机器人

介绍 当前,人工智能大模型公司如雨后春笋般迅速涌现,例如 OpenAI、文心一言、通义千问等,它们提供了成熟的 API 调用服务。然而,随之而来的是不同公司的繁琐协议接入过程,这让许多开发者感到头疼不已。有没有一种统一…

Redis常见数据类型(6)-set, zset

目录 Set 命令小结 内部编码 使用场景 用户画像 其它 Zset有序集合 普通指令 zadd zcard zcount zrange zrevrange ​编辑 zrangebyscore zpopmax/zpopmin bzpopmax/bzpopmin zrank/zrevrank zscore zrem zremrangebyrank zremrangebyscore Set 命令小结 …

COD论文笔记 Boundary-Guided Camouflaged Object Detection

动机 挑战性任务:伪装物体检测(COD)是一个重要且具有挑战性的任务,因为伪装物体往往与背景高度相似,使得准确识别和分割非常困难。现有方法的不足:现有的深度学习方法难以有效识别伪装物体的结构和细节&am…

【Rust日报】ratatui版本更新

[new ver] ratatui v0.26.3 一个构建终端用户界面的库。新版本包括: 修复Unicode 截断 bug对颜色更好地序列化更快的渲染弃用assert_buffer_eq宏暴露错误类型常量函数和类型 官网: https://ratatui.rs/ 链接: https://ratatui.rs/highlights/v0263/ [new lib] ansi2…

二十七篇:未来掌控:嵌入式系统的革命性进展

未来掌控:嵌入式系统的革命性进展 1. 引言:嵌入式系统的重要性及其在未来科技中的角色 在当今这个数字化迅速发展的时代,嵌入式系统已成为推动现代科技进步的基石。从智能手机到智能家居,从自动驾驶汽车到复杂的工业控制系统&…

读书笔记-Java并发编程的艺术--持续更新中

文章目录 第1章 并发编程的挑战1.1 上下文切换1.1.1 多线程一定快吗1.1.2 如何减少上下文切换 1.2 死锁1.3 资源限制的挑战 第2章 Java并发机制的底层实现原理第3章 Java内存模型第4章 Java编发编程基础第5章 Java中的锁第6章 Java并发容器和框架第7章 Java中的13个原子操作类第…

java人口老龄化社区服务与管理平台源码(springboot+vue+mysql)

风定落花生,歌声逐流水,大家好我是风歌,混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的人口老龄化社区服务与管理平台。项目源码以及部署相关请联系风歌,文末附上联系信息 。 项目简介: 人口老龄化…