点击(此处)折叠或打开
- #include <stdio.h>
- int main (int argc, char *argv[])
- {
- printf ("Hello World\n");
- return 0;
- }
图 1
执行:make hello 生成hello可执行文件(ELF格式).首先,我们可以通过readelf -h hello,来获取hello这个elf文件的头部信息(该信息放置在hello文件的头部,大小为64字节):
点击(此处)折叠或打开
- $ readelf -h hello
- 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: EXEC (Executable file)
- Machine: Advanced Micro Devices X86-64
- Version: 0x1
- Entry point address: 0x400430
- Start of program headers: 64 (bytes into file)
- Start of section headers: 6696 (bytes into file)
- Flags: 0x0
- Size of this header: 64 (bytes)
- Size of program headers: 56 (bytes)
- Number of program headers: 9
- Size of section headers: 64 (bytes)
- Number of section headers: 31
- Section header string table index: 28
图 2
当我们在shell命令行敲击./hello的时候,内核是怎么识别这是一个可执行文件(elf文件)的呢?其实,在shell进行运行的时候,busybox会将"./hello"当成execve系统函数参数进行传参即:execve("./hello", ["./hello"]) 。当Linux发生系统调用并陷入内核后,Linux内核将这个hello文件的从0开始的前面几个字节与.ELF(7f 45 4c 46)比较,如果一样,则是elf文件,如果不一样,则与"#!"进行比较,以此来查看是否为需要第三方解释的脚本语言(#!后面跟的是解释器的路径),如#!/bin/sh或者#!/usr/bin/python。上面提到的7f 45 4c 46就是一个elf文件的magic,一种固定elf标志即文件的识别码,其对应的ascii码是.ELF, 可以通过readelf -h hello获取到,如图2。
由图2可知,这个ELF文件支持的平台为X86-64,版本是0x1,入口地址是0x400430,段的起始地址是文件偏移6696字节处,Program Header在文件偏移64字节处即elf头信息之后。当前elf header占大小64字节,有9个program header和31个段等等,具体elf header格式,可以参考elf.h头文件。
温馨小提示:这里我们普及一下什么是section。我们常听说的section有代码段(TEXT段),BSS段,数据段(DATA段),只读数据段(RODATA段),HEAP, STACK等。在C语言中,.TEXT段主要用于存放函数对应的机器码的(也就是可执行程序的可运行部分),BSS段主要存放全局未初始化变量的(数据部分),DATA段主要存放全局并且已经初始化过的变量的(注意:初始化成0/NULL的全局变量会被认为是未初始化而放置到BSS段,因为BSS段的数据默认就是0/NULL),RODATA段用于存放const类型的变量,HEAP主要是分配内存使用,而STACK主要是用于函数调用和函数局部变量使用。
在讲ELF各个部分内容之前,我们先看看ELF文件的整体结构:
- +-----------------------+ hello文件偏移 0bytes
- | |
- | ELF Header |
- +-----------------------+ hello文件偏移 64bytes
- | |
- | Program Header |
- +-----------------------+ hello文件偏移 568bytes (64+56 * 9)
- | interpreter | (动态解释器位置)
- +-----------------------+
- | ....... |
- +-----------------------+ hello文件偏移 3600bytes
- | text | (代码段位置)
- +-----------------------+
- | ro data | (只读数据段位置)
- +-----------------------+
- | ....... | (其它段)
- +-----------------------+
- | data | (数据段)
- +-----------------------+ hello文件偏移 6696bytes
- | Section Header | (段表位置)
- +-----------------------+ hello文件尾部 8680 bytes
点击(此处)折叠或打开
- $ ls -l hello
- -rwxr-xr-x 1 cliu4 users 8680 9月 30 14:31 hello
图 3
如图3,图为hello文件的整个布局图,从图中可以看出,hello可执行文件的大小为8680字节,其中0-64字节存放的是elf文件的头部信息,即elf header(这个结构体可以通过查看elf.h获取),64字节之后存放的是program header,在之后放的是动态解释器(interpreter),而section header则是放到文件末尾的即6696字节处,中间放到程序段即section。而当我们知道了elf头部信息的作用就是指明当前elf文件的版本号,运行环境和其他段的位置,个数以及大小后,那么紧接着elf header的program header到底又有什么用呢?首先我们看看program header里面到底有什么,如下图:点击(此处)折叠或打开
- $ readelf -l hello
- Elf file type is EXEC (Executable file)
- Entry point 0x400430
- There are 9 program headers, starting at offset 64
- Program Headers:
- Type Offset VirtAddr PhysAddr FileSiz MemSiz Flags Align
- PHDR 0x0000000000000040 0x0000000000400040 0x0000000000400040 0x00000000000001f8 0x00000000000001f8 RE 8
- INTERP 0x0000000000000238 0x0000000000400238 0x0000000000400238 0x000000000000001c 0x000000000000001c R 1
- [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
- LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000 0x0000000000000794 0x0000000000000794 RE 200000
- LOAD 0x0000000000000e00 0x0000000000600e00 0x0000000000600e00 0x0000000000000238 0x0000000000000240 RW 200000
- DYNAMIC 0x0000000000000e28 0x0000000000600e28 0x0000000000600e28 0x00000000000001d0 0x00000000000001d0 RW 8
- NOTE 0x0000000000000254 0x0000000000400254 0x0000000000400254 0x0000000000000044 0x0000000000000044 R 4
- GNU_EH_FRAME 0x0000000000000618 0x0000000000400618 0x0000000000400618 0x0000000000000044 0x0000000000000044 R 4
- GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 RW 10
- GNU_RELRO 0x0000000000000e00 0x0000000000600e00 0x0000000000600e00 0x0000000000000200 0x0000000000000200 R 1
- Section to Segment mapping:
- Segment Sections...
- 00
- 01 .interp
- 02 .interp .note.ABI-tag .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .plt.got .text .fini .rodata .eh_frame_hdr .eh_frame
- 03 .init_array .fini_array .jcr .dynamic .got .got.plt .data .bss
- 04 .dynamic
- 05 .note.ABI-tag .note.gnu.build-id
- 06 .eh_frame_hdr
- 07
- 08 .init_array .fini_array .jcr .dynamic .got
图 4
如图4,program headers包含:1、PHDR(program header起始位置0x40,大小0x1f8);2、INTERP(动态解释器,其实就是一个字符串,记录了动态解释器的位置:/lib64/ld-linux-x86-64.so.2);3、LOAD;4、LOAD;5、DYNAMIC;6、NOTE等。从第20行"Section to Segment mapping"下面可以看到编号00,01,02,03....08,这些编号对应的是program header对应的表,例如:00对应的是PHDR,01对应的是INTERP,02对应的是LOAD等。因此,可以知道01对应的program header INTERP部分记录的是.interp段信息;而其他的与运行相关的记录在02/03对应的LOAD结构当中。那么这个program header到底有什么用呢?其实,这个program header仔细的朋友应该能够发现每个program header都记录了对应所在的文件偏移和内存的虚拟地址和物理地址,当系统调用execve陷入到内核,并且发现这个hello文件为elf文件的时候,Linux内核就会根据program header当中的提示信息来对hello进行内存映射,给hello开辟自己的虚拟地址空间(如LOAD部分虚拟地址是0x400000即图4标红部分),并且通过INTERP获取到当前elf文件的动态解释器路径:/lib64/ld-linux-x86-64.so.2,还可以通过DYNAMIC部分获取到当前hello文件依赖的动态库信息,知道哪些动态库需要引用(readelf -d hello)。因此,我可以简单的理解为:program header信息 就是为Linux内核提供应用程序加载相关的信息,方便内核加载可执行程序。如图3,经过了program header,挨着它的便是动态解释器(.interpreter)的位置了,这个地方比较简单,就是一个字符串,指明了动态解释器的路径。这个动态解释器/lib64/ld-linux-x86-64.so.2看起来是一个动态库,其实不是,它是一个可用自我重定位的可执行程序,其主要作用就是帮助hello进行代码重定位。
如图3,在动态解释器后的具体段,将在section headers之后描述。
如图3,在文件的末尾,即6696偏移到8680偏移的位置处,存放的是section header。可用通过readelf -S hello获取到。下图是section headers结构的信息:
点击(此处)折叠或打开
- There are 31 section headers, starting at offset 0x1a28:
- Section Headers:
- [Nr] Name Type Address Offset Size EntSize Flags Link Info Align
- [ 0] NULL 0000000000000000 00000000 0000000000000000 0000000000000000 0 0 0
- [ 1] .interp PROGBITS 0000000000400238 00000238 000000000000001c 0000000000000000 A 0 0 1
- [ 2] .note.ABI-tag NOTE 0000000000400254 00000254 0000000000000020 0000000000000000 A 0 0 4
- [ 3] .note.gnu.build-i NOTE 0000000000400274 00000274 0000000000000024 0000000000000000 A 0 0 4
- [ 4] .gnu.hash GNU_HASH 0000000000400298 00000298 000000000000001c 0000000000000000 A 5 0 8
- [ 5] .dynsym DYNSYM 00000000004002b8 000002b8 0000000000000060 0000000000000018 A 6 1 8
- [ 6] .dynstr STRTAB 0000000000400318 00000318 000000000000003d 0000000000000000 A 0 0 1
- [ 7] .gnu.version VERSYM 0000000000400356 00000356 0000000000000008 0000000000000002 A 5 0 2
- [ 8] .gnu.version_r VERNEED 0000000000400360 00000360 0000000000000020 0000000000000000 A 6 1 8
- [ 9] .rela.dyn RELA 0000000000400380 00000380 0000000000000018 0000000000000018 A 5 0 8
- [10] .rela.plt RELA 0000000000400398 00000398 0000000000000030 0000000000000018 AI 5 24 8
- [11] .init PROGBITS 00000000004003c8 000003c8 000000000000001a 0000000000000000 AX 0 0 4
- [12] .plt PROGBITS 00000000004003f0 000003f0 0000000000000030 0000000000000010 AX 0 0 16
- [13] .plt.got PROGBITS 0000000000400420 00000420 0000000000000008 0000000000000000 AX 0 0 8
- [14] .text PROGBITS 0000000000400430 00000430 00000000000001b2 0000000000000000 AX 0 0 16
- [15] .fini PROGBITS 00000000004005e4 000005e4 0000000000000009 0000000000000000 AX 0 0 4
- [16] .rodata PROGBITS 00000000004005f0 000005f0 0000000000000027 0000000000000000 A 0 0 4
- [17] .eh_frame_hdr PROGBITS 0000000000400618 00000618 0000000000000044 0000000000000000 A 0 0 4
- [18] .eh_frame PROGBITS 0000000000400660 00000660 0000000000000134 0000000000000000 A 0 0 8
- [19] .init_array INIT_ARRAY 0000000000600e00 00000e00 0000000000000010 0000000000000000 WA 0 0 8
- [20] .fini_array FINI_ARRAY 0000000000600e10 00000e10 0000000000000010 0000000000000000 WA 0 0 8
- [21] .jcr PROGBITS 0000000000600e20 00000e20 0000000000000008 0000000000000000 WA 0 0 8
- [22] .dynamic DYNAMIC 0000000000600e28 00000e28 00000000000001d0 0000000000000010 WA 6 0 8
- [23] .got PROGBITS 0000000000600ff8 00000ff8 0000000000000008 0000000000000008 WA 0 0 8
- [24] .got.plt PROGBITS 0000000000601000 00001000 0000000000000028 0000000000000008 WA 0 0 8
- [25] .data PROGBITS 0000000000601028 00001028 0000000000000010 0000000000000000 WA 0 0 8
- [26] .bss NOBITS 0000000000601038 00001038 0000000000000008 0000000000000000 WA 0 0 1
- [27] .comment PROGBITS 0000000000000000 00001038 0000000000000035 0000000000000001 MS 0 0 1
- [28] .shstrtab STRTAB 0000000000000000 00001915 000000000000010c 0000000000000000 0 0 1
- [29] .symtab SYMTAB 0000000000000000 00001070 0000000000000678 0000000000000018 30 49 8
- [30] .strtab STRTAB 0000000000000000 000016e8 000000000000022d 0000000000000000 0 0 1
图 5
图5是hello文件的section header, 这个信息描述了这个hello文件中到底存在有多少section,这里我将比较重要的section用紫色表示。其中,.interp, .text, .rodata, .data, .bss等几个常用段,这里就不在进行介绍(通常.rodata,.data,和.text是挨着的,是为了节约存储空间,因为.bss不会占用存储空间)。.interp的具体实现将在以后的文章中加以描述。.note开头和.gnu开头的段基本上都是存放与调试相关的信息。.dynsym和.dynstr: 这两个段为动态符号段和动态字符串符号段,里面存放的是hello程序需要的外部符号信息,用于动态链接。
点击(此处)折叠或打开
- $readelf --dyn-syms hello
- Symbol table '.dynsym' contains 4 entries:
- Num: Value Size Type Bind Vis Ndx Name
- 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
- 1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND puts@GLIBC_2.2.5 (2)
- 2: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.2.5 (2)
- 3: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
点击(此处)折叠或打开
- $readelf -r hello
- Relocation section '.rela.dyn' at offset 0x380 contains 1 entries:
- Offset Info Type Sym. Value Sym. Name + Addend
- 000000600ff8 000300000006 R_X86_64_GLOB_DAT 0000000000000000 __gmon_start__ + 0
- Relocation section '.rela.plt' at offset 0x398 contains 2 entries:
- Offset Info Type Sym. Value Sym. Name + Addend
- 000000601018 000100000007 R_X86_64_JUMP_SLO 0000000000000000 puts@GLIBC_2.2.5 + 0
- 000000601020 000200000007 R_X86_64_JUMP_SLO 0000000000000000 __libc_start_main@GLIBC_2.2.5 + 0
注:其中R_X86_64_GLOB_DAT 和R_X86_64_JUMP_SLO 为重定向类型,具体参考重定向。
.init: 与应用初始化相关,在进入main函数之前会涉及到,通常位于PLT代码的前面。
点击(此处)折叠或打开
- Disassembly of section .init: 只是一个过渡函数,由__libc_csu_init调用
- 00000000004003c8 <_init>:
- 4003c8: 48 83 ec 08 sub $0x8,%rsp
- 4003cc: 48 8b 05 25 0c 20 00 mov 0x200c25(%rip),%rax # 600ff8 <_DYNAMIC+0x1d0>
- 4003d3: 48 85 c0 test %rax,%rax
- 4003d6: 74 05 je 4003dd <_init+0x15>
- 4003d8: e8 43 00 00 00 callq 400420 <__libc_start_main@plt+0x10>
- 4003dd: 48 83 c4 08 add $0x8,%rsp
- 4003e1: c3 retq
点击(此处)折叠或打开
- Contents of section .got.plt: .got.plt的内容,601020->0x400416, 601018->0x400406(标红部分,为数据,PLT第一次会访问这里,之后这里会被覆盖成真正的函数地址)
601000 280e6000 00000000 00000000 00000000 (.`.............
601010 00000000 00000000 06044000 00000000 ..........@.....
601020 16044000 00000000 - Disassembly of section .plt:
- 00000000004003f0 <puts@plt-0x10>:
- 4003f0: ff 35 12 0c 20 00 pushq 0x200c12(%rip) # 601008 <_GLOBAL_OFFSET_TABLE_+0x8>
- 4003f6: ff 25 14 0c 20 00 jmpq *0x200c14(%rip) # 601010 <_GLOBAL_OFFSET_TABLE_+0x10>
- 4003fc: 0f 1f 40 00 nopl 0x0(%rax)
- 0000000000400400 <puts@plt>: 这是一个跳板函数,当第一次调用的时候,GOT+0x8指向400406,然后进行函数重定位 ,第二次调用的时候,指向重定位后的地址
- 400400: ff 25 12 0c 20 00 jmpq *0x200c12(%rip) # 601018 <_GLOBAL_OFFSET_TABLE_+0x18>
- 400406: 68 00 00 00 00 pushq $0x0
- 40040b: e9 e0 ff ff ff jmpq 4003f0 <_init+0x28>
- 0000000000400410 <__libc_start_main@plt>:跳板函数:当第一次调用的时候,GOT+0x8指向400416,然后进行函数重定位 ,第二次调用的时候,指向重定位后的地址
- 400410: ff 25 0a 0c 20 00 jmpq *0x200c0a(%rip) # 601020 <_GLOBAL_OFFSET_TABLE_+0x20>
- 400416: 68 01 00 00 00 pushq $0x1
- 40041b: e9 d0 ff ff ff jmpq 4003f0 <_init+0x28>
- Disassembly of section .plt.got:
- 0000000000400420 <.plt.got>:
- 400420: ff 25 d2 0b 20 00 jmpq *0x200bd2(%rip) # 600ff8 <_DYNAMIC+0x1d0>
- 400426: 66 90 xchg %ax,%ax
.fini: 与应用退出有关,在main函数退出可能会涉及到,通常为空。
.init_array和.fini_array: 类似于构造函数和析构函数,挂在.init_array段里面的函数,在main函数运行前运行;挂在.fini_array段里面的函数在main函数退出后运行。
.got和.got.plt: 又名全局偏移表,用于存放全局符号地址,其中plt属于一种特殊的GOT表。.got.plt主要用于存放动态函数地址,此表和PLT搭配使用(以后会讲解)。
.symtab和.strtab: hello程序内部能提供的符号表和一些符号信息,这个段通常用于动态库需要,应用程序对此无用。
点击(此处)折叠或打开
- $readelf -s hello
- Symbol table '.dynsym' contains 4 entries:
- Num: Value Size Type Bind Vis Ndx Name
- 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
- 1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND puts@GLIBC_2.2.5 (2)
- 2: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.2.5 (2)
- 3: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
- Symbol table '.symtab' contains 69 entries:
- Num: Value Size Type Bind Vis Ndx Name
- 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
- 1: 0000000000400238 0 SECTION LOCAL DEFAULT 1
- 2: 0000000000400254 0 SECTION LOCAL DEFAULT 2
- 3: 0000000000400274 0 SECTION LOCAL DEFAULT 3
- 4: 0000000000400298 0 SECTION LOCAL DEFAULT 4
- 5: 00000000004002b8 0 SECTION LOCAL DEFAULT 5
- 限于篇幅,此处省略部分符号
- 55: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@@GLIBC
- 56: 0000000000601028 0 NOTYPE GLOBAL DEFAULT 25 __data_start
- 57: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
- 58: 0000000000601030 0 OBJECT GLOBAL HIDDEN 25 __dso_handle
- 59: 00000000004005f0 4 OBJECT GLOBAL DEFAULT 16 _IO_stdin_used
- 60: 0000000000400570 101 FUNC GLOBAL DEFAULT 14 __libc_csu_init
- 61: 0000000000601040 0 NOTYPE GLOBAL DEFAULT 26 _end
- 62: 0000000000400430 42 FUNC GLOBAL DEFAULT 14 _start
- 63: 0000000000601038 0 NOTYPE GLOBAL DEFAULT 26 __bss_start
- 64: 0000000000400548 32 FUNC GLOBAL DEFAULT 14 main
- 65: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses
- 66: 0000000000601038 0 OBJECT GLOBAL HIDDEN 25 __TMC_END__
- 67: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMCloneTable
- 68: 00000000004003c8 0 FUNC GLOBAL DEFAULT 11 _init
64行:64: 0000000000400548 32 FUNC GLOBAL DEFAULT 14 main
函数名字main函数,全局符号,函数,地址0x400548等。
另外,我们可以通过objdump -s hello获取整个hello文件各个section对应的内容,如下:
点击(此处)折叠或打开
- hello: file format elf64-x86-64 (下面的布局是按照program header提供的虚拟内存地址布局的,如.interp的起始地址0x400238)
- Contents of section .interp:
- 400238 2f6c6962 36342f6c 642d6c69 6e75782d /lib64/ld-linux-
- 400248 7838362d 36342e73 6f2e3200 x86-64.so.2.
- Contents of section .note.ABI-tag:
- 400254 04000000 10000000 01000000 474e5500 ............GNU.
- 400264 00000000 02000000 06000000 20000000 ............ ...
- Contents of section .note.gnu.build-id:
- 400274 04000000 14000000 03000000 474e5500 ............GNU.
- 400284 ce3c4f78 e2194357 f5296b53 6f39b5c2 .<Ox..CW.)kSo9..
- 400294 e4f14ee6 ..N.
- Contents of section .gnu.hash:
- 400298 01000000 01000000 01000000 00000000 ................
- 4002a8 00000000 00000000 00000000 ............
- Contents of section .dynsym:
- 4002b8 00000000 00000000 00000000 00000000 ................
- 4002c8 00000000 00000000 0b000000 12000000 ................
- 4002d8 00000000 00000000 00000000 00000000 ................
- 4002e8 10000000 12000000 00000000 00000000 ................
- 4002f8 00000000 00000000 22000000 20000000 ........"... ...
- 400308 00000000 00000000 00000000 00000000 ................
- Contents of section .dynstr:
- 400318 006c6962 632e736f 2e360070 75747300 .libc.so.6.puts.
- 400328 5f5f6c69 62635f73 74617274 5f6d6169 __libc_start_mai
- 400338 6e005f5f 676d6f6e 5f737461 72745f5f n.__gmon_start__
- 400348 00474c49 42435f32 2e322e35 00 .GLIBC_2.2.5.
- Contents of section .gnu.version:
- 400356 00000200 02000000 ........
- Contents of section .gnu.version_r:
- 400360 01000100 01000000 10000000 00000000 ................
- 400370 751a6909 00000200 31000000 00000000 u.i.....1.......
- Contents of section .rela.dyn:
- 400380 f80f6000 00000000 06000000 03000000 ..`.............
- 400390 00000000 00000000 ........
- Contents of section .rela.plt:
- 400398 18106000 00000000 07000000 01000000 ..`.............
- 4003a8 00000000 00000000 20106000 00000000 ........ .`.....
- 4003b8 07000000 02000000 00000000 00000000 ................
- Contents of section .init:
- 4003c8 4883ec08 488b0525 0c200048 85c07405 H...H..%. .H..t.
- 4003d8 e8430000 004883c4 08c3 .C...H....
- Contents of section .plt:
- 4003f0 ff35120c 2000ff25 140c2000 0f1f4000 .5.. ..%.. ...@.
- 400400 ff25120c 20006800 000000e9 e0ffffff .%.. .h.........
- 400410 ff250a0c 20006801 000000e9 d0ffffff .%.. .h.........
- Contents of section .plt.got:
- 400420 ff25d20b 20006690 .%.. .f.
- Contents of section .text:
- 省略.text的具体内容
- Contents of section .fini:
- 4005e4 4883ec08 4883c408 c3 H...H....
- Contents of section .rodata:
- 4005f0 01000200 4265666f 7265206d 61696e00 ....Before main.
- 400600 41667465 72206d61 696e0048 656c6c6f After main.Hello
- 400610 20576f72 6c6400 World.
- Contents of section .eh_frame_hdr:
- 400618 011b033b 44000000 07000000 d8fdffff ...;D...........
- 400628 90000000 18feffff 60000000 0effffff ........`.......
- 400638 b8000000 1fffffff d8000000 30ffffff ............0...
- 400648 f8000000 58ffffff 18010000 c8ffffff ....X...........
- 400658 60010000 `...
- Contents of section .eh_frame:
- 400660 14000000 00000000 017a5200 01781001 .........zR..x..
- 400670 1b0c0708 90010710 14000000 1c000000 ................
- 400680 b0fdffff 2a000000 00000000 00000000 ....*...........
- 400690 14000000 00000000 017a5200 01781001 .........zR..x..
- 4006a0 1b0c0708 90010000 24000000 1c000000 ........$.......
- 4006b0 40fdffff 30000000 000e1046 0e184a0f @...0......F..J.
- 4006c0 0b770880 003f1a3b 2a332422 00000000 .w...?.;*3$"....
- 4006d0 1c000000 44000000 4efeffff 11000000 ....D...N.......
- 4006e0 00410e10 8602430d 064c0c07 08000000 .A....C..L......
- 4006f0 1c000000 64000000 3ffeffff 11000000 ....d...?.......
- 400700 00410e10 8602430d 064c0c07 08000000 .A....C..L......
- 400710 1c000000 84000000 30feffff 20000000 ........0... ...
- 400720 00410e10 8602430d 065b0c07 08000000 .A....C..[......
- 400730 44000000 a4000000 38feffff 65000000 D.......8...e...
- 400740 00420e10 8f02420e 188e0345 0e208d04 .B....B....E. ..
- 400750 420e288c 05480e30 8606480e 3883074d B.(..H.0..H.8..M
- 400760 0e40720e 38410e30 410e2842 0e20420e .@r.8A.0A.(B. B.
- 400770 18420e10 420e0800 14000000 ec000000 .B..B...........
- 400780 60feffff 02000000 00000000 00000000 `...............
- 400790 00000000 ....
- Contents of section .init_array:
- 600e00 00054000 00000000 26054000 00000000 ..@.....&.@.....
- Contents of section .fini_array:
- 600e10 e0044000 00000000 37054000 00000000 ..@.....7.@.....
- Contents of section .jcr:
- 600e20 00000000 00000000 ........
- Contents of section .dynamic:
- 省略.dynamic具体内容
- Contents of section .got:
- 600ff8 00000000 00000000 ........
- Contents of section .got.plt:
- 601000 280e6000 00000000 00000000 00000000 (.`.............
- 601010 00000000 00000000 06044000 00000000 ..........@.....
- 601020 16044000 00000000 ..@.....
- Contents of section .data:
- 601028 00000000 00000000 00000000 00000000 ................
- Contents of section .comment:
- 0000 4743433a 20285562 756e7475 20352e34 GCC: (Ubuntu 5.4
- 0010 2e302d36 7562756e 7475317e 31362e30 .0-6ubuntu1~16.0
- 0020 342e3131 2920352e 342e3020 32303136 4.11) 5.4.0 2016
- 0030 30363039 00 0609.
Contents of section 段名:
地址 内容1 内容2 内容3 内容4 ASCII字符
地址 内容1 内容2 内容3 内容4 ASCII字符
地址 内容1 内容2 内容3 内容4 ASCII字符
...........................
elf文件的大致粗略信息就是如此,如果有需要可以进行更详细的分析,这篇到这里为止,下一篇,主要分析execve系统调用里面到底完成了什么。