elf-hash-symbol.sh 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. #!/bin/bash
  2. set -euo pipefail
  3. if [ "$#" -ne 2 ]; then
  4. echo "Usage: $0 <path/to/elf_file> <symbol_name>" >&2
  5. exit 1
  6. fi
  7. ELF_FILE="$1"
  8. SYMBOL_NAME="$2"
  9. # 1. Get Symbol VA, Size, and Section Index (Ndx)
  10. # Output fields: [1]Value [2]Size [6]Ndx
  11. SYMBOL_DETAILS=$(readelf -Ws "$ELF_FILE" | grep -w "$SYMBOL_NAME" | head -n 1)
  12. if [ -z "$SYMBOL_DETAILS" ]; then
  13. echo "Error: Symbol '$SYMBOL_NAME' not found in '$ELF_FILE'." >&2
  14. exit 2
  15. fi
  16. read -r _ SYMBOL_VA SYMBOL_SIZE _ _ _ SYMBOL_NDX _ <<< "$SYMBOL_DETAILS"
  17. # Exit if size is zero or invalid
  18. if ! [[ "$SYMBOL_SIZE" =~ ^[0-9]+$ ]] || [ "$SYMBOL_SIZE" -eq 0 ]; then
  19. echo "Error: Symbol '$SYMBOL_NAME' has an invalid or zero size ($SYMBOL_SIZE)." >&2
  20. exit 3
  21. fi
  22. # 2. Get Section VA and File Offset using Ndx
  23. # Output fields: [4]Addr (VA) [5]Offset (File)
  24. SECTION_LINE=$(readelf -S "$ELF_FILE" | awk -v ndx="[$SYMBOL_NDX]" '$1 == ndx {print; exit}')
  25. if [ -z "$SECTION_LINE" ]; then
  26. echo "Error: Could not find section index $SYMBOL_NDX for symbol '$SYMBOL_NAME'." >&2
  27. exit 4
  28. fi
  29. read -r _ _ _ SECTION_VA SECTION_OFFSET _ <<< "$SECTION_LINE"
  30. # 3. Calculate the Absolute File Offset (Hex-to-Dec conversion is simplified)
  31. # We use shell arithmetic by prefixing with 16# (a Bash feature), which is cleaner than printf.
  32. # Ensure uppercase hex digits are used for shell arithmetic (readelf uses lowercase)
  33. SYMBOL_VA_UPPER="${SYMBOL_VA^^}"
  34. SECTION_VA_UPPER="${SECTION_VA^^}"
  35. SECTION_OFFSET_UPPER="${SECTION_OFFSET^^}"
  36. # Perform arithmetic directly using Bash's 16#BASE notation
  37. FILE_OFFSET_DEC=$(( 16#$SYMBOL_VA_UPPER - 16#$SECTION_VA_UPPER + 16#$SECTION_OFFSET_UPPER ))
  38. # 4. Extract Content and Hash
  39. echo "--- Symbol Details ---"
  40. echo "Symbol: $SYMBOL_NAME"
  41. echo "Size: $SYMBOL_SIZE bytes"
  42. echo "File Offset (Dec): $FILE_OFFSET_DEC"
  43. echo "----------------------"
  44. # dd command to extract and hash the content
  45. echo -n "Hash (SHA256): "
  46. dd if="$ELF_FILE" bs=1 skip="$FILE_OFFSET_DEC" count="$SYMBOL_SIZE" status=none 2>/dev/null | sha256sum | awk '{print $1}'