卷序列号(例如 Windows 分区)应用于 MS Office 文件





5.00/5 (2投票s)
标记 Office 文件的实用技巧,或如何通过一个步骤使 Office 文件更改在统计上可见
引言
本文探讨了 VSN(卷序列号)计算算法的使用和实现,该算法增强了 Windows 操作系统进行的计算,以提供类似于 AB0C-1DEF 的字符串。这种字符串正是我们需要通过在命令提示符中键入 vol c:\ 或 vol d:\ 或 vol 其他字母来读取的,它被称为给定分区的卷序列号。
本文的目标是展示,Windows 在计算某个分区的卷序列号(VSN)时应用的相同算法,可以用于揭示由我们选择进行 VSN 计算的文件或文件夹的 VSN。
首先,请记住,给定分区的卷序列号是基于日期和时间计算的。换句话说,分区创建的时刻——日期(年、月、日)和时间(小时、分钟、秒和毫秒)——被转换为一个字母数字字符串,其中包含用于书写十六进制数字的字符(0-9 的数字和 A-F 的字母)——这就是 VSN 序列号看起来像 AB0C-1DEF 的原因。
分区的创建日期和时间通过一个开放、免费使用的算法进行处理,如下图所示
代码片段做了什么?
它将计算文件卷序列号所需的计算转换成 VB.NET 2010 代码,这些计算与 Windows 提供分区卷序列号所做的计算相同。实际上,我们需要:文件创建日期和时间(由原生 VB.NET 代码提供)、一个打开文件对话框,并且至少将文件创建日期和时间使用 hex(something) 方法转换为十六进制值。
注意:您选择用作计算样本的 Office 文件不会进行任何更改。上述解决方案只是一个**概念验证**,旨在**仅仅**演示如何计算文件的卷序列号,而不会通过将标签存储为文件内容或元数据来标记样本 Office 文件,也不会对您的任何文件进行任何其他更改!
VSN 算法如何工作以及此解决方案如何将其应用于 Office 文件?
首先,请关注上图,它解释了卷序列号算法
- 请注意上图中,文件**创建日期**中的月份(October)和日期(19th)以及**文件创建时间**中的秒(27)和百分之一秒(0.01)是如何分别转换为十六进制,以及如何合并结果以获得第一个十六进制和的项
- 关于文件创建日期和时间提供的其他项,文件创建时间(22 小时)、分钟(33 分钟)和文件创建年份(2003)也应用了相同的算法。现在,我们将小时、分钟和年份转换为十六进制后获得的字符串合并,得到了最终和的第二项。
- 最后一步是计算上面两个和之间的最终十六进制和。
上面获得的和反映了在 2003 年 10 月 19 日(**日期**)22 小时 33 分 27.001 秒(**时间**)创建的文件将提供 2514-1df4 作为**卷序列号**。
背景
为了更好地理解元数据——它们是如何由 Office 文件报告(如“创建日期”、“作者”)以及如何读取和修改它们,请阅读
PoC 做了什么?
它一步计算 Microsoft Office 文件的**卷序列号 (vol)**。**要计算您自己的文件的 VSN**,请下载 PoC 副本,它将帮助您提高对应用于 MS Office 文件的元数据和 Windows 变量的知识。
Using the Code
该代码不到 50 行(即,代码行数),其中很大一部分是计算用户加载进行计算的文件的 **VSN** 所需的算法。
首先,我们来提一下,原生的 VB.NET 代码提供了程序员用于提示文件生命周期中每个时刻的例程,例如:文件创建的日期和时间、文件上次保存、上次打印和上次修改的时间。我们的代码还仅使用 VB.NET 原生例程(例如 `directory.getfileinfo(...)`)提取在加载的 Office 文件上进行的每个操作的日期和时间。
让我们揭示以下内容的日期和时间
- 文件创建
- 上次保存
- 上次打印
- 上次修改
...使用下面的代码(**注意**:我们将使用文件创建时刻来进行提供 VSN 所需的计算)。
' Let us calculate the file creation date and time, used to calculate the VOL
Function file_cd(ByVal filename As String) As DateTime
file_cd = File.GetCreationTime(filename)
Return file_cd
End Function
' Now we reveal the date and time when the file was last accessed
Function file_la(ByVal filename As String) As DateTime
file_la = File.GetLastAccessTime(filename)
Return file_la
End Function
' Finally, the last written date and time moment of the file provides us how recent the user
' edited or simply saved the file we chose to analyse through these calculations
Function file_lw(ByVal filename As String) As DateTime
file_lw = File.GetLastWriteTime(filename)
Return file_lw
End Function
现在,我们将一步一步地了解文件创建日期和时间是如何被分割成元素,例如月份、日期和年份作为日期元素,以及小时、分钟、秒和百分之一秒作为时间元素。
我们从上面的引言段落中了解到,我们需要将日期元素和时间元素都转换为十六进制数字,才能使算法得以应用。让我们看看如何做到这一点
Dim cdatetime As DateTime = File.GetCreationTime(filename)
Dim hex_cmon As String = Hex(CInt(cdatetime.Month))
Dim hex_cday As String = Hex(CInt(cdatetime.Day))
Dim hex_csec As String = Hex(CInt(cdatetime.Second))
Dim hex_cms As String = Hex(CInt(Int((cdatetime.Millisecond / 10))))
Dim hex_chour As String = Hex(CInt(cdatetime.Hour))
Dim hex_cmin As String = Hex(CInt(cdatetime.Minute))
Dim hex_cyr As String = Hex(CInt(cdatetime.Year))
请注意,这些元素是根据 VSN 算法用于提供最终 VSN 字符串的顺序转换为十六进制数字的(有关更多学习,请参阅图片)。
下一步包括获得两个和,最后将它们相加,以提供我们选择作为计算样本的文件或文件夹的 VSN 标签,如下面代码的学习所示
Dim hex_cmon_cday As String = hex_cmon & hex_cday
Dim hex_csec_cms As String = hex_csec & hex_cms
Dim hex_chour_cmin As String = hex_chour & hex_cmin
' Dim hex_cyr As String = Hex(CInt(cdatetime.Year))
Dim vol_1, vol_2, vol_3, vol_4, vol_12, vol_34 As Long
vol_1 = CLng("&H" & hex_cmon_cday)
vol_2 = CLng("&H" & hex_csec_cms)
vol_3 = CLng("&H" & hex_chour_cmin)
vol_4 = CLng("&H" & hex_cyr)
vol_12 = vol_1 + vol_2
vol_34 = vol_3 + vol_4
最后,让我们获得需要读取为文件卷序列号的字符串。请记住,Windows 将此字符串显示为两组,每组 4 个字符(A 到 F 的字母和 0 到 9 的数字),由一个减号“-”分隔。(即,上图中显示的 VSN 是 2514-1df4。只要 0(零)被接受为 VSN 标签中的合法字符,最终结果将被截断,我的意思是 0 将不会显示(即,像 0ABC-1234 这样的 VSN 标签将显示为 ABC-1234——与 VOL 标签格式完全不符)。这就是为什么我们的代码中需要一些零,只要我们能使其动态化)。
为了便于理解,`first_sum` 在图中表示为 `2514`,`second_sum` 表示为 `1df4`。
Dim first_sum As String = Hex(vol_12)
Dim second_sum As String = Hex(vol_34)
If Len(first_sum) = 3 Then : first_sum = first_sum & 0
ElseIf Len(first_sum) = 2 Then : first_sum = first_sum & "00"
ElseIf Len(first_sum) = 1 Then : first_sum = first_sum & "000"
End If
If Len(second_sum) = 3 Then : second_sum = second_sum & 0
ElseIf Len(second_sum) = 2 Then : second_sum = second_sum & "00"
ElseIf Len(second_sum) = 1 Then : second_sum = second_sum & "000"
End If
vol = first_sum & "-" & second_sum
将任何文件的创建日期和时间转换所需的全部代码如下
(请注意,我们的软件需要加载一个文件,下面的代码会为该文件计算 VSN 标签。使用模块、表单和项目文件加载到 VB.NET 2010+ IDE 中的源代码可以在本文开头提供的下载档案中找到)。
Imports System.IO
Module mdlfiledate
Function file_cd(ByVal filename As String) As DateTime
file_cd = File.GetCreationTime(filename)
Return file_cd
End Function
Function file_la(ByVal filename As String) As DateTime
file_la = File.GetLastAccessTime(filename)
Return file_la
End Function
Function file_lw(ByVal filename As String) As DateTime
file_lw = File.GetLastWriteTime(filename)
Return file_lw
End Function
Function vol(ByVal filename As String) As String
Dim cdatetime As DateTime = File.GetCreationTime(filename)
Dim hex_cmon As String = Hex(CInt(cdatetime.Month))
Dim hex_cday As String = Hex(CInt(cdatetime.Day))
Dim hex_csec As String = Hex(CInt(cdatetime.Second))
Dim hex_cms As String = Hex(CInt(Int((cdatetime.Millisecond / 10))))
Dim hex_chour As String = Hex(CInt(cdatetime.Hour))
Dim hex_cmin As String = Hex(CInt(cdatetime.Minute))
Dim hex_cyr As String = Hex(CInt(cdatetime.Year))
Dim hex_cmon_cday As String = hex_cmon & hex_cday
Dim hex_csec_cms As String = hex_csec & hex_cms
Dim hex_chour_cmin As String = hex_chour & hex_cmin
' Dim hex_cyr As String = Hex(CInt(cdatetime.Year))
Dim vol_1, vol_2, vol_3, vol_4, vol_12, vol_34 As Long
vol_1 = CLng("&H" & hex_cmon_cday)
vol_2 = CLng("&H" & hex_csec_cms)
vol_3 = CLng("&H" & hex_chour_cmin)
vol_4 = CLng("&H" & hex_cyr)
vol_12 = vol_1 + vol_2
vol_34 = vol_3 + vol_4
Dim first_sum As String = Hex(vol_12)
Dim second_sum As String = Hex(vol_34)
If Len(first_sum) = 3 Then : first_sum = first_sum & 0
ElseIf Len(first_sum) = 2 Then : first_sum = first_sum & "00"
ElseIf Len(first_sum) = 1 Then : first_sum = first_sum & "000"
End If
If Len(second_sum) = 3 Then : second_sum = second_sum & 0
ElseIf Len(second_sum) = 2 Then : second_sum = second_sum & "00"
ElseIf Len(second_sum) = 1 Then : second_sum = second_sum & "000"
End If
vol = first_sum & "-" & second_sum
End Function
End Module
关注点
下载本文开头第二个链接后的可用代码。解压内容并使用 VB.NET IDE 加载项目文件。阅读代码,编译并享受!
注意:无论您运行的是什么 Windows 操作系统版本,都必须从 Windows 功能中激活 .NET 4.0 框架(如果已安装)。
历史
此项目没有可用的先前版本或概念。此代码的未来和改进版本将在测试和可用后立即发布。