Sté*_*las 30
您必须弄清楚 gif 的结束位置和 7z 的开始位置。
如果您不知道 gif 文件的原始大小,您可以尝试找出文件的开头,7z
该文件应以字符开头7z
。
如果你幸运的话:
grep -boa 7z Afile
Run Code Online (Sandbox Code Playgroud)
(假设 GNU 实现grep
或兼容其非标准-b
(b
yte 偏移),-o
(o
仅输出匹配部分)-a
(a
所有文件,包括非文本文件))将仅返回一个:
<offset>:7z
Run Code Online (Sandbox Code Playgroud)
其中的行将<offset>
是文件中文件7z
开始处的偏移量。
然后,您可以使用以下命令提取它们:
tail -c +<offset+1> Afile > b.7z
head -c <offset> Afile > a.gif
Run Code Online (Sandbox Code Playgroud)
例如,如果grep
返回1234:7z
,则运行tail -c +1235 Afile > b.7z
和head -c 1234 > a.gif
。
如果grep
返回多个,其中一个将是 7z 文件的开头,而其他文件将只是恰好包含 0x37 0x7a(ASCII集中的7
和字符的值)字节序列的 gif 或 7z 文件。z
要确定哪个是正确的,您可以将tail -c
每个的输出通过管道传输到file -
哪个应该返回类似于7-zip archive data
正确的输出。或者甚至尝试列出其内容,bsdtar tf -
例如。
tail -c +<offset+1> Afile | file -
tail -c +<offset+1> Afile | bsdtar tf -
Run Code Online (Sandbox Code Playgroud)
该binwalk
实用程序可用于自动化该过程,因为它尝试在文件内查找文件格式签名(通常用于从固件映像中提取信息):
$ binwalk Afile
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
0 0x0 GIF image data, version "89a", 584 x 137
8570 0x217A 7-zip archive data, version 0.4
Run Code Online (Sandbox Code Playgroud)
理想情况下,正如 @Henrik 在评论中指出的那样,您需要查看 gif 部分元数据以获取有关 GIF 数据结尾位置的信息。我检查了 ImageMagick identify
、GNU extract
、perlImage::Info
和exiftool
报告图像信息的常用工具,不幸的是,它们都没有报告该信息。
通过研究GIF 图像格式规范,很可能可以手动完成此操作,另一种方法可能是连接到图像查看器或转换器,以查看它们在尝试解析文件时停止读取文件的位置。
我发现这款giftopnm
古老的netpbm
软件可以让我做到这一点。在 zsh 中:
zmodload zsh/system
{
giftopnm > /dev/null
head -c $(( systell(0) )) < Afile > a.gif
cat > b.7z
} < Afile
Run Code Online (Sandbox Code Playgroud)
在我的测试中,giftopnm
在转换为 pnm 后,将 gif 文件末尾处的位置保留在 stdin 中(我们在此将其丢弃)。
假设 gif 在数据结束后还没有额外的信息,这看起来并不罕见。例如,参见 libreoffice gallery/htmlexpo/bludown.gif
,它在有用数据末尾后有 212 个看似随机的字节。其中cut.gif
似乎openjdk
有 949 个额外字节(几乎是文件大小的 80%!),包括一些 Sun Microsystems 版权声明(未由 清理mat2
)