根据NTFS - File - Search思路:Qt/C++中了解NTFS文件系统全解析系列

2025-02-05 06:06:45

整个列系列是基于开源项目NTFS-File-分区获得所有文件/目录列表的想法。

细节如下:

QT/C ++了解NTFS文件系统,了解MFT(文件表)主文件表(1)

介绍NTFS文件系统,通过MFT(文件表)主文件表比较数据的优点和缺点,简要介绍了NTFS-File-开源项目,并了解NTFS系统中引用的所有文章。 QT/C ++了解NTFS文件系统,分析磁盘的数据以指导扇区数据以获取MFT(文件表)主文件表偏移地址

阅读$ boot指南分区扇区数据,获取单个群集大小(4096字节),$ mft元数据大小(1024字节)和$ mft元数据的启动群集编号,计算磁盘磁盘上的$ mft元数据拍摄地址。 QT/C ++了解NTFS文件系统,获取第一个MFT表数据,分析文件的内容以查找第一个属性偏移地址

分析$ MFT元数据结构,并根据$ MFT元数据文件的记录标头获取属性的偏移地址。它用于以后分析0x80 $数据属性。居民属性和非常居民的属性

简要介绍$ MFT元数据.qt/c ++中的居民属性和非常居民的属性结构,了解NTFS文件系统,分析0x80 $数据属性并获得运行列表数据列表

根据0x80 $数据属性,查找间隔列表(运行列表数据列表)以存储所有$ MFT元数据数据。

根据前面获得的运行列表数据列表,

遍历所有运行列表数据列表读取所有$ mft元数据,并分析$属性的实际大小和$属性获取文件或目录,名称,磁盘分布大小,记录号,文件属性和其他信息

目录指南

前言

根据第一个MFT(文件表)的第一个MFT(文件表),获得的偏移地址,

获取第一个MFT(文件表)主文件表数据,分析文件记录标头的内容数据,然后获取第一个属性的偏移地址。

用于查找所有属性,直到找到$数据(0x80)属性并获取数据列表。

NTFS文件系统中的每个文件或目录都由一个或多个MFT(文件表)主文件表保存

数据列表是指所有MFT(文件表)主文件表位于区域磁盘的文件目录中的偏移地址列表

设置偏移地址,读取(1024)的数据字节,

参考ntfs-file-

//! 设置偏移量读取数据
DWORD ReadBytes(HANDLE m_hVolume,PVOID pBuffer, DWORD cbReadSize, UINT64 ullAbsoluteOffset)
{
    DWORD	dwNumberOfBytesRead=0;
    BOOL	bSuccess;
    if (ullAbsoluteOffset != UINT64_MAX)
    {
        LARGE_INTEGER liPosition;
        liPosition.QuadPart = ullAbsoluteOffset;
        LARGE_INTEGER liUpdatedPosition;
        if (SetFilePointerEx(m_hVolume, liPosition, &liUpdatedPosition, FILE_BEGIN))
            m_ullCurrentOffset = liUpdatedPosition.QuadPart;
        else
            return 0;
    }
    bSuccess = ReadFile(m_hVolume, pBuffer, cbReadSize, &dwNumberOfBytesRead, NULL);
    if (bSuccess) {
        m_ullCurrentOffset += cbReadSize;
    }
    return dwNumberOfBytesRead;
}
 //! 开始读取首个MFT表
PBYTE pbMFTBuffer = new BYTE[m_ullRecordSize];
UINT64 MFT_LCN= (UINT64)(m_BootRecord.MFT_LCN * m_BootRecord.BytesPerSector * m_BootRecord.SectorsPerCluster);
if (m_ullRecordSize != ReadBytes(m_hVolume,pbMFTBuffer, (INT64)m_ullRecordSize, MFT_LCN))
    goto out;
qDebug()<<"输出...";
for(int i=0;i<m_ullRecordSize;i++)
{
  Val+=QString("%1 ").arg(pbMFTBuffer[i],2,16,QLatin1Char('0')).toUpper();
  if((i+1)%16==0)
  {
      qDebug()<<Val;
      Val="";
  }
}
/*输出...
"46 49 4C 45 30 00 03 00 EC F3 01 ED 15 00 00 00 "
"01 00 01 00 38 00 01 00 B8 01 00 00 00 04 00 00 "
"00 00 00 00 00 00 00 00 17 00 00 00 00 00 00 00 "
"D6 03 00 00 00 00 00 00 10 00 00 00 60 00 00 00 "
"00 00 18 00 00 00 00 00 48 00 00 00 18 00 00 00 "
"A0 73 73 A7 99 E8 D7 01 A0 73 73 A7 99 E8 D7 01 "
"A0 73 73 A7 99 E8 D7 01 A0 73 73 A7 99 E8 D7 01 "
....
....
*/

