数据恢复(九)-从XFS_undelete源码分析XFS文件系统恢复原理

 数据恢复(九)-从XFS_undelete源码分析XFS文件系统恢复原理

工具源码链接

https://github.com/ianka/xfs_undelete

XFS文件系统删除原理

当文件在XFS文件系统中被删除时,虽然iNode被标记为空闲(使用特定的”IN\0\0″签名),但数据块和inode结构本身并不会立即被覆盖,核心在于iNode中存储的extent并没有被删除,即指向文件实际数据块block的指针。

这一点和EXT文件系统有着本质区别,EXT文件系统在删除文件时,是把iNode中对应的extent信息给填0,一旦被删除就找不到iNode和block的映射关系。

XFS_undelete恢复原理

XFS_undelete的核心原理基于XFS文件系统的以下特性:

  • 当文件被删除时,inode标记为删除状态(使用特定的”IN\0\0″签名)但实际内容仍保留在磁盘上
  • inode中存储了extent信息,即指向文件实际数据块的指针
  • 通过读取这些extent信息并复制对应的数据块,可以重建被删除的文件

所以XFS_undelete通过搜索所有被标记为删除的iNode即可找到被删除的文件。

XFS_undelete数据恢复流程

文件系统准备

程序首先确保文件系统以只读方式挂载,这样可以防止新数据写入覆盖被删除的文件。如果检测到文件系统以读写方式挂载,它会尝试重新挂载为只读模式。这一步非常关键,因为继续写入可能会覆盖待恢复的数据。

读取超级块

程序读取XFS超级块,获取文件系统参数,包括:

  • 块大小(blocksize)
  • 数据块总数(dblocks)
  • 分配组块数(agblocks)
  • 分配组数量(agcount)
  • 版本号(versionnum)
  • 扇区大小(sectsize)
  • inode大小(inodesize)
  • 每块inode数(inopblock)

这些参数对于理解文件系统结构和正确解析inode信息至关重要。

遍历inode B+树

程序遍历每个分配组(AG)的inode B+树结构,识别所有inode。这个过程通过递归遍历树节点实现,区分节点(node)和叶子(leaf):

  • 对于节点:继续递归遍历子节点
  • 对于叶子:检查包含的inode记录

识别已删除inode

程序在遍历inode时,寻找特定签名。具体而言:

  • 检查”IN”魔术字符串确认inode记录存在
  • 检查”IN\0\0″签名识别已删除但未覆盖的inode

时间筛选

恢复过程可以基于以下时间条件进行筛选:

  • 删除时间(ctime):文件被删除的时间
  • 修改时间(mtime):文件最后修改的时间

这允许用户恢复特定时间段内删除的文件。

extent信息提取

对于每个符合条件的已删除inode,程序提取extent信息。每个extent包含:

  • 逻辑偏移量(loffset):文件内的位置
  • 分配组号(aag):物理位置(分配组)
  • 分配块号(ablock):物理位置(块号)
  • 块数(count):连续的块数量

这些信息指示了文件数据在磁盘上的位置。

文件恢复

使用dd命令从源文件系统复制特定数据块到输出文件:

  1. 首先恢复第一个数据块以确定文件类型
  2. 使用file命令识别文件类型和MIME类型
  3. 根据文件类型添加适当的扩展名
  4. 恢复所有extent对应的数据块

XFS_undelete限制与局限性

基于代码分析,该工具存在一些固有限制:

  • 无法恢复目录结构或文件名
  • 无法保证文件完整性(特别是对于碎片化文件)
  • 可能无法恢复具有非标准存储模式的文件

XFS_undelete最大的局限性在于无法恢复大文件。

当文件被删除时,该工具仅依赖保留在inode中的区段信息进行恢复。由于物理空间限制,一个典型的512字节inode最多只能直接存储21个区段信息。超过这个数量的文件会使用B+树结构存储其区段信息,而现有的恢复工具(如xfs_undelete)并没有去解析这种复杂的树结构,因此无法恢复具有超过21个区段的文件。

赞赏

微信赞赏支付宝赞赏

Zgao

愿有一日,安全圈的师傅们都能用上Zgao写的工具。

发表评论