NTFS文件系统解析(四)

1、引言

前文在非常驻属性中提及了Data Run,那么Data Run到底是什么呢?
简单来说,Data Run是一个指向实际数据存储的一个固定格式的数组。

2、Data Run

通常情况下,Data Run由一组或者多组数字组成。如下所示:

  • 21 18 34 56 00
    解析规则:
  1. 从数组中取出第1个Byte。
  2. 低8位代表簇个数的长度L。
  3. 高8位代表LCN的长度S。
  4. 从数组第二个Byte开始取出L个Byte,取出的数据C代表当前Data Run执行的数据的存在多少个簇。
  5. 从数组第1 + L 个Byte开始取出S个Byte,根据当前Data Run的位置:
    1. 第一个Data Run中,代表起始LCN号。
    2. 其它的Data Run中,代表与前一个LCN号的差值。(最高位大于0,则差值为负)

3、示例

示例1: 21 18 34 56 00

Run 1:

  • Header = 0x21 - 1 byte length, 2 byte offset
  • Length = 0x18
  • Offset = 0x5634

Run 2:

  • Header = 0x00 - the end

Summary:

  • 0x18 Clusters @ LCN 0x5634

示例2: 31 38 73 25 34 32 14 01 E5 11 02 31 42 AA 00 03 00

Run 1:

  • Header = 0x31 - 1 byte length, 3 byte offset
  • Length = 0x38
  • Offset = 0x342573

Run 2:

  • Header = 0x32 - 2 byte length, 3 byte offset
  • Length = 0x114
  • Offset = 0x211E5

Run 3:

  • Header = 0x31 - 1 byte length, 3 byte offset
  • Length = 0x42
  • Offset = 0x300AA

Run 4:

  • Header = 0x00 - the end

Summary:

  • 0x38 Clusters @ LCN 0x342573
  • 0x114 Clusters @ LCN 0x363758
  • 0x42 Clusters @ LCN 0x393802

示例3: 11 30 20 01 60 11 10 30 00
Run 1:

  • Header = 0x11 - 1 byte length, 1 byte offset
  • Length = 0x30
  • Offset = 0x20

Run 2:

  • Header = 0x01 - 1 byte length, 0 byte offset (sparse)
  • Length = 0x60
  • Offset = N/A

Run 3:

  • Header = 0x11 - 1 byte length, 1 byte offset
  • Length = 0x10
  • Offset = 0x30

Run 4:

  • Header = 0x00 - the end

Summary:

  • 0x30 Clusters @ LCN 0x20
  • 0x60 Clusters (sparse)
  • 0x10 Clusters @ LCN 0x50

4 、实现

bool CNonResidentAttr::PraseDataRun(b8 **data_run_p, b64 *num_cluster,
                                    b64 *lcn_offset) {
  b8 mark = **data_run_p;
  // data run len
  b8 length = mark & 0x0f;
  // data run offset
  b8 offset = mark >> 4;

  memcpy(num_cluster, (*data_run_p) + sizeof(mark), length);
  if (*num_cluster < 0) {
    return false;
  }

  *lcn_offset = 0;
  // when sparse, offset must be 0;
  if (offset) {
    // check last byte wheather minus,
    if ((b8)(*data_run_p)[length + offset] < 0) {
      *lcn_offset = -1;
    }
    memcpy(lcn_offset, (*data_run_p) + sizeof(mark) + length, offset);
  }

  *data_run_p += (sizeof(mark) + length + offset);
  return true;
}

你可能感兴趣的:(文件系统,NTFS,磁盘扫描)