我正在尝试检测Android设备的bash shell中ELF二进制文件的位数(32位或64位)。
我没有file
,objdump
或readelf
,这是真正Linux系统上的明显答案。此外,我没有head
,tail
,sed
,awk
,grep
或perl
。
我在ELF header description中看到二进制标头的e_ident[EI_CLASS]
字段应该包含一个描述位数的字节。也许我可以用它?但是我在使用如此有限的工具集从文件中取出该字节时遇到了麻烦。
答案 0 :(得分:2)
感谢Charles Duffy对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位。
答案 1 :(得分:1)
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位。如果它是其他任何东西,那么它目前是未定义的。
编辑:
推荐的read(hehe pun intention)描述了-n
和-N
之间的差异。
因此,如果不使用head
和tail
,这会更好:
read -r -N 5 elf_header < ${executable} && echo -n "${elf_header:4:1}"
此时,回显到stdout的单个字符对于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 "???"; }
答案 2 :(得分:1)
使用printf
和dd
:
#!/bin/sh
elf32="$(printf "\177ELF\001")"
elf64="$(printf "\177ELF\002")"
header="$(dd bs=5 seek=0 count=1 "if=$1" 2> /dev/null)"
case "$header" in
"$elf32") echo ELF32 ;;
"$elf64") echo ELF64 ;;
*) exit 1 ;;
esac