Linux基础 -- 使用readelf或gdb查看二进制的节与解析

使用 readelf -S 命令查看 ELF 文件的解析

前言

本文档介绍了如何使用 readelf -S 命令查看 ELF 文件的节表(Section Headers),以及如何结合 ASLR(Address Space Layout Randomization)技术,理解启用和禁用 ASLR 时 ELF 文件的差异。

使用 readelf -S 查看 ELF 文件的节表

1. 基本用法

假设有一个名为 example 的 ELF 文件,可以使用以下命令查看其节表:

readelf -S example

2. 输出示例及解析

以下是一个示例输出及其解析:

There are 29 section headers, starting at offset 0x1c20:

Section Headers:
  [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            0000000000000000 000000 000000 00      0   0  0
  [ 1] .interp           PROGBITS        0000000000000200 000200 00001c 00   A  0   0  1
  [ 2] .note.ABI-tag     NOTE            0000000000000220 000220 000020 00   A  0   0  4
  [ 3] .note.gnu.build-i NOTE            0000000000000240 000240 000024 00   A  0   0  4
  [ 4] .gnu.hash         GNU_HASH        0000000000000268 000268 000030 00   A  5   0  8
  ...
  [28] .shstrtab         STRTAB          0000000000000000 000840 000120 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), l (large)
  I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)

3. 解析各字段

  • [Nr]:节的索引号。
  • Name:节的名称。
  • Type:节的类型(例如,PROGBITSNOTESTRTAB等)。
  • Address:在内存中的加载地址。
  • Off:在文件中的偏移。
  • Size:节的大小。
  • ES:条目大小(对于含有表项的节,如符号表)。
  • Flg:节的标志(例如,A表示在内存中分配,X表示可执行等)。
  • Lk:关联的链接。
  • Inf:额外的信息。
  • Al:对齐。

ASLR(Address Space Layout Randomization)

ASLR 是一种内存保护技术,通过随机化进程的内存地址空间来防止攻击者预测内存地址。

不使用 ASLR

在不使用 ASLR 的情况下,每次程序加载到内存中的地址是固定的。例如,可以通过以下方式禁用 ASLR:

echo 0 | sudo tee /proc/sys/kernel/randomize_va_space

使用 ASLR

使用 ASLR 时,程序每次加载到内存中的地址都会变化。可以通过以下方式启用 ASLR:

echo 2 | sudo tee /proc/sys/kernel/randomize_va_space

查看差异

1. 不使用 ASLR

程序的各个节的加载地址固定。例如,.text 节(代码段)在每次运行时都加载到相同的内存地址。

2. 使用 ASLR

程序的各个节的加载地址是随机的。例如,.text 节在每次运行时加载到不同的内存地址。

可以通过多次运行 readelf -l 命令来查看程序加载地址的变化:

readelf -l ./example | grep LOAD

输出示例

不使用 ASLR
  LOAD           0x0000000000000000 0x0000000000400000 0x0000000000400000 0x001000 0x001000 R E 0x200000
  LOAD           0x0000000000001000 0x0000000000401000 0x0000000000401000 0x000100 0x000100 RW  0x200000
使用 ASLR
  LOAD           0x0000000000000000 0x0000000000400000 0x0000000000400000 0x001000 0x001000 R E 0x200000
  LOAD           0x0000000000001000 0x0000000000402000 0x0000000000402000 0x000100 0x000100 RW  0x200000

注意到 0x0000000000400000 地址会在每次运行时发生变化,这就是 ASLR 生效的结果。

使用 GDB 查看节的映射表

1. 启动 GDB 并加载程序

gdb ./example

2. 运行程序

在 GDB 提示符下输入:

(gdb) run

3. 查看节的映射

在 GDB 提示符下输入以下命令以查看节的映射信息:

(gdb) info files

输出示例:

Symbols from "/path/to/example".
Local exec file:
    `/path/to/example', file type elf64-x86-64.
    Entry point: 0x400400
    0x0000000000400238 - 0x0000000000400254 is .interp
    0x0000000000400254 - 0x0000000000400274 is .note.ABI-tag
    0x0000000000400274 - 0x0000000000400298 is .note.gnu.build-id
    0x0000000000400298 - 0x00000000004002c8 is .gnu.hash
    0x00000000004002c8 - 0x0000000000400300 is .dynsym
    0x0000000000400300 - 0x0000000000400328 is .dynstr
    0x0000000000400328 - 0x0000000000400330 is .gnu.version
    ...
    0x0000000000601020 - 0x0000000000601040 is .fini_array
    0x0000000000601040 - 0x0000000000601048 is .jcr
    0x0000000000601048 - 0x0000000000601050 is .dynamic
    0x0000000000601050 - 0x0000000000601068 is .got
    0x0000000000601068 - 0x0000000000602000 is .got.plt
    0x0000000000602000 - 0x0000000000602018 is .data
    0x0000000000602018 - 0x0000000000602020 is .bss

该输出显示了各个节的内存地址范围及其名称。

结合 ASLR 查看映射差异

1. 禁用 ASLR

echo 0 | sudo tee /proc/sys/kernel/randomize_va_space

2. 再次运行程序并查看映射

重新启动 GDB 并运行程序,查看节的内存映射:

gdb ./example
(gdb) run
(gdb) info files

3. 启用 ASLR

echo 2 | sudo tee /proc/sys/kernel/randomize_va_space

4. 再次运行程序并查看映射

重新启动 GDB 并运行程序,查看节的内存映射:

gdb ./example
(gdb) run
(gdb) info files

比较这两次输出,可以观察到 ASLR 启用和禁用时,程序各个节加载地址的变化。这些变化正是 ASLR 工作的结果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值