在工具中,第一个MFT(文件表)主文件表是指导该扇区后的第16个扇区。

在这里插入图片描述

MFT(文件表)主文件表的分析

了解MFT(文件表)的结构对于了解NTFS文件系统的操作至关重要。以下是对MFT结构的详细说明:

MFT记录:

MFT由一系列固定尺寸记录组成,每个记录对应于文件,目录或元数据文件。

MFT记录包括文件或目录的元数据信息,例如文件属性,数据位置,文件名等。

MFT记录号:

每个MFT记录都有一个唯一的标识符,称为MFT记录号。

MFT记录号用于在MFT中找到和识别特定文件或目录。

摘要来自:MFT(文件表,主文件表)是操作系统中NTFS(新文件,新技术文件系统)的关键组件,用于存储文件和目录的元数据信息。 MFT与UNIX和Linux系统中的Inode相似,但实现却不同。

MFT是一组文件记录。卷中的每个文件都由一个或多个文件记录完全描述。用UNIX术语,文件记录等效于索引节点。给定文件描述的第一个文件记录称为基本文件记录,其他记录称为扩展文件记录。

文件记录由标题,几个可变长度属性和一个终端标签组成(简单)。

来自:file- $ mft(0)

-文件

以第一个MFT(文件表)主文件表作为一个示例来分析数据结构

MFT(文件表)主文件表以File0字符串开始。

分析文件记录标题布局($ MFT文件)

MFT表中的前48个字节是文件记录标头的内容。数据的数据结构获得了数据记录标头数据的属性。数据结构是:

字节大小描述

0x00

4个字节

(魔术'文件')

固定值必须是“文件”

0x04

2个字节

(到)

更新序列号的偏移

0x06

2个字节

(用(s)的单词大小

更新序列号并更新单词中的数组

0x08

8个字节

$(LSN)

日志序列编号(每个记录都经过修改,将使序列为Plus 1)

0x10

2个字节

序列号(用于记录文件记录的次数重复使用的次数,在删除文件时添加1,并跳过0个值。如果是0,则将其保留为0)

0x12

2个字节

硬链路计数

硬链数仅出现在基本文件记录中,目录中包含的项目数必须用于他

0x14

2个字节

到第一个

第一个属性流的偏移位置

0x16

2个字节

标志

按字节标记,1表示在记录期间,2表示记录是目录

0x18

4个字节

文件的实际尺寸

文件记录的实际大小(填写8个字节,即8个字节8个字节)

0x1c

4个字节

文件的大小

文件记录分布大小(填充到8个字节,即8个字节8个字节)

0x20

8个字节

文件到基本文件

相应基本文件记录的文件参考号(在扩展文件记录中使用,基本文件记录中的0,基本文件记录0x20属性存储相关信息的属性列表的属性列表)

0x28

2个字节

下一个ID

下一个免费ID号,添加新属性时,将值分配给新属性,然后值增加。如果重复使用IFT记录,请将其设置为0,第一个实例始终为0

0x2a

2个字节

XP

与4个字节保持一致

边框,在XP中使用,即此记录中使用的两个扇区的最后两个字节的值

0x2c

4个字节

XP

这个MFT

在XP中使用此MFT记录号

价值描述

0x01

表示正在使用记录

0x02

记录是目录(存在文件名索引)

0x04

是扩展名($目录中的记录设置)

0x08

有特殊的索引(对于包含索引的非注销记录设置:objid,配额,配额,配额,)

分配大小是磁盘上占据的空间。这应该是集群大小的倍数,并且可能等于MFT文件记录的大小。实际大小是记录中使用的字节数。

注意:实际尺寸将填充到8字节边界中。

参考:NTFS文件系统的详细说明(3)NTFS元素文件分析

-文件

请添加图片描述

定义一个48字节结构,对数据结构转换的对齐字节,例如NTFS-File-中的ER结构:


/*
* $MFT File Record Header Layout - 文件记录头布局 标准属性标题,
* MFT是一组文件记录。卷中的每个文件都由一个或多个这样的文件记录完整地描述。
* 在Unix术语中,文件记录相当于索引节点。描述给定文件的第一个文件记录称为基本文件记录,其他记录称为扩展文件记录。
* 文件记录由一个标题、几个可变长度属性和一个结束标记(简单地说就是0xFFFFFFFF)组成。
* https://flatcap.github.io/linux-ntfs/ntfs/concepts/file_record.html
*/
typedef struct MFT_FILE_RECORD_HEADER
{
    //!字节4 固定值 一定是"FILE"
    DWORD		Magic;					// "FILE" (0x454C4946)
    //!字节2 更新序列号的偏移
    WORD		UpdateSequenceOffset;	// Update Sequence offset - 偏移到更新序列
    //!字节2 更新序列号与更新数组以字为单位(s)
    WORD		SizeOfUpdateSequence;	// Size in words of Update Sequence - 	更新序列的字数
    //!字节8 日志序列号(每次记录被修改,都将导致该序列加1)
    ULONGLONG	LogSequenceNumber;		// $LogFile Sequence Number (LSN) - $日志文件序列号(LSN)
    //!字节2 序列号(用于记录本文件记录被重复使用的次数,每次文件删除时加1,跳过0值,如果为0,则保持为0)
    WORD		SequenceNumber;			// Sequence number - 序列号
    //!字节2 硬链接数 只出现在基本文件记录中,目录所含项数要使用到他
    WORD		HardLinkCount;			// Hard link count - 硬链接计数
    //!字节2 第一个属性流的偏移位置
    WORD		FirstAttributeOffset;	// First attribute offset - 到第一个属性的偏移量
    //!字节2 标志字节,1表示记录使用中,2表示该记录为目录
    WORD		Flags;
    //!字节4 文件记录实际大小(填充到8字节,即以8字节为边界)
    DWORD		RealSize;				// Real size of the FILE record - FILE记录的实际大小
    //!字节4 文件记录分配大小(填充到8字节,即以8字节为边界)
    DWORD		AllocatedSize;			// Allocated size of the FILE record - 文件记录的分配大小
    //!字节8 所对应的基本文件记录的文件参考号(扩展文件记录中使用,基本文件记录中为0,在基本文件记录的属性列表0x20属性存储中扩展文件记录的相关信息)
    ULONGLONG	FileReference;			// File reference to the base FILE record - 对基本文件记录的文件引用
    //!字节2 下一个自由ID号,当增加新的属性时,将该值分配给新属性,然后该值增加,如果IFT记录重新使用,则将它置0,第一个实例总是0
    WORD		NextAttributeId;        // 下一个属性Id
    //!字节2 边界, WINDOWS XP 中使用,也就是本记录使用的两个扇区的最后两个字节的值
    WORD		Align;                  // 对齐4字节边界
    //!字节4 WINDOWS XP中使用,本MFT记录号
    DWORD		RecordNumber;			// MFT Record Number - MFT记录号
}*PMFT_FILE_RECORD_HEADER;

PMFT_FILE_RECORD_HEADER header=(PMFT_FILE_RECORD_HEADER)pbMFTBuffer;
qDebug()<<"FirstAttributeOffset: "<<QString::number(header->FirstAttributeOffset,16).toUpper()<<" -> "<<QString::number(header->FirstAttributeOffset,10);
qDebug()<<"LogSequenceNumber: "<<QString::number(header->LogSequenceNumber,16).toUpper()<<" -> "<<QString::number(header->LogSequenceNumber,10);
qDebug()<<"Flags: "<<QString::number(header->Flags,16).toUpper()<<" -> "<<QString::number(header->Flags,10);
qDebug()<<"RealSize: "<<QString::number(header->RealSize,16).toUpper()<<" -> "<<QString::number(header->RealSize,10);
qDebug()<<"AllocatedSize: "<<QString::number(header->AllocatedSize,16).toUpper()<<" -> "<<QString::number(header->AllocatedSize,10);
/*
FirstAttributeOffset:  "38"  ->  "56"
LogSequenceNumber:  "15ED01F3EC"  ->  "94170641388"
Flags:  "1"  ->  "1"
RealSize:  "1B8"  ->  "440"
AllocatedSize:  "400"  ->  "1024"
*/

获取第一个属性偏移地址()从56个字节开始

如下所示:

在这里插入图片描述

标签: MFT
首页
欧意注册
欧意下载
联系