系列文章目录
文章目录
- 前言
- 一、使用readelf工具查看程序代码变量的内存空间布局情况
- 1.1 源程序与程序的映射
- 1.2 程序到进程的映射
 
- 二、readelf指令
- 2.1 节头信息
- 2.2符号表段中的项
 
- 总结
前言
在现代软件开发中,了解和理解可执行文件和共享库的结构变得越来越重要。而readelf工具正是一个强大的工具,它能够帮助开发人员深入了解和分析可执行文件和共享库的结构和内容。通过readelf工具,我们可以获取有关文件的一些重要信息,如符号表、节区、动态链接等等。我们将从基础知识开始,介绍readelf工具的原理和功能。从而使读者能够更好地理解和分析可执行文件和共享库。无论是在调试、优化代码性能还是进行漏洞分析,掌握readelf工具都将为我们提供强大的工具和洞察力。
一、使用readelf工具查看程序代码变量的内存空间布局情况
1.1 源程序与程序的映射
| 段 | 描述 | 
|---|---|
| BSS段 | 存放未初始化的全局变量或静态变量,Block Started by Symbol | 
| DATA段 | 存放已初始化的变量 | 
| TEXT段 | 存放二进制代码 | 
1.2 程序到进程的映射
| 区 | 描述 | 
|---|---|
| 程序代码区 | 存放函数体二进制代码 | 
| 常量区 | 存放常量、字符串等,只读 | 
| 全局数据区 | 存放全局变量、静态变量等,可读可写 | 
| 堆区 | 存放进程运行中被动态分配的内存段,可动态扩展或缩减 | 
| 动态链接库 | 用于在程序运行期间加载和卸载动态链接库 | 
| 栈区 | 存放函数的参数值局部变量的值等 | 
#include<stdio.h>int v1;
int v2 = 0;
static int v3;
static int v4 = 4;int main(void)
{int v5;return 0;
}
v1、v2、v3都是未初始化的全局变量,所以在BSS段;
v4为已初始化的全局变量,所以在DATA段;
v5位局部变量,存储在栈(stack) 中。
注意:未初始化的全局变量和静态变量以及被初始化为0的全局和静态变量
二、readelf指令
在Linux中,可以使用readelf指令来查看相应的信息。ELF(The Executable and Linking Format),是Linux的主要可执行文件格式,包含三种:
- 可执行文件(.out)
- 可重定位文件(.o)
- 共享目标文件(.so)
readelf指令参数说明表:
| 指令 | 描述 | 
|---|---|
| readelf -h | elf header,头文件信息 | 
| readelf -l | program headers,显示程序头 (段头) 信息 | 
| readelf -S | section headers,显示节头信息 | 
| readelf -s | symbols,显示符号表段中的项 | 
| readelf -r | relocs,显示可重定位段的信息 | 
| readelf -d | dynamic,显示动态段的信息 | 
| readelf -V | version-info,显示版本段的信息 | 
| readelf -A | arch-specific,显示CPU构架信息 | 
| readelf -I | histogram,显示符号的时候,显示bucket list长度的柱状图 | 
| readelf -a | all 显示全部信息,等价于 -h -l -S -s -r -d -V -A -I | 
2.1 节头信息
There are 28 section headers, starting at offset 0x1950:节头:[号] 名称              类型             地址              偏移量大小              全体大小          旗标   链接   信息   对齐
......[13] .text             PROGBITS         00000000000004f0  000004f00000000000000192  0000000000000000  AX       0     0     16
......[15] .rodata           PROGBITS         0000000000000690  000006900000000000000004  0000000000000004  AM       0     0     4
......[22] .data             PROGBITS         0000000000201000  000010000000000000000014  0000000000000000  WA       0     0     8[23] .bss              NOBITS           0000000000201014  000010140000000000000014  0000000000000000  WA       0     0     42.2符号表段中的项
   Num:    Value          Size Type    Bind   Vis      Ndx Name......34: 000000000020101c     4 OBJECT  LOCAL  DEFAULT   23 v335: 0000000000201010     4 OBJECT  LOCAL  DEFAULT   22 v4......51: 0000000000201020     4 OBJECT  GLOBAL DEFAULT   23 v1......64: 0000000000201018     4 OBJECT  GLOBAL DEFAULT   23 v2
#include<stdio.h>int v1;
int v2 = 0;
static int v3;
static int v4 = 4;int main(void)
{int v5;return 0;
}
- v1: 未初始化变量,是一个GLOBAL符号,地址为0000000000201020,从Section Headers可以看到这个地址位于bss段;
- v2: 初始化变量为0,是一个GLOBAL符号,地址为0000000000201018,从Section Headers可以看到这个地址位于bss段;
- v3: 未初始化变量,但是被static修饰,所以为LOCAL,地址为000000000020101c,从Section Headers可以看到这个地址位于bss段;
- v4: 初始化变量为非0,但是被static修饰,所以为LOCAL,地址为0000000000201010,从Section Headers可以看到这个地址位于data段。