在第二季中,我们已经介绍了NK记录了。在这一季中,我们将要介绍的是NK记录最好的“伙伴”——VK记录。
VK记录
如果我们需要定义一个与NK记录相关的数值,那么就需要用到VK(数值项)记录中的信息了。下图显示的是磁盘中现有的一条VK记录实例:
下图显示的是另一条VK记录的实例:
你能发现这两个实例之间的区别吗?即便不能也没有关系,继续阅读这篇文章,你的问题就会迎刃而解。
在一条VK记录中,总共有10种类型的信息。这些信息几乎每一条都是非常重要的,主要包括:
| 大小(Size)
| 签名(Signature)
| 名称长度(Name length)
| 数据长度(Data length)
| 数据(Data)
| 类型(Type)
| 标识符(Flag)
| 名称(Name)
请注意,在一条VK记录之中,没有最后一次写操作的时间。这样一来,我们就无法得知一个给定项的最后一次更新时间了(除非一个给定项中只有一个数值)。
大小(Size)
VK记录的大小值起始于偏移量0x00处,系统使用了一个长度为32位的有符号整数来对它进行存储。在上述第一张截图中,其十六进制数值为0xD8FFFFFF(小端存储格式)。将这个十六进制数值进行转换,其十进制数值为-40。
VK记录大小跟NK记录的大小是一样,所以这条记录的实际大小为40个字节。
签名(Signature)
VK记录的签名起始于偏移量0x04处。VK记录的签名是ASCII码字符串“vk”,用十六进制表示即为0x766B。
命名长度(Name length)
命名长度值起始于偏移量0x06处,系统使用了一个长度为16位的无符号整数来对它进行存储,其长度为2个字节。
在第一个例子中,其命名长度值为0x0B00,转换成十进制即为11。在第二个例子中,其命名长度值为0x0000,转换成十进制即为0。
一个数值的命名长度为什么会为零呢?如果没有命名,那么我们怎么去表达一个数值呢?
通过regedit.exe(注册表编辑器)打开注册表之后,你可以看到在很多值的名称显示为(默认),不知道你曾经是否质疑过这一点。那是因为当注册表编辑器发现命名长度为0的值时,就会给这个值命名为(默认)。系统之所以这样操作,是因为在一个普通的注册表项中,系统通常会对相同的字符串进行一遍又一遍的存储操作,系统采用了这样的操作方式之后,效率会大大提高。
这就是上述两个例子中我所指的不同点。
在VK记录中,当命名长度为零的时候,命名就不存在。当命名长度大于零时,命名就存在。在第一个例子中,命名长度为11。虽然我没有指出这条记录名称的位置在哪,但是如果你仔细看第一个例子,你就会找到它的位置。在第一个例子中,数据值的命名称为‘Description’,其长度为11个字符。
数据长度(Data length)
数据长度值起始于偏移量0x08处,系统使用了一个长度为32位的无符号整数来对它进行存储。
在第一个例子中,其数据长度为0xB0000000,将其转换为十进制即得到176。在第二个例子中,数据长度为0x58000000,将其转换为十进制即得到88.
这些长度值看起来可能会有些奇怪。一个大小为40字节的VK记录怎么能容的下一个大小为176字节的值呢?我们将会在下一部分的讨论中为大家解答这个问题。
当我们分析数据长度的时候还有一个非常重要的东西需要了解,即驻留数据的概念。跟MFT记录相似,注册表可以在VK记录中直接存储足够小的数据。
如果想让问题变得更加的容易理解,那么我们还需要对另外一条VK记录进行分析:
在这个例子中,其数据长度为 0x02000080, 转换为十进制后得到2,147,483,650。我从未在注册表中见过这么大的值,这里肯定出现了问题。
判断数据是否驻留在VK记录中的关键就在于把数据长度转换为二进制格式,并检查其高阶位的数值。你应该还记得数据长度的值是一个32位的整数吧?所以当我们要把数据长度转换成二进制数值时,可以向转换所得到的二进制数的左边用0进行填充,然后变可以得到一个总长度为32个字符的数据了。
如果把前两个数据长度的大小转换成二进制,我们可以得到下列数据:
176 --> 00000000000000000000000010110000
88 --> 00000000000000000000000001011000
但是当我们在对最后一个例子采用同样的方式进行操作时,请注意发生了什么:
2,147,483,650 --> 10000000000000000000000000000010
在最后一个例子中,最高位是1,这种情况表示的就是该数据是驻留数据。一旦我们知道哪些数据是驻留数据时,我们就可以用数据长度减去0x80000000(0x80000002 – 0x80000000 == 0x02),从而得到实际的数据长度。
基于这些信息,你能猜出当数据是驻留数据时,一条VK记录所能容纳的最大数据长度是多少吗?
请继续阅读,你会得到答案的!
数据(Data)
数据起始于偏移量0x0c处,其长度为4个字节。
在第一例子中,数据为0x48000E00。第二个例子中,数据为0x304D8500。在讨论驻留数据的第三个例子中,数据为0x00000000。
有一点很重要,就是我们要找出VK记录的值占多少个字节。换言之,我们最终得到的数据将会是一段字节序列。在我们进入下一部分(类型Type)讨论之前,我们目前仍不知道如何将这些数据解析成为更加容易理解的东西。我们在下一部分将会对类型Type进行讨论。
当我们讨论到数据时,有两种情况我们必须要注意:有驻留数据的情况和无驻留数据的情况。
既然我们刚刚已经总结出了怎么判断数据是否为驻留数据,那么我们就先讨论有驻留数据的情形。
当数据驻留在VK记录中时,这也就意味着数据字节(在驻留数据例子中的0x00000000)就是VK记录的数据。虽然这看起来会有些奇怪,但是在我们讨论无驻留数据时,这些知识会变得更加有用。
既然你明白了这一点,那么回到我刚刚提到的问题,现在你应该有些思路了吧?既然数据只有4字节,那么驻留数据所能存储的最大字节数就是4。在我们上面的例子中,驻留数据长度为2,但是也有以下可能:
| 大小为4字节的数据占用了数据偏移量全部的4个字节
| 大小为2字节的数据占用了数据偏移量的最后两个字节(小端存储系统)
| 大小为1字节的数据占用了数据偏移量的最后一个字节(小端存储系统)
| 大小为0字节的数据表示值未被设置(或为空)
既然我们的驻留数据长度为2,那么记录中的数据字节数为0x0000。
驻留数据通常用来存储32位(或更小)的数据,以及一些可能很小的字符串。
既然有数据驻留的情形是比较罕见的,那么我们将会在第三季的下集来讲解无数据驻留的情形。敬请期待!
还没有评论,来说两句吧...