第十七节_ELF_文件解析

第十七节 ELF 文件解析

(第1章 安卓逆向概论)

学习目标

学完本节,希望你能够:搞清 ELF 格式(头、节、程序头);会用 readelf、objdump、hexdump 解析 ELF;能从 ELF 里提符号表、函数地址、动态链接信息;会做 ELF 的静态分析和动态调试(GDB、Frida);能分析 Android 里的 libnative.so、做 Hook。


一、ELF 是啥?

用一句话说清楚

ELF(Executable and Linkable Format)是一种 Linux 和 Android 下的可执行文件格式,包括:

  • 可执行文件(Executable)
  • 共享库(Shared Object, .so)
  • 核心转储(Core Dump)

查看 ELF 文件

bash 复制代码
file libnative.so

示例输出:

复制代码
libnative.so: ELF 64-bit LSB shared object, ARM aarch64

解析 ELF 结构

bash 复制代码
readelf -h libnative.so


二、ELF 头里都有啥?

ELF 头部(ELF Header)

ELF 头部包含 ELF 文件的基本信息,如 架构、入口点、段表位置 等。

查看 ELF 头

bash 复制代码
readelf -h libnative.so

示例输出:

复制代码
ELF Header:
  Magic:   7f 45 4c 46  ...
  Class:   ELF64
  Data:    2's complement, little endian
  Entry point address: 0x0000000000001234

关键字段

字段 含义
Magic ELF 文件标识(7F 45 4C 46 -> .ELF)
Class ELF32 / ELF64
Data 小端/大端存储
Entry point 程序入口地址


三、程序头是啥?

程序头(Program Header)定义了 可执行文件的加载方式 ,指定 代码段、数据段、动态链接信息

查看程序头

bash 复制代码
readelf -l libnative.so

示例输出:

复制代码
Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz  MemSiz Flags Align
  LOAD           0x000000 0x000000  0x000000  0x1234   0x2000 R E 0x1000

关键字段

字段 含义
Type LOAD(可加载段), DYNAMIC(动态段), NOTE(调试信息)
VirtAddr 代码段/数据段的虚拟地址
Flags R(读), W(写), X(执行)


四、节表是啥?

节表(Section Header)描述了 ELF 文件的 各个节(代码段、数据段、符号表等)

查看节表

bash 复制代码
readelf -S libnative.so

示例输出:

复制代码
Section Headers:
  [Nr] Name          Type         Addr      Off    Size   ES Flg Lk Inf Al
  [ 1] .text         PROGBITS     0x000010  0x0010 0x1000 00  AX  0   0 16
  [ 2] .data         PROGBITS     0x002000  0x2000 0x2000 00  WA  0   0 16

关键段

节名 作用
.text 代码段(只读、可执行)
.data 数据段(读写)
.rodata 只读数据段
.bss 未初始化数据


五、符号表是啥?

符号表(Symbol Table)存储了 函数名、变量名与地址映射关系,用于调试和动态链接。

查看符号表

bash 复制代码
readelf -s libnative.so | grep " func"

示例输出:

复制代码
  1234: 00000000  123 FUNC  GLOBAL DEFAULT  UND printf

反查符号

bash 复制代码
nm -D libnative.so


六、动态链接信息咋看?

查看共享库依赖

bash 复制代码
ldd libnative.so

示例输出:

复制代码
libc.so => /lib/libc.so
libm.so => /lib/libm.so

查看动态段

bash 复制代码
readelf -d libnative.so


七、逆向里咋用 ELF?

1. 解析 ELF 头

bash 复制代码
readelf -h libnative.so

2. 解析符号表

bash 复制代码
nm -D libnative.so

3. 反汇编 ELF

bash 复制代码
objdump -d libnative.so | head -n 20

4. Hook ELF 运行时

使用 Frida Hook open()

js 复制代码
Java.perform(function() {
    var libc = Module.findExportByName(null, "open");
    Interceptor.attach(libc, {
        onEnter: function(args) {
            console.log("File Opened: " + Memory.readUtf8String(args[0]));
        }
    });
});


动手练一练

  1. 提取 ELF
bash 复制代码
adb shell run-as com.example.app cat /data/app/com.example.app/lib/arm64/libnative.so > libnative.so
  1. 解析 ELF
bash 复制代码
readelf -h libnative.so
readelf -S libnative.so
readelf -s libnative.so
  1. 反汇编
bash 复制代码
objdump -d libnative.so | head -n 20
  1. Hook open()
js 复制代码
Java.perform(function() {
    var libc = Module.findExportByName(null, "open");
    Interceptor.attach(libc, {
        onEnter: function(args) {
            console.log("File Opened: " + Memory.readUtf8String(args[0]));
        }
    });
});

本节小结

你只要记住这几条就行:ELF 有头、程序头、节表、符号表;头里有 Magic、Class、Entry;程序头管加载段,节表管 .text/.data/.rodata 等;用 readelf -h/-l/-S/-s 看结构,用 objdump 反汇编,用 Frida Hook 看运行时行为。


本节思考与练习

  1. 概念:ELF 头、程序头、节表各管啥?.text 和 .data 有啥区别?
  2. 动手:用 readelf -h/-S/-s 看一个 so 的头、节表、符号表。
  3. 动手:用 objdump -d 反汇编同一个 so 的 .text 段。
  4. 动手:用 Frida Hook 该 so 里的一个导出函数,打印参数。

下一节预告 :下一节讲 如何调试 Native 层(第十八节),把 GDB、gdbserver、Frida Hook Native 讲清楚。

相关推荐
长沙火山4 小时前
第十三节_Android_APP_目录结构
逆向·安卓逆向
长沙火山4 小时前
第十二节_Android_权限机制
逆向·安卓逆向
长沙火山4 小时前
第十六节_反汇编工具介绍
逆向·安卓逆向
长沙火山6 小时前
第十一节_Android_进程管理
逆向·安卓逆向
长沙火山6 小时前
第九节_Android_CPU_架构解析
逆向·安卓逆向
长沙火山1 天前
第六节_x86_vs_ARM_汇编
逆向·安卓逆向
泡泡以安1 天前
Android 逆向实战:从零突破某电商 App 登录接口全参数加密
android·爬虫·安卓逆向
长沙火山2 天前
第五节_汇编语言基础
逆向·安卓逆向
夏了茶糜3 天前
Electron应用逆向分析思路
逆向