123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- #!/bin/bash
- progname="${0##*/}"
- progname="${progname%.sh}"
- # usage: check_elf_alignment.sh [path to *.so files|path to *.apk]
- cleanup_trap() {
- if [ -n "${tmp}" -a -d "${tmp}" ]; then
- rm -rf ${tmp}
- fi
- exit $1
- }
- usage() {
- echo "Host side script to check the ELF alignment of shared libraries."
- echo "Shared libraries are reported ALIGNED when their ELF regions are"
- echo "16 KB or 64 KB aligned. Otherwise they are reported as UNALIGNED."
- echo
- echo "Usage: ${progname} [input-path|input-APK|input-APEX]"
- }
- if [ ${#} -ne 1 ]; then
- usage
- exit
- fi
- case ${1} in
- --help | -h | -\?)
- usage
- exit
- ;;
- *)
- dir="${1}"
- ;;
- esac
- if ! [ -f "${dir}" -o -d "${dir}" ]; then
- echo "Invalid file: ${dir}" >&2
- exit 1
- fi
- if [[ "${dir}" == *.apk ]]; then
- trap 'cleanup_trap' EXIT
- echo
- echo "Recursively analyzing $dir"
- echo
- if { zipalign --help 2>&1 | grep -q "\-P <pagesize_kb>"; }; then
- echo "=== APK zip-alignment ==="
- zipalign -v -c -P 16 4 "${dir}" | egrep 'lib/arm64-v8a|lib/x86_64|Verification'
- echo "========================="
- else
- echo "NOTICE: Zip alignment check requires build-tools version 35.0.0-rc3 or higher."
- echo " You can install the latest build-tools by running the below command"
- echo " and updating your \$PATH:"
- echo
- echo " sdkmanager \"build-tools;35.0.0-rc3\""
- fi
- dir_filename=$(basename "${dir}")
- tmp=$(mktemp -d -t "${dir_filename%.apk}_out_XXXXX")
- unzip "${dir}" lib/* -d "${tmp}" >/dev/null 2>&1
- dir="${tmp}"
- fi
- if [[ "${dir}" == *.apex ]]; then
- trap 'cleanup_trap' EXIT
- echo
- echo "Recursively analyzing $dir"
- echo
- dir_filename=$(basename "${dir}")
- tmp=$(mktemp -d -t "${dir_filename%.apex}_out_XXXXX")
- deapexer extract "${dir}" "${tmp}" || { echo "Failed to deapex." && exit 1; }
- dir="${tmp}"
- fi
- RED="\e[31m"
- GREEN="\e[32m"
- ENDCOLOR="\e[0m"
- unaligned_libs=()
- unaligned_critical_libs=()
- echo
- echo "=== ELF alignment ==="
- matches="$(find "${dir}" -type f)"
- IFS=$'\n'
- for match in $matches; do
- # We could recursively call this script or rewrite it to though.
- [[ "${match}" == *".apk" ]] && echo "WARNING: doesn't recursively inspect .apk file: ${match}"
- [[ "${match}" == *".apex" ]] && echo "WARNING: doesn't recursively inspect .apex file: ${match}"
- [[ $(file "${match}") == *"ELF"* ]] || continue
- res="$(objdump -p "${match}" | grep LOAD | awk '{ print $NF }' | head -1)"
- if [[ $res =~ 2\*\*(1[4-9]|[2-9][0-9]|[1-9][0-9]{2,}) ]]; then
- echo -e "${match}: ${GREEN}ALIGNED${ENDCOLOR} ($res)"
- else
- unaligned_libs+=("${match}")
- # Check if this is a critical architecture (arm64-v8a or x86_64)
- if [[ "${match}" == *"arm64-v8a"* ]] || [[ "${match}" == *"x86_64"* ]]; then
- unaligned_critical_libs+=("${match}")
- echo -e "${match}: ${RED}UNALIGNED${ENDCOLOR} ($res)"
- else
- echo -e "${match}: UNALIGNED ($res)"
- fi
- fi
- done
- if [ ${#unaligned_libs[@]} -gt 0 ]; then
- echo -e "Found ${#unaligned_libs[@]} unaligned libs (only arm64-v8a/x86_64 libs need to be aligned).${ENDCOLOR}"
- fi
- echo "====================="
- # Exit with appropriate code: 1 if critical unaligned libs found, 0 otherwise
- if [ ${#unaligned_critical_libs[@]} -gt 0 ]; then
- echo -e "${RED}Found ${#unaligned_critical_libs[@]} critical unaligned libs.${ENDCOLOR}"
- exit 1
- else
- echo -e "${GREEN}ELF Verification Successful${ENDCOLOR}"
- exit 0
- fi
|