在 Android 上检查 ELF 二进制位数

Checking ELF binary bitness on Android

我正在尝试检测 android 设备的 bash shell 中 ELF 二进制文件的位数(32 位或 64 位)。

我没有 fileobjdumpreadelf,这些是真实 Linux 系统上的明显答案。此外,我没有 headtailsedawkgrepperl

我在 ELF header description 中看到二进制 header 的 e_ident[EI_CLASS] 字段应该包含一个描述位数的字节。也许我可以用那个?但是我无法使用如此有限的工具集从文件中提取该字节。

感谢 Charles Duffy's answer to How do I read first line using cat,我找到了一种方法来只从文件中读取我需要的字节:

$ # Read 5 bytes of the 'adb' binary.    
$ read -r -n 5 elf_header < /system/bin/adb; echo $elf_header | cat -v
^?ELF^A

如果该输出的第 7 个字符是 "A",则二进制文件是 32 位的。如果是 "B",则为 64 位。

https://en.wikipedia.org/wiki/Executable_and_Linkable_Format

head -c 20 ${executable} | tail -c 2 将为您提供 e_machine 的 2 个字节。然后你可以做进一步的处理。例如,x86 可能是 32 位或 64 位,而 x86-64 是 64 位。

或者,如果您专门寻找 ELF 容器的位数(而不是可执行代码),这意味着代码的要求,您可以尝试查看 e_ident[EI_CLASS]:

head -c 5 ${executable} | tail -c 1。如果字节为 0x01,则为 32 位。如果是0x02,就是64位。如果是别的,暂时未定义。

编辑: 推荐 reading(呵呵双关语)描述了 -n-N 之间的区别。

所以如果不使用 headtail,这样会更好: read -r -N 5 elf_header < ${executable} && echo -n "${elf_header:4:1}"

此时,回显到标准输出的单个字符对于 32 位为 "\x1",对于 64 位为 "\x2"。在更完整的 linux 环境中,您可以通过 xxd 传递它以查看十六进制转储。你可以用这个 1-liner 检查钻头:

bitness32=$(printf "\x1") && bitness64=$(printf "\x2") && read -r -N 5 elf_header < ~/a.out && elf_bitness="${elf_header:4:1}" && { [[ "${bitness32}" == "${elf_bitness}" ]] && echo "32-bit"; } || { [[ "${bitness64}" == "${elf_bitness}" ]] && echo "64-bit"; } || { echo "???"; }

使用 printfdd:

#!/bin/sh

elf32="$(printf "7ELF[=10=]1")"
elf64="$(printf "7ELF[=10=]2")"
header="$(dd bs=5 seek=0 count=1 "if=" 2> /dev/null)"

case "$header" in
    "$elf32") echo ELF32 ;;
    "$elf64") echo ELF64 ;;
    *)        exit 1 ;;
esac