ELF 文件数据分析: 全局变量
先編譯一個簡單的 C 程序。
#include <stdio.h>
char* s = "Hello, World!";
char* x;
int i = 0x1234;
int main(int argc, char* argv[])
{
?x = "Ubuntu";
?printf("%s/n", s);
?return 0;
}
編譯后,使用 objdump 輸出 ELF Section 信息。我們通常關心只有 .text, .rodata, .data, .bss 這幾個段。
yuhen@yuhen-desktop:~/Learn.c$?objdump -h hello
hello: file format elf32-i386
Sections:
Idx Name Size VMA LMA File off Algn
?12 .text 0000018c 08048310 08048310 00000310 2**4
?CONTENTS, ALLOC, LOAD, READONLY, CODE
?14 .rodata 0000001d 080484b8 080484b8 000004b8 2**2
?CONTENTS, ALLOC, LOAD, READONLY, DATA
?22 .data 00000010 0804a00c 0804a00c 0000100c 2**2
?CONTENTS, ALLOC, LOAD, DATA
?23 .bss 0000000c 0804a01c 0804a01c 0000101c 2**2
?ALLOC
Section 說明:
- .text: 程序執(zhí)行代碼。
- .rodata: 代碼中的字符串常量等。
- .data: 初始化的全局變量。
- .bss: 未初始化的全局變量。
我們反匯編看看 main 函數(shù)中的相關代碼。
yuhen@yuhen-desktop:~/Learn.c$?objdump -d -M intel hello > hello.asm?
yuhen@yuhen-desktop:~/Learn.c$?cat hello.asm | less?# 我們只關心 main,其他代碼省略
080483c4 <main>:
?80483c4: 8d 4c 24 04 lea ecx,[esp+0x4]
?80483c8: 83 e4 f0 and esp,0xfffffff0
?80483cb: ff 71 fc push DWORD PTR [ecx-0x4]
?80483ce: 55 push ebp
?80483cf: 89 e5 mov ebp,esp
?80483d1: 51 push ecx
?80483d2: 83 ec 04 sub esp,0x4
?80483d5: c7 05 24 a0 04 08 ce mov DWORD PTR ds:0x804a024,0x80484ce ; 注釋: x = "Ubuntu"
?80483dc: 84 04 08
?80483df: a1 14 a0 04 08 mov eax,ds:0x804a014 ; 注釋: s 地址
?80483e4: 89 04 24 mov DWORD PTR [esp],eax
?80483e7: e8 08 ff ff ff call 80482f4 <puts@plt>
?
?80483ec: b8 00 00 00 00 mov eax,0x0
?80483f1: 83 c4 04 add esp,0x4
?80483f4: 59 pop ecx
?80483f5: 5d pop ebp
?80483f6: 8d 61 fc lea esp,[ecx-0x4]
?80483f9: c3 ret
?80483fa: 90 nop
?80483fb: 90 nop
?80483fc: 90 nop
?80483fd: 90 nop
?80483fe: 90 nop
?80483ff: 90 nop
我們先關注全局變量 s,其地址是:
0x804a014 - 0x0804a00c (.data 基地址) + 0x0000100c (.data Offset) = 0x1014
我們看看二進制文件中對應位置的信息。
yuhen@yuhen-desktop:~/Learn.c$?xxd -g 1 -s 0x1014 -l 100 hello
0001014: c0 84 04 08 34 12 00 00 00 47 43 43 3a 20 28 55 ....4....GCC: (U
0001024: 62 75 6e 74 75 20 34 2e 33 2e 33 2d 35 75 62 75 buntu 4.3.3-5ubu
0001034: 6e 74 75 34 29 20 34 2e 33 2e 33 00 00 47 43 43 ntu4) 4.3.3..GCC
指向 0x080484c0,我們計算一下該字符串的 offset。
0x080484c0 - 0x080484b8 (.rodata 基地址) + 0x000004b8 (.rodata Offset) = 0x04c0
看看數(shù)據(jù)。
yuhen@yuhen-desktop:~/Learn.c$?xxd -g 1 -s 0x04c0 -l 100 hello
00004c0: 48 65 6c 6c 6f 2c 20 57 6f 72 6c 64 21 00 55 62 Hello, World!.Ub
00004d0: 75 6e 74 75 00 00 00 00 00 00 00 00 00 00 00 00 untu............
接下來看看未出化全局變量 x 的情況。
mov DWORD PTR ds:0x804a024,0x80484ce ; 注釋: x = "Ubuntu"
很顯然,該變量地址 (0x804a024) 在 .bss 段 (0x0804a01c ~ 0x0804a028)。字符串 "Ubuntu" 地址是 0x80484ce,我們可以計算其 Offset。
0x80484ce - 0x080484b8 (.rodata 基地址) + 0x000004b8 (.rodata Offset) = 0x04ce
yuhen@yuhen-desktop:~/Learn.c$?xxd -g 1 -s 0x04ce -l 100 hello
00004ce: 55 62 75 6e 74 75 00 00 00 00 00 00 00 00 00 00 Ubuntu..........
00004de: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
全局變量和靜態(tài)變量的地址在編譯時就決定了的。我們還可以用 readelf 命令獲取更詳細的 ELF 文件信息。
yuhen@yuhen-desktop:~/Learn.c$?readelf -e hello
ELF Header:
?Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
?Class: ELF32
?Data: 2's complement, little endian
?Version: 1 (current)
?OS/ABI: UNIX - System V
?ABI Version: 0
?Type: EXEC (Executable file)
?Machine: Intel 80386
?Version: 0x1
?Entry point address: 0x8048310
?Start of program headers: 52 (bytes into file)
?Start of section headers: 6004 (bytes into file)
?Flags: 0x0
?Size of this header: 52 (bytes)
?Size of program headers: 32 (bytes)
?Number of program headers: 8
?Size of section headers: 40 (bytes)
?Number of section headers: 36
?Section header string table index: 33
Section Headers:
?[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
?[ 0] NULL 00000000 000000 000000 00 0 0 0
?[ 1] .interp PROGBITS 08048134 000134 000013 00 A 0 0 1
?[ 2] .note.ABI-tag NOTE 08048148 000148 000020 00 A 0 0 4
?[ 3] .hash HASH 08048168 000168 000028 04 A 5 0 4
?[ 4] .gnu.hash GNU_HASH 08048190 000190 000020 04 A 5 0 4
?[ 5] .dynsym DYNSYM 080481b0 0001b0 000050 10 A 6 1 4
?[ 6] .dynstr STRTAB 08048200 000200 00004a 00 A 0 0 1
?[ 7] .gnu.version VERSYM 0804824a 00024a 00000a 02 A 5 0 2
?[ 8] .gnu.version_r VERNEED 08048254 000254 000020 00 A 6 1 4
?[ 9] .rel.dyn REL 08048274 000274 000008 08 A 5 0 4
?[10] .rel.plt REL 0804827c 00027c 000018 08 A 5 12 4
?[11] .init PROGBITS 08048294 000294 000030 00 AX 0 0 4
?[12] .plt PROGBITS 080482c4 0002c4 000040 04 AX 0 0 4
?[13] .text PROGBITS 08048310 000310 00018c 00 AX 0 0 16
?[14] .fini PROGBITS 0804849c 00049c 00001c 00 AX 0 0 4
?[15] .rodata PROGBITS 080484b8 0004b8 00001d 00 A 0 0 4
?[16] .eh_frame PROGBITS 080484d8 0004d8 000004 00 A 0 0 4
?[17] .ctors PROGBITS 08049f0c 000f0c 000008 00 WA 0 0 4
?[18] .dtors PROGBITS 08049f14 000f14 000008 00 WA 0 0 4
?[19] .jcr PROGBITS 08049f1c 000f1c 000004 00 WA 0 0 4
?[20] .dynamic DYNAMIC 08049f20 000f20 0000d0 08 WA 6 0 4
?[21] .got PROGBITS 08049ff0 000ff0 000004 04 WA 0 0 4
?[22] .got.plt PROGBITS 08049ff4 000ff4 000018 04 WA 0 0 4
?[23] .data PROGBITS 0804a00c 00100c 000010 00 WA 0 0 4
?[24] .bss NOBITS 0804a01c 00101c 00000c 00 WA 0 0 4
?[25] .comment PROGBITS 00000000 00101c 0000fc 00 0 0 1
?[26] .debug_aranges PROGBITS 00000000 001118 000070 00 0 0 8
?[27] .debug_pubnames PROGBITS 00000000 001188 000025 00 0 0 1
?[28] .debug_info PROGBITS 00000000 0011ad 0001b5 00 0 0 1
?[29] .debug_abbrev PROGBITS 00000000 001362 000083 00 0 0 1
?[30] .debug_line PROGBITS 00000000 0013e5 000180 00 0 0 1
?[31] .debug_str PROGBITS 00000000 001565 00008e 01 MS 0 0 1
?[32] .debug_ranges PROGBITS 00000000 0015f8 000040 00 0 0 8
?[33] .shstrtab STRTAB 00000000 001638 000139 00 0 0 1
?[34] .symtab SYMTAB 00000000 001d14 0004d0 10 35 54 4
?[35] .strtab STRTAB 00000000 0021e4 000213 00 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)
Program Headers:
?Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
?PHDR 0x000034 0x08048034 0x08048034 0x00100 0x00100 R E 0x4
?INTERP 0x000134 0x08048134 0x08048134 0x00013 0x00013 R 0x1
?[Requesting program interpreter: /lib/ld-linux.so.2]
?LOAD 0x000000 0x08048000 0x08048000 0x004dc 0x004dc R E 0x1000
?LOAD 0x000f0c 0x08049f0c 0x08049f0c 0x00110 0x0011c RW 0x1000
?DYNAMIC 0x000f20 0x08049f20 0x08049f20 0x000d0 0x000d0 RW 0x4
?NOTE 0x000148 0x08048148 0x08048148 0x00020 0x00020 R 0x4
?GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x4
?GNU_RELRO 0x000f0c 0x08049f0c 0x08049f0c 0x000f4 0x000f4 R 0x1
?Section to Segment mapping:
?Segment Sections...
?00
?01 .interp
?02 .interp .note.ABI-tag .hash ... .text .fini .rodata .eh_frame
?03 .ctors .dtors .jcr .dynamic .got .got.plt .data .bss
?04 .dynamic
?05 .note.ABI-tag
?06
?07 .ctors .dtors .jcr .dynamic .got
總結
以上是生活随笔為你收集整理的ELF 文件数据分析: 全局变量的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android java 调试快捷键_A
- 下一篇: python 比赛成绩预测_利用 Pyt