[英]How to dump part of binary file
我有二进制文件,想要提取部分内容,从知道字节字符串(即FF D8 FF D0)开始,以已知字节字符串结尾(AF FF D9)
在过去,我使用dd
从开始/结束切割部分二进制文件,但这个命令似乎不支持我的要求。
终端上的什么工具可以做到这一点?
找到开始/结束位置,然后提取范围。
$ xxd -g0 input.bin | grep -im1 FFD8FFD0 | awk -F: '{print $1}'
0000cb0
$ ^FFD8FFD0^AFFFD9^
0009590
$ dd ibs=1 count=$((0x9590-0xcb0+1)) skip=$((0xcb0)) if=input.bin of=output.bin
在一个管道中:
xxd -c1 -p file |
awk -v b="ffd8ffd0" -v e="aaffd9" '
found == 1 {
print $0
str = str $0
if (str == e) {found = 0; exit}
if (length(str) == length(e)) str = substr(str, 3)}
found == 0 {
str = str $0
if (str == b) {found = 1; print str; str = ""}
if (length(str) == length(b)) str = substr(str, 3)}
END{ exit found }' |
xxd -r -p > new_file
test ${PIPESTATUS[1]} -eq 0 || rm new_file
我们的想法是在两个xxd
之间使用awk
来选择所需文件的一部分。 找到第一个模式后, awk
打印字节,直到找到第二个模式并退出。
必须考虑找到第一个图案但不是第二个图案的情况。 它在awk
脚本的END
部分完成,返回非零退出状态。 这是由bash
的${PIPESTATUS[1]}
捕获的,我决定删除新文件。
请注意,空文件也意味着没有找到任何内容。
这应该适用于标准工具(xxd,tr,grep,awk,dd)。 这正确地处理了“跨行的模式分割”问题,也寻找仅在字节偏移(不是半字节)处对齐的模式。
file=<yourfile>
outfile=<youroutputfile>
startpattern="ff d8 ff d0"
endpattern="af ff d9"
xxd -g0 -c1 -ps ${file} | tr '\n' ' ' > ${file}.hex
start=$((($(grep -bo "${startpattern}" ${file}.hex\
| head -1 | awk -F: '{print $1}')-1)/3))
len=$((($(grep -bo "${endpattern}" ${file}.hex\
| head -1 | awk -F: '{print $1}')-1)/3-${start}))
dd ibs=1 count=${len} skip=${start} if=${file} of=${outfile}
注意:上面的脚本使用临时文件来防止二进制>十六进制转换两次。 空格/时间权衡是将xxd
的结果直接传递给两个grep
。 单透明也是可能的,但是以清晰度为代价。
也可以使用tee
和命名管道来防止必须存储临时文件并将输出转换两次,但我不确定它会更快(xxd很快)并且写入肯定更复杂。
有关二进制grep的方法,请参阅此链接 。 一旦你有开始和结束偏移量,你应该能够用dd
来获得你需要的东西。
awk
解决方案的变体,假设您的二进制文件一旦用十六进制转换为空格,就适合内存:
xxd -c1 -p file |
tr "\n" " " |
sed -n -e 's/.*\(ff d8 ff d0.*aa ff d9\).*/\1/p' |
xxd -r -p > new_file
sed
另一个解决方案,但使用更少的内存:
xxd -c1 -p file |
sed -n -e '1{N;N;N}' -e '/ff\nd8\nff\nd0/{:begin;p;s/.*//;n;bbegin}' -e 'N;D' |
sed -n -e '1{N;N}' -e '/aa\nff\nd9/{p;Q1}' -e 'P;N;D' |
xxd -r -p > new_file
test ${PIPESTATUS[2]} -eq 1 || rm new_file
第一个sed
从ff d8 ff d0
打印到文件末尾。 请注意,您需要尽可能多的N
in -e '1{N;N;N}'
因为第一个模式中的字节数少于1 。
第二个sed
从文件的开头打印到aa ff d9
。 再次注意,你需要尽可能多的N
in -e '1{N;N}'
因为你的第二个模式中的字节少了一个 。
同样,需要进行测试以检查是否找到第二个模式,如果不是,则删除该文件。
请注意, Q
命令是sed
的GNU扩展。 如果你没有它,你需要在找到模式后丢弃文件的其余部分(在第一个sed
类的循环中,但不打印文件),并在hex到二进制转换后检查new_file以怀特模式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.