你有没有考虑过类似这样的东西?
cat /dev/sdd1 | od -cv | sed s'/[0-9]* \(.*\)/\1/' | tr -d '\n' | sed s'/ F l/ F l/'g > v1
cat /dev/sdd1 | od -cv | sed s'/[0-9]* \(.*\)/\1/' | tr -d '\n' | sed s'/ F l/x F l/'g > v2
cmp -lb v1 v2
例如将此应用于一个.pdf文件。
od -cv phase-2-guidance.pdf | sed s'/[0-9]* \(.*\)/\1/' | tr -d '\n' | sed s'/ F l/ F l/'g > v1
od -cv phase-2-guidance.pdf | sed s'/[0-9]* \(.*\)/\1/' | tr -d '\n' | sed s'/ F l/ x l/'g > v2
cmp -l v1 v2
给出输出
228 106 F 170 x
23525 106 F 170 x
37737 106 F 170 x
48787 106 F 170 x
52577 106 F 170 x
56833 106 F 170 x
57869 106 F 170 x
118322 106 F 170 x
119342 106 F 170 x
第一列中的数字将是寻找模式开始的字节偏移量。这些字节偏移量乘以4,因为od每个字节使用四个字节。
在bash shell中的单行格式,无需编写大型临时文件,可以是:
od -cv phase-2-guidance.pdf | sed s'/[0-9]* \(.*\)/\1/' | tr -d '\n' | sed s'/ F l/ x l/'g | cmp -lb - <(od -cv phase-2-guidance.pdf | sed s'/[0-9]* \(.*\)/\1/' | tr -d '\n' | sed s'/ F l/ F l/'g )
这样可以避免需要将/dev/sdd1的内容写入临时文件。
以下是一个示例,查找USB驱动器上的PDF文件,并除以4和512以获取块号。
dd if=/dev/disk5s1 bs=512 count=100000 | od -cv | sed s'/[0-9]* \(.*\)/\1/' | tr -d '\n' | cmp -lb - <(dd if=/dev/disk5s1 bs=512 count=100000 | od -cv | sed s'/[0-9]* \(.*\)/\1/' | tr -d '\n' | sed s'/P D F/x D F/'g ) | awk '{print int($1/512/4)}' | head -10
测试这个会给出:
100000+0 records in
100000+0 records out
51200000 bytes transferred in 18.784280 secs (2725683 bytes/sec)
100000+0 records in
100000+0 records out
51200000 bytes transferred in 40.915697 secs (1251353 bytes/sec)
cmp: EOF on -
28913
32370
32425
33885
35097
35224
37177
38522
39981
41570
这里的数字是512字节块的编号。检查结果如下:
dd if=/dev/disk5s1 bs=512 skip=35224 count=1 | od -vc | grep P
0000340 \0 \0 \0 001 P D F C A R O \0 \0 \0 \0
这是一个实际的完整示例,使用磁盘并查找字符序列
live,其中字符由NUL分隔。
dd if=/dev/disk5s1 bs=512 count=100000 | od -cv | sed s'/[0-9]* \(.*\)/\1/' | tr -d '\n' | sed s'/l \\0 i \\0 v \\0 e/x \\0 i \\0 v \\0 e/'g | cmp -lb - <(dd if=/dev/disk5s1 bs=512 count=100000 | od -cv | sed s'/[0-9]* \(.*\)/\1/' | tr -d '\n' | sed s'/l \\0 i \\0 v \\0 e/l \\0 i \\0 v \\0 e/'g )
注意
- 这不会处理将模式分成非连续块的情况,其中该块会被分割。第二个sed,它执行模式和替换,可以被自定义程序所取代,该程序进行一些部分模式匹配,并在匹配字符数超过某个级别时进行替换。这可能会返回错误的结果,但可能是处理碎片化的唯一方法。
[[ $value =~ $re ]]
方法永远无法区分needle
和n<NUL>e<NUL>e<NUL><NUL>dle
。 - Charles Duffy$HAYSTACK=...
更改为HAYSTACK=...
;这是http://shellcheck.net/
可以自动识别的一个 bug 类型。 - Charles Duffyexec 3< <(dd if=/dev/sdd1 | tr '\0' '@'); sector_count=0; while IFS= read -r -N 2048 -d '' sector <&3; do (( ${#sector} == 2048 )) || { echo "Got a short read (${#sector} bytes) at sector $sector_count; aborting!"; exit 1; }; [[ $sector =~ "$needle" ]] && echo "Found needle at $sector_count"; (( ++sector_count )); done
- Charles Duffy