我正在寻找任何可以实现以下功能的方法:从文件夹中每个输入文件读取偏移量 Y 处的 X 字节,然后将其添加到单个输出文件的末尾。例如,有一个包含许多视频文件片段的文件夹,想法是读取第一个文件偏移量 1024 处的 16 个字节,将其写入新文件,然后添加换行符,然后以此类推处理整个文件夹。然后,该文件将用作关键字列表,以便在 WinHex 中同时进行搜索,以便解决那个问题。
我曾经用 ddrescue 做过类似的事情。这里我需要一个在 Windows 上工作的方法。我发现 ddrescue 可以作为 Cygwin 端口在 Windows 上工作,但我无法让它处理单个文件。然后有一个适用于 Windows 的 dd 端口,它可以从输入文件中读取一块数据,但我找不到让它将该块写入输出文件末尾的方法。我知道两个命令行工具,称为 dsfo 和 dsfi(包含在德斯福克),它们各自可以完成一半的预期任务(dsfo 可以读取任何定义的数据块并将其提取为新文件,但不能将其写入现有文件;dsfi 可以将输入文件写入输出文件中的任何位置,但不允许定义输入文件的特定部分),我试图让它们在同一个脚本中一起工作但它失败了。
可以使用 PowerShell 完成此操作吗? 怎么做?
编辑(根据 Keith Miller 的建议):
此命令按预期工作:
foreach ($file in gci *.mts, *.vob) {
$16Bytes = [System.Text.Encoding]::Default.GetString([System.IO.File]::ReadAllBytes("$file"), 1024, 16)
Add-Content -path "G:\PowerShell search terms MTS-VOB.txt" -value $16Bytes
}
它从每个输入文件中读取偏移量为 1024 的 16 个字节并将其写入 TXT 文件,并自动在每个 ASCII 编码字符串后添加换行符 (0D 0A)(如果这是正确的术语),因此无需为此添加特定命令。
但它太慢了,就好像每个文件都被完整读取一样(如果我使用不同的偏移参数再次运行该命令,速度会快得多,可能是因为在第一次运行时文件被复制到了 RAM)。有没有办法加快这个过程,以确保每个文件只被解析相关部分?
另一个问题是,WinHex 似乎仅将搜索词列表导入/导出为“Unicode BOM”,而此 PS 脚本会生成 ANSI 文件。如果直接导入 ANSI 文件,列表将保持为空。我可以将该文件的输出复制到 WinHex,但如果存在“空”(00) 字符,它会被截断。如果我先使用 Notepad2 将 ANSI 文件转换为“Unicode BOM”,然后将其导入 WinHex 的搜索窗口,它也会被截断。但有一个名为“GREP 的直接字节转换”的选项,它允许执行任何字节序列的搜索,而不管代码页是什么。
摘自WinHex帮助文档:
您最多可以在 6 个代码页中同时搜索相同的搜索词。Windows 系统中活动的默认代码页标有星号,并且最初是预选的。例如,在美国和西欧的计算机上,通常默认的代码页是 1252 ANSI Latin I。名为“ANSI”的代码页用于 Microsoft Windows。“MAC”表示 Apple Macintosh 代码页。“OEM”表示 MS-DOS 和 Windows 命令提示符中使用的代码页。如果由于该代码页中存在未知字符而无法将搜索词转换为指定的代码页,则会发出警告。在名为“GREP 的直接字节转换”的“非”代码页中搜索时,可以进行独立于代码页的 GREP 搜索以获得精确的字节值,该代码页无需对某些代码页进行任何映射或大小写匹配即可转换字节值。 X-Ways Forensics 还允许在小端和大端 UTF-16 中进行搜索,以及在任何区域 Windows 代码页加上应用了 MS Outlook 密码(可压缩加密)的 UTF16 中进行搜索。
如果在 WinHex 中,我将一个小块复制为“GREP Hex”,它将以以下形式粘贴:
\xFC\x70\x28\x4C\x00\xB5\x47\x00\x52\x30\x96\xA3\x17\x51\x4A\x44
使用像这样格式的列表进行搜索,激活“GREP 语法”,并以“GREP 的直接字节转换”进行搜索,似乎可以可靠地工作,即使使用上面示例中的“00”字节也是如此。因此,基于文章在下面的评论中链接,我尝试了这个:
foreach ($file in gci *.mts, *.vob) {
$16Bytes = [System.Text.Encoding]::Default.GetString([System.IO.File]::ReadAllBytes("$file"), 100000, 32)
[System.BitConverter]::ToString($16Bytes)
Add-Content -path "G:\HGST_recherche_fragments_PowerShell_test_hex.txt" -value $16Bytes
}
但出现了多个这样的错误:
Impossible de convertir l'argument « 0 » (valeur « Qe▬?'QhNèJ↕?÷ß}÷ûï« → * l ?♠ @ ») de « ToString » en type « System.Byte[] » : « Impossible de con
vertir la valeur « Qe▬?'QhNèJ↕?÷ß}÷ûï« → * l ?♠ @ » en type « System.Byte[] ». Erreur : « Impossible de convertir la valeur « Qe▬?'QhNèJ↕?÷ß}÷ûï« →
* l ?♠ @ » en type « System.Byte ». Erreur : « Le format de la chaîne d'entrée est incorrect. » » »
Au niveau de ligne : 3 Caractère : 32
+ [System.BitConverter]::ToString <<<< ($16Bytes)
+ CategoryInfo : NotSpecified: (:) [], MethodException
+ FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument
显然这里有些地方不对,但是它越来越接近一种实际有效的方法...那么我怎样才能让 PS 读取偏移量 Y 处的 X 字节并将它们写为十六进制值序列呢?
现在,为使此过程尽可能快速和轻松,还有一个额外的步骤是执行自动校验和比较,以便在获得可能匹配的文件列表后避免进行手动比较。我发现 WinHex 可以在整个卷内进行“逻辑搜索”,这意味着对于每个搜索命中,它可以报告绝对偏移量(相对于分区的开头)以及文件偏移量(在通过该分区的文件系统标识的文件中找到搜索字符串的位置,即使该文件是碎片化的或 NTFS 压缩的)。因此,一旦我有了搜索命中列表以及文件的路径/名称,我想要做的是:
– 计算文件“A”(从中复制搜索词的文件)的 MD5 校验和;
– 计算文件“B”(找到搜索词的命中的文件)中应该与文件“A”重合的块的 MD5 校验和;
– 将结果打印到报告文件中;
– 如果 MD5 校验和匹配,则意味着文件“A”完全且准确地包含在文件“B”中,因此可以删除;如果不匹配,则要么是误报(搜索词不够具体,要么原始文件碎片化,因此恢复的文件可能包含外部数据),在这种情况下必须手动检查。要
做到这一点,我必须在循环中为每对文件定义文件 B 中的块,该块从 开始[offset where the hit was found in file B] - [offset where the search term was copied from file A]
,到 结束[starting offset] + [size of file A]
。然后计算该块的 MD5 校验和、文件 A 的 MD5,并报告两个值是否匹配。
这似乎可以用一个简单的 PowerShell 脚本来完成?