Search code examples
androidbash32bit-64bitelf

Checking ELF binary bitness on Android


I'm trying to detect the bitness (32 or 64 bit) of an ELF binary in the bash shell of an android device.

I don't have file, objdump or readelf, which are the obvious answers on a real Linux system. Additionally, I don't have head, tail, sed, awk, grep or perl.

I've seen in the ELF header description that the e_ident[EI_CLASS] field of the binary header should contain a byte which describes the bitness. Maybe I could use that? But I'm having trouble teasing that byte out of the file with such a limited toolset.


Solution

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

    head -c 20 ${executable} | tail -c 2 will get you the 2 bytes for e_machine. Then you can do further processing on that. Eg, x86 may be either 32-bit or 64-bit while x86-64 is 64-bit.

    Alternatively, if you're specifically looking for the bitness of the ELF container (as opposed to the executable code), which implies the requirements of the code, you might try looking at e_ident[EI_CLASS]:

    head -c 5 ${executable} | tail -c 1. If the byte is 0x01, it's 32 bit. If it's 0x02, it's 64 bit. If it's anything else, it's undefined at this time.

    Edit: Recommended reading (hehe pun intended) describes the difference between -n and -N.

    So without the use of head and tail, this would be better: read -r -N 5 elf_header < ${executable} && echo -n "${elf_header:4:1}"

    At this point, the single character that was echoed to stdout would be "\\x1" for 32-bit and "\\x2" for 64-bit. In a more complete linux environment you can pass that through xxd to see a hex dump. You can check the bit with this 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 "???"; }