使用readelf分析so文件
+ +++版权归作者所有,如有转发,请注明文章出处:https://cyrus-studio.github.io/blog/
+
readelf
+readelf 是一个用于读取和显示 ELF(Executable and Linkable Format)文件信息的工具。虽然 readelf 工具本身是为 Unix-like 操作系统设计的,但你可以在 Windows 上通过 WSL 使用它。
+WSL 允许你在 Windows 上运行 Linux 发行版,并且可以在其中使用 readelf 工具。
+安装 WSL
+打开 PowerShell 以管理员身份运行,并执行以下命令启用 WSL 并安装 Ubuntu 系统
+wsl --install -d Ubuntu
+
然后设置用户账户和密码。 +
+通过 wsl 命令进入 Ubuntu 系统。
+在 wsl 中 /mnt/d 对应的就是 windows 下的 D 盘,其他同理。
+使用 readelf
+调用 readelf -a 一次性查看文件中的所有信息,包括文件头、程序头、节头、符号表、动态节等。
+readelf -a libGameVMP.so
+
+ELF Header:
+ Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
+ Class: ELF64
+ Data: 2's complement, little endian
+ Version: 1 (current)
+ OS/ABI: UNIX - System V
+ ABI Version: 0
+ Type: DYN (Shared object file)
+ Machine: AArch64
+ Version: 0x1
+ Entry point address: 0x2650
+ Start of program headers: 64 (bytes into file)
+ Start of section headers: 130160 (bytes into file)
+ Flags: 0x0
+ Size of this header: 64 (bytes)
+ Size of program headers: 56 (bytes)
+ Number of program headers: 7
+ Size of section headers: 64 (bytes)
+ Number of section headers: 7
+ Section header string table index: 1
+
+Section Headers:
+ [Nr] Name Type Address Offset
+ Size EntSize Flags Link Info Align
+ [ 0] NULL 0000000000000000 00000000
+ 0000000000000000 0000000000000000 0 0 0
+ [ 1] .shstrtab STRTAB 000000000001fe30 0001fe30
+ 0000000000000035 0000000000000000 0 0 0
+ [ 2] .dynsym DYNSYM 0000000000000518 00000518
+ 0000000000000048 0000000000000018 A 3 1 4
+ [ 3] .dynstr STRTAB 0000000000000ec0 00000ec0
+ 0000000000000342 0000000000000000 A 0 0 0
+ [ 4] .symtab SYMTAB 000000000001fe65 0001fe65
+ 0000000000000048 0000000000000018 A 5 1 4
+ [ 5] .strtab STRTAB 000000000001fead 0001fead
+ 000000000000002b 0000000000000000 A 0 0 1
+ [ 6] .dynamic DYNAMIC 000000000006eae8 0001dae8
+ 0000000000000240 0000000000000008 AX 3 0 4
+Key to Flags:
+ W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
+ L (link order), O (extra OS processing required), G (group), T (TLS),
+ C (compressed), x (unknown), o (OS specific), E (exclude),
+ D (mbind), p (processor specific)
+
+There are no section groups in this file.
+
+Program Headers:
+ Type Offset VirtAddr PhysAddr
+ FileSiz MemSiz Flags Align
+ LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000
+ 0x000000000001cba4 0x000000000001cba4 R E 0x10000
+ LOAD 0x000000000001d9e8 0x000000000006e9e8 0x000000000006e9e8
+ 0x00000000000021de 0x0000000000002418 RW 0x1000
+ DYNAMIC 0x000000000001dae8 0x000000000006eae8 0x000000000006eae8
+ 0x0000000000000240 0x0000000000000240 RW 0x8
+ NOTE 0x00000000000001c8 0x00000000000001c8 0x00000000000001c8
+ 0x0000000000000024 0x0000000000000024 R 0x4
+ GNU_EH_FRAME 0x0000000000015634 0x0000000000056634 0x0000000000056634
+ 0x0000000000001afc 0x0000000000001afc R 0x4
+ GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
+ 0x0000000000000000 0x0000000000000000 RW 0x10
+ GNU_RELRO 0x000000000001d9e8 0x000000000006e9e8 0x000000000006e9e8
+ 0x0000000000000618 0x0000000000000618 R 0x1
+
+ Section to Segment mapping:
+ Segment Sections...
+ 00 .dynsym .dynstr
+ 01 .dynamic
+ 02 .dynamic
+ 03
+ 04
+ 05
+ 06 .dynamic
+
+Dynamic section at offset 0x1dae8 contains 32 entries:
+ Tag Type Name/Value
+ 0x0000000000000001 (NEEDED) Shared library: [liblog.so]
+ 0x0000000000000001 (NEEDED) Shared library: [libandroid.so]
+ 0x0000000000000001 (NEEDED) Shared library: [libz.so]
+ 0x0000000000000001 (NEEDED) Shared library: [libc.so]
+ 0x0000000000000001 (NEEDED) Shared library: [libm.so]
+ 0x0000000000000001 (NEEDED) Shared library: [libstdc++.so]
+ 0x0000000000000001 (NEEDED) Shared library: [libdl.so]
+ 0x000000000000000e (SONAME) Library soname: [libGameVMP.so]
+ 0x000000000000000c (INIT) 0x1bd68
+ 0x0000000000000019 (INIT_ARRAY) 0x6e9e8
+ 0x000000000000001b (INIT_ARRAYSZ) 216 (bytes)
+ 0x000000000000001a (FINI_ARRAY) 0x6eac0
+ 0x000000000000001c (FINI_ARRAYSZ) 16 (bytes)
+ 0x0000000000000004 (HASH) 0x1f0
+ 0x0000000000000005 (STRTAB) 0xec0
+ 0x0000000000000006 (SYMTAB) 0x518
+ 0x000000000000000a (STRSZ) 834 (bytes)
+ 0x000000000000000b (SYMENT) 24 (bytes)
+ 0x0000000000000003 (PLTGOT) 0x6ed28
+ 0x0000000000000002 (PLTRELSZ) 1488 (bytes)
+ 0x0000000000000014 (PLTREL) RELA
+ 0x0000000000000017 (JMPREL) 0x1c78
+ 0x0000000000000007 (RELA) 0x1330
+ 0x0000000000000008 (RELASZ) 2376 (bytes)
+ 0x0000000000000009 (RELAENT) 24 (bytes)
+ 0x0000000000000018 (BIND_NOW)
+ 0x000000006ffffffb (FLAGS_1) Flags: NOW
+ 0x000000006ffffffe (VERNEED) 0x12d0
+ 0x000000006fffffff (VERNEEDNUM) 3
+ 0x000000006ffffff0 (VERSYM) 0x1202
+ 0x000000006ffffff9 (RELACOUNT) 76
+ 0x0000000000000000 (NULL) 0x0
+
+There are no static relocations in this file.
+To see the dynamic relocations add --use-dynamic to the command line.
+
+The decoding of unwind sections for machine type AArch64 is not currently supported.
+
+Symbol table '.dynsym' contains 3 entries:
+ Num: Value Size Type Bind Vis Ndx Name
+ 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
+ 1: 0000000000002650 0 SECTION LOCAL DEFAULT bad section index[ 10]
+readelf: Warning: local symbol 1 found at index >= .dynsym's sh_info value of 1
+ 2: 000000000006ead0 0 SECTION LOCAL DEFAULT bad section index[ 16]
+readelf: Warning: local symbol 2 found at index >= .dynsym's sh_info value of 1
+
+Symbol table '.symtab' contains 3 entries:
+ Num: Value Size Type Bind Vis Ndx Name
+ 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
+ 1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __stack_chk_fail
+ 2: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __intel_security[...]
+
+Histogram for bucket list length (total of 97 buckets):
+ Length Number % of total Coverage
+ 0 38 ( 39.2%)
+ 1 29 ( 29.9%) 29.0%
+ 2 20 ( 20.6%) 69.0%
+ 3 9 ( 9.3%) 96.0%
+ 4 1 ( 1.0%) 100.0%
+
+No version information found in this file.
+
+Displaying notes found at file offset 0x000001c8 with length 0x00000024:
+ Owner Data size Description
+ GNU 0x00000014 NT_GNU_BUILD_ID (unique build ID bitstring)
+ Build ID: 7e55cc28965ecb053c55055043d9f1ed3260a498
+
自动化脚本
+新一个 soinfo.sh,编写一个简单的Shell脚本,调用 readelf -a 命令并将输出保存到同名的 .txt 文件中。
+#!/bin/bash
+
+# 检查是否提供了SO文件
+if [ -z "$1" ]; then
+ echo "Usage: $0 <path_to_so_file>"
+ exit 1
+fi
+
+# 提取输入文件的文件名
+so_file="$1"
+
+# 检查文件是否存在
+if [ ! -f "$so_file" ]; then
+ echo "Error: File '$so_file' not found!"
+ exit 1
+fi
+
+# 获取文件名(不含扩展名)
+base_name=$(basename "$so_file" .so)
+
+# 创建输出文件名(.txt文件)
+output_file="${base_name}.txt"
+
+# 调用 readelf -a 并将结果导出到输出文件
+readelf -a "$so_file" > "$output_file"
+
+# 提示用户操作成功
+echo "Information exported to $output_file"
+
创建 scripts 目录,并把 soinfo.sh 放到该目录下。 +执行 nano ~/.bashrc 命令,把 scripts 目录添加到环境变量
+export PATH=$PATH:/mnt/e/scripts
+
修改保存后,执行 source ~/.bashrc 使其生效。
+之后就可以调用 soinfo.sh <so_path> 将 SO 文件的信息导出到同名的 +.txt 文件
+soinfo.sh libGameVMP.so
+
+readelf: Warning: local symbol 1 found at index >= .dynsym's sh_info value of 1
+readelf: Warning: local symbol 2 found at index >= .dynsym's sh_info value of 1
+Information exported to libGameVMP.txt
+
+