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 ... 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 ... ... 011aa26: 1f c8 08 ... 01326b0: 1f c7 08 ... A: scz 2025-03-21 若允许使用第三方工具,选择更多,比如rafind2 $ r2 -v radare2 5.9.9 33622 @ linux-x86-32 r2的命令行参数未向后兼容,下面以r2 5.9.9版为例 export LANG=C echo -ne scz_is_here > some.bin grep -a -b -o -P '\x7a\x5f.\x73\x5f' some.bin | cut -d: -f1 rafind2 -x "7a5f69735f" some.bin rafind2 -x "7a5fcc735f" -M ffff00ffff some.bin (变相支持通配字节) rafind2 -s "z_is_" some.bin export F=some.bin for a in $(grep -a -b -o -P '\x7a\x5f.\x73\x5f' $F | cut -d: -f1) ; do \ xxd -g 1 -s $a -l 16 $F ; done for a in $(rafind2 -x "7a5fcc735f" -M ffff00ffff $F) ; do \ xxd -g 1 -s $a -l 16 $F ; done for a in $(rafind2 -x "7a5fcc735f" -M ffff00ffff $F) ; do \ r2 -ns $a -qc 'e hex.header=false;e hex.pairs=false;px 16' $F ; done D: scz 2025-03-21 非常不推荐r2的hexdump $ xxd -g 1 some.bin 00000000: 73 63 7a 5f 69 73 5f 68 65 72 65 scz_is_here $ xxd -g 1 -s 2 -l 16 some.bin 00000002: 7a 5f 69 73 5f 68 65 72 65 z_is_here r2的hexdump有病,若px的长度已越过文件尾,缺省用ff来填充显示,而非截止,这 什么狗屎毛病。xxd没这毛病。 $ r2 -ns 2 -qc 'e hex.header=false;e hex.pairs=false;px 16' some.bin 0x00000002 7a 5f 69 73 5f 68 65 72 65 ff ff ff ff ff ff ff z_is_here....... 可用io.unalloc、io.unalloc.ch改变缺省行为 $ r2 -ns 2 -qc 'e io.unalloc=true;e io.unalloc.ch=;e hex.header=false;e hex.pairs=false;px 16' some.bin 0x00000002 7a 5f 69 73 5f 68 65 72 65 z_is_here $ r2 -ns 2 -qc 'e io.unalloc=true;e io.unalloc.ch=?;e hex.header=false;e hex.pairs=false;px 16' some.bin 0x00000002 7a 5f 69 73 5f 68 65 72 65 ?? ?? ?? ?? ?? ?? ?? z_is_here