我需要检查执行给定二进制对象所需的最小x86指令扩展集(不是一般二进制文件,而是gcc -c somefile.s
的输出(。手动完成既耗时又容易出错。我正在寻找一个自动化的过程。
我需要的是一些二进制文件,它将二进制对象作为输入返回一个类似 x86 指令扩展的类似objdump
输出。类似于以下示例:
$ objdump-extended -d someobject.o
...
66 41 0f 38 00 c0 SSSE3 pshufb %xmm8,%xmm0
66 0f 6f d8 SSE2 movdqa %xmm0,%xmm3
66 0f fe 00 SSE2 paddd (%rax),%xmm0
0f 38 cb d1 SHANI sha256rnds2 %xmm0,%xmm1,%xmm2
...
Extensions used: SSE2, SSSE3, SHANI, ...
有类似的工具吗?
最简单和最可靠的选项是@PeterCordes提到的选项:使用汇编程序命令行选项来限制可用指令集。
如果在将不允许的指令扩展与gas
到gcc
一起使用时需要编译时警告/错误,以下代码片段演示了一个示例,该示例仅允许泛型x86_64指令加上 SSSE3 和 SHANI 扩展;其他任何扩展都将报告错误:
$ gcc -c -Wa,-march=generic64+ssse3+sha somefile.s
对于已经编译的二进制对象,我破解了一个简单的脚本,该脚本在优秀工具 Zydis 的帮助下通过每条指令扩展扩展objdump
输出:
#!/bin/bash
REGEX='^([0-9a-f]+)s+<(.*)>s+([0-9a-f][0-9a-f]( [0-9a-f][0-9a-f])*)s+(.*?)$'
EXTS=
while read -r LINE ; do
if [[ $LINE =~ $REGEX ]] ; then
ADDR=${BASH_REMATCH[1]}
LABEL=${BASH_REMATCH[2]}
HEX=${BASH_REMATCH[3]}
INSTR=${BASH_REMATCH[5]}
EXT=$(ZydisInfo -64 $HEX | grep ' ISA-EXT:' | cut -d ' ' -f 6)
[[ " $EXTS " != *" $EXT "* ]] && EXTS="$EXTS $EXT"
echo -e "$LABELt$EXTt$INSTR"
fi
done < <(objdump --disassemble --wide --prefix-addresses --show-raw-insn "$1")
echo "Extensions:$EXTS"
注意:前面的代码不会尝试检查错误或意外状态。使用风险自负。
您可以使用英特尔的 X86 编码器解码器 (XED( 来获得类似的输出。
指示:
git clone https://github.com/intelxed/xed.git xed
git clone https://github.com/intelxed/mbuild.git mbuild
cd xed
./mfile.py examples
obj/wkit/examples/obj/xed -A -i someobject.o
这将生成以下输出:
...
XDIS 0: SSE SSSE3 66410F3800C0 pshufb %xmm8, %xmm0
XDIS 6: DATAXFER SSE2 660F6FD8 movdqa %xmm0, %xmm3
XDIS a: SSE SSE2 660FFE00 padddx (%rax), %xmm0
XDIS e: SHA SHA 0F38CBD1 sha256rnds2 %xmm1, %xmm2
...
如果您更喜欢英特尔语法,则可以省略-A
参数。