1#!/bin/bash 2progname="${0##*/}" 3progname="${progname%.sh}" 4 5# usage: check_elf_alignment.sh [path to *.so files|path to *.apk] 6 7cleanup_trap() { 8 if [ -n "${tmp}" -a -d "${tmp}" ]; then 9 rm -rf ${tmp} 10 fi 11 exit $1 12} 13 14usage() { 15 echo "Host side script to check the ELF alignment of shared libraries." 16 echo "Shared libraries are reported ALIGNED when their ELF regions are" 17 echo "16 KB or 64 KB aligned. Otherwise they are reported as UNALIGNED." 18 echo 19 echo "Usage: ${progname} [input-path|input-APK|input-APEX]" 20} 21 22if [ ${#} -ne 1 ]; then 23 usage 24 exit 25fi 26 27case ${1} in 28 --help | -h | -\?) 29 usage 30 exit 31 ;; 32 33 *) 34 dir="${1}" 35 ;; 36esac 37 38if ! [ -f "${dir}" -o -d "${dir}" ]; then 39 echo "Invalid file: ${dir}" >&2 40 exit 1 41fi 42 43if [[ "${dir}" == *.apk ]]; then 44 trap 'cleanup_trap' EXIT 45 46 echo 47 echo "Recursively analyzing $dir" 48 echo 49 50 if { zipalign --help 2>&1 | grep -q "\-P <pagesize_kb>"; }; then 51 echo "=== APK zip-alignment ===" 52 zipalign -v -c -P 16 4 "${dir}" | egrep 'lib/arm64-v8a|lib/x86_64|Verification' 53 echo "=========================" 54 else 55 echo "NOTICE: Zip alignment check requires build-tools version 35.0.0-rc3 or higher." 56 echo " You can install the latest build-tools by running the below command" 57 echo " and updating your \$PATH:" 58 echo 59 echo " sdkmanager \"build-tools;35.0.0-rc3\"" 60 fi 61 62 dir_filename=$(basename "${dir}") 63 tmp=$(mktemp -d -t "${dir_filename%.apk}_out_XXXXX") 64 unzip "${dir}" lib/* -d "${tmp}" >/dev/null 2>&1 65 dir="${tmp}" 66fi 67 68if [[ "${dir}" == *.apex ]]; then 69 trap 'cleanup_trap' EXIT 70 71 echo 72 echo "Recursively analyzing $dir" 73 echo 74 75 dir_filename=$(basename "${dir}") 76 tmp=$(mktemp -d -t "${dir_filename%.apex}_out_XXXXX") 77 deapexer extract "${dir}" "${tmp}" || { echo "Failed to deapex." && exit 1; } 78 dir="${tmp}" 79fi 80 81RED="\e[31m" 82GREEN="\e[32m" 83ENDCOLOR="\e[0m" 84 85unaligned_libs=() 86 87echo 88echo "=== ELF alignment ===" 89 90matches="$(find "${dir}" -type f)" 91IFS=$'\n' 92for match in $matches; do 93 # We could recursively call this script or rewrite it to though. 94 [[ "${match}" == *".apk" ]] && echo "WARNING: doesn't recursively inspect .apk file: ${match}" 95 [[ "${match}" == *".apex" ]] && echo "WARNING: doesn't recursively inspect .apex file: ${match}" 96 97 [[ $(file "${match}") == *"ELF"* ]] || continue 98 99 res="$(objdump -p "${match}" | grep LOAD | awk '{ print $NF }' | head -1)" 100 if [[ $res =~ 2\*\*(1[4-9]|[2-9][0-9]|[1-9][0-9]{2,}) ]]; then 101 echo -e "${match}: ${GREEN}ALIGNED${ENDCOLOR} ($res)" 102 else 103 echo -e "${match}: ${RED}UNALIGNED${ENDCOLOR} ($res)" 104 unaligned_libs+=("${match}") 105 fi 106done 107 108if [ ${#unaligned_libs[@]} -gt 0 ]; then 109 echo -e "${RED}Found ${#unaligned_libs[@]} unaligned libs (only arm64-v8a/x86_64 libs need to be aligned).${ENDCOLOR}" 110elif [ -n "${dir_filename}" ]; then 111 echo -e "ELF Verification Successful" 112fi 113echo "=====================" 114