微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何从 Linux 命令行检查二进制文件是否包含在另一个二进制文件中?

如何解决如何从 Linux 命令行检查二进制文件是否包含在另一个二进制文件中?

基本上我想要一个“将二进制字符串作为模式的多行 grep”。

例如:

printf '\x00\x01\n\x02\x03' > big.bin
printf '\x01\n\x02' > small.bin
printf '\x00\n\x02' > small2.bin

那么以下应该成立:

  • small.bin 包含在 big.bin
  • small2.bin 不包含在 big.bin

我不想将文件转换为带有 xxd 的 ASCII 十六进制表示,如图所示at:https://unix.stackexchange.com/questions/217936/equivalent-command-to-grep-binary-files 因为那感觉很浪费。

理想情况下,该工具应该处理无法放入内存的大文件

请注意,以下尝试无效。

grep -f 匹配不应该的地方,因为它必须拆分换行符:

grep -F -f small.bin big.bin
# Correct: Binary file big.bin matches
grep -F -f small2.bin big.bin
# Wrong: Binary file big.bin matches

$(cat) 中的外壳替换失败,因为它是 impossible to handle null characters in Bash AFAIK,所以字符串在第一个 0 处被截断,我相信:

grep -F "$(cat small.bin)" big.bin
# Correct: Binary file big.bin matches
grep -F "$(cat small2.bin)" big.bin
# Wrong: Binary file big.bin matches

一个 C 问题已在:How can i check if binary file's content is found in other binary file? 提出,但是否可以使用任何广泛使用的 CLI(希望是 POSIX 或 GNU coreutils)工具?

值得注意的是,实现诸如 Boyer-Moore 之类的非朴素算法并非易事。

我可以按如下方式破解一个可用的 Python one liner,但它不适用于不适合内存的文件

grepbin() ( python -c 'import sys;sys.exit(not open(sys.argv[1]).read() in open(sys.argv[2]).read())' "$1" "$2" )
grepbin small.bin big.bin && echo 1
grepbin small2.bin big.bin && echo 2

我还可以在 GitHub 上找到以下两个工具:

但他们似乎不太支持文件获取模式,您在命令行上以十六进制 ASCII 的形式提供输入。我可以使用:

bgrep $(xxd -p small.bin | tr -d '\n') big.bin

因为小文件xxd 转换没有那么重要,但它不是很好。

无论如何,如果我要实现该功能,我很可能会将其用于上面的 Rust 库。

bgrep 也在:How does bgrep work?

在 Ubuntu 20.10 上测试。

解决方法

如何从 Linux 命令行检查二进制文件是否包含在另一个二进制文件中?

POSIX 可移植的方式是使用 od 转换为十六进制,然后使用 grep 检查子字符串,以及中间的一些 sed 脚本。

通常的可移植方式是使用 xxd 而不是 od

xxd -p small.bin | tr -d '[ \n]' > small.bin2
xxd -p big.bin | tr -d '[ \n]' > big.bin2
grep -F -f small.bin2 big.bin2

docker 上的 alpine 中使用 busybox 进行了很好的测试。

但是:

我不想将文件转换为带有 xxd 的 ASCII 十六进制表示,如图所示

那么你不能在shell中处理二进制文件。选择另一种语言。 Shell 是专门为解析漂亮的人类可读字符串而创建的 - 对于其他任何内容,它完全令人不快,对于零字节的文件 xxd 是您输入的第一件事。

我可以按如下方式编写一个可用的 Python one liner,

awk 也是 POSIX 并且随处可用 - 我相信在 awk 方面更熟练的人可能会来编写准确的 1:1 的 Python 脚本,但是:

但它不适用于不适合内存的文件:

所以写一个不同的算法,不会那样做。

总体而言,当给出不使用 xxd(或 od)将具有零字节的二进制文件转换为其十六进制表示的约束时:

是否可以使用任何广泛使用的 CLI(希望是 POSIX 或 GNU coreutils)工具?

没有。为此编写您自己的程序。您也可以在 perl 中编写它,它有时可以在没有 python 的机器上使用。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。