1

我需要检查执行给定二进制对象(不是通用二进制文件,而是 的输出gcc -c somefile.s)所需的最小 x86 指令扩展集。手工操作既费时又容易出错。我正在寻找一个自动化的过程。

我需要的是一些二进制,它给定一个二进制对象作为输入,返回一个类似于objdumpx86 指令扩展的输出。类似于以下示例:

$ 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, ...

有没有类似的工具可用?

4

2 回答 2

3

最简单和最可靠的选项是@PeterCordes 提到的:使用汇编器命令行选项来限制可用指令集。

如果您在使用不允许的指令扩展时需要编译时警告/错误,gas通过gcc以下代码段说明了一个仅允许通用 x86_64 指令以及 SSSE3 和 SHANI 扩展的示例;其他任何东西都会报错:

$ gcc -c -Wa,-march=generic64+ssse3+sha somefile.s

对于已经编译的二进制对象,我在出色的工具Zydisobjdump的帮助下破解了一个简单的脚本,该脚本通过每个指令扩展来扩展输出:

#!/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 "$LABEL\t$EXT\t$INSTR"
  fi
done < <(objdump --disassemble --wide --prefix-addresses --show-raw-insn "$1")

echo "Extensions:$EXTS"

注意:前面的代码没有尝试检查错误或意外状态。使用风险自负。

于 2019-12-31T15:51:53.410 回答
1

您可以使用 Intel 的X86 Encoder Decoder (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
...

如果您更喜欢 Intel 语法,则可以省略该-A参数。

于 2020-01-01T15:44:13.480 回答