ELF 文件结构分析 (6)

[ 2009-12-05 03:33:17 | 作者: yuhen ]
字号: | |
8. Section .rodata .data

.data 段包含了诸如全局变量、常量、静态局部变量之类的需要初始化的数据,而 .rodata 段则包含代码中的常量字符串(注意不是函数名这些符号名)等只读数据。.data 段是可写的,实际内容是指针或常量值,而 .rodata 则是个只读段。

为了查看实际效果,需要修改一下演示程序。
#include <stdio.h>

const char* format = "Hello, %s !\n";
char* name = "Q.yuhen";

int main(int argc, char* argv[])
{
    printf(format, name);                                                                    
    return 0;
}

我们开始分析编译后的程序文件。

$ objdump -dS -M intel hello | less
... ...

080483e4 <main>:

const char* format = "Hello, %s !\n";
char* name = "Q.yuhen";

int main(int argc, char* argv[])
{
    80483e4:  push   ebp
    80483e5:  mov    ebp,esp
    80483e7:  and    esp,0xfffffff0
    80483ea:  sub    esp,0x10
        printf(format, name);
    80483ed:  mov     edx,DWORD PTR ds:0x804a018 ; 变量 name
    80483f3:  mov    eax,ds:0x804a014 ; 常量 format
    80483f8:  mov    DWORD PTR [esp+0x4],edx
    80483fc:  mov    DWORD PTR [esp],eax
    80483ff:  call   804831c <printf@plt>
        return 0;
    8048404:  mov    eax,0x0
}
    8048409:  leave  
    804840a:  ret    
    804840b:  nop
    804840c:  nop
    804840d:  nop
    804840e:  nop
... ...

我们可以从符号表中找出相关的定义信息。通过对比,就可以知道汇编代码中的虚拟地址的实际含义。

$ readelf -s hello
... ...

Symbol table '.symtab' contains 76 entries:
    Num:    Value  Size Type    Bind   Vis      Ndx Name
    ... ...
    57: 0804a014     4 OBJECT  GLOBAL DEFAULT   24 format
    70: 0804a018     4 OBJECT  GLOBAL DEFAULT   24 name
    74: 080483e4    39 FUNC    GLOBAL DEFAULT   14 main
    ... ...

$ readelf -S hello
There are 38 section headers, starting at offset 0x16f0:

Section Headers:
    ... ...
    [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
    [16] .rodata           PROGBITS        080484c8 0004c8 00001d 00   A  0   0  4
    [24] .data             PROGBITS        0804a00c 00100c 000010 00  WA  0   0  4
    ... ...
Key to Flags:
    W (write), A (alloc), X (execute), M (merge), S (strings)
    I (info), L (link order), G (group), x (unknown)
    O (extra OS processing required) o (OS specific), p (processor specific)

format 和 name 都存储在 .data 段中,且该段是可写的,这表明该变量是多个栈共享。我们继续看看 .data 段中具体内容。

$ readelf -x .data hello
Hex dump of section '.data':
    0x0804a00c 00000000 00000000 d0840408 dd840408 ................

从符号表的 Value 值我们可以看到:

[format] = 0x080484d0
[name] = 0x080484dd

.data 中存储的指针显然指向 .rodata 段(0x080484c8 ~ 0x080484e5)。

$ readelf -x .rodata hello
Hex dump of section '.rodata':
    0x080484c8 03000000 01000200 48656c6c 6f2c2025 ........Hello, %
    0x080484d8 7320210a 00512e79 7568656e 00       s !..Q.yuhen.

.rodata 段果然也就是这些变量所指向的字符串。

9. Section .bss

.bss 段实际是执行后才会启用,并不占用文件空间(下面 .bss 和 .comment Offset 相同),相关细节可参考 Linux/ELF 内存布局分析之类文章。

$ readelf -S hello
There are 38 section headers, starting at offset 0x16f0:

Section Headers:
    [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
    ... ...
    [25] .bss              NOBITS          0804a01c 00101c 000008 00  WA  0   0  4
    [26] .comment          PROGBITS        00000000 00101c 000046 01  MS  0   0  1
    ... ...
Key to Flags:
    W (write), A (alloc), X (execute), M (merge), S (strings)
    I (info), L (link order), G (group), x (unknown)
    O (extra OS processing required) o (OS specific), p (processor specific)

$ readelf -x .bss hello
Section '.bss' has no data to dump.

--------- 分割线 -----------------

ELF 中我们常打交道的几个段:
  • .bss : 存储未初始化数据(未初始化的全局或静态局部变量),当程序开始运行时系统对这段数据初始为零,但该段并不占文件空间。
  • .data : 包含占据内存映像的初始化数据(包括已初始化的全局变量、静态局部变量等)。
  • .rodata : 包含程序映像中的只读数据,通常是代码中的常量字符串(注意不是函数名这些符号名)。
  • .shstrtab : 字符串表,包含 Section 名称。
  • .strtab : 字符串表,包含符号表记录(Symbol Table Entry)名称。
  • .symtab : 符号表,包含定位或重定位程序符号定义和引用时所需要的信息。
  • .text : 包含程序的可执行指令。
(完)
[最后修改由 yuhen, 于 2010-05-05 02:08:17]
评论Feed 评论Feed: http://www.rainsts.net/feed.asp?q=comment&id=891

这篇日志没有评论。

发表评论
表情图标
[smile] [confused] [cool] [cry]
[eek] [angry] [wink] [sweat]
[lol] [stun] [razz] [redface]
[rolleyes] [sad] [yes] [no]
[heart] [star] [music] [idea]
UBB代码
转换链接
表情图标
悄悄话
用户名:   密码:  
验证码 * 请输入验证码