20.34 二进制搜索 https://scz.617.cn/unix/201612071200.txt Q: 如何利用系统自带命令进行字节流搜索 A: scz 2016-12-07 grep支持二进制搜索: # grep -a -b -o -m 1 -e $'\x1f\x8b\x08' vmlinuz | cut -d: -f1 # grep -a -b -o -m 1 -P '\x1f\x8b\x08' vmlinuz | cut -d: -f1 # grep -a -b -o -m 1 -P '\x1f\x8b\x08' vmlinuz | awk -F: '{print $1}' 20912 20912是10进制偏移量 用grep做二进制搜索时有坑,务必提前做如下设置: $ export LANG=C 否则不是字节流搜索,UTF-8之类的干挠就来了,导致明明有却搜不到。此外,-o表 示仅显示匹配部分,但这个是以字符形式显示,而字节流中存在很多非可打印字符, 严重影响输出效果。 $ LANG=C grep -a -b -o -m 1 -P '\x1f\x8b\x08' vmlinuz | xxd -g 1 $ LANG=C grep -P '\xae\xee\x11\x44' vmlinuz $ LANG=C grep -l -P '\xae\xee\x11\x44' vmlinuz # od -Ax -tx1 -v vmlinuz | grep '1f 8b 08' 0051b0 1f 8b 08 00 33 53 42 46 02 03 ec fd 0b 78 54 d5 # xxd -g 1 vmlinuz | grep '1f 8b 08' 00051b0: 1f 8b 08 00 33 53 42 46 02 03 ec fd 0b 78 54 d5 ....3SBF.....xT. $ xxd -g 1 vmlinuz | grep -C 1 '1f 8b 08' 00051a0: 18 00 00 00 00 80 0b 00 04 e3 23 00 ed ec 12 00 ..........#..... 00051b0: 1f 8b 08 00 33 53 42 46 02 03 ec fd 0b 78 54 d5 ....3SBF.....xT. 00051c0: d5 38 8c 9f 99 39 93 4c 92 09 67 80 09 04 0d 10 .8...9.L..g..... 用od、xxd找"1F 8B 08"并不可靠,若这3个字节未出现在同一行,这种办法找不到。 $ xxd -g 0 -p vmlinuz | tr -d '\n' | grep -b -o 1f8b08 | awk -F: '{print $1/2}' 20912 进行二进制搜索时,可以使用正则表达式: $ grep -a -b -o -P '\x1f.\x08' vmlinuz | cut -d: -f1 20912 84663 92302 249646 417862 670514 700863 824763 955544 981185 1033232 1157670 1255088 $ xxd -s 20912 -g 1 -l 3 vmlinuz 00051b0: 1f 8b 08 ... $ xxd -s 1255088 -g 1 -l 3 vmlinuz 01326b0: 1f c7 08 ... $ for pos in $(grep -a -b -o -P '\x1f.\x08' vmlinuz | cut -d: -f1);do xxd -s $pos -g 1 -l 3 vmlinuz;done 00051b0: 1f 8b 08 ... 0014ab7: 1f c3 08 ... 001688e: 1f 41 08 .A. 003cf2e: 1f 2b 08 .+. 0066046: 1f ed 08 ... 00a3b32: 1f ca 08 ... 00ab1bf: 1f fe 08 ... 00c95bb: 1f 8c 08 ... 00e9498: 1f 38 08 .8. 00ef8c1: 1f c7 08 ... 00fc410: 1f e0 08 ... 011aa26: 1f c8 08 ... 01326b0: 1f c7 08 ...