现在的位置: 首页 > 综合 > 正文

ELF 文件数据分析: 全局变量(objdump 如何查找一个变量,并把它变成可阅读的)

2013年12月05日 ⁄ 综合 ⁄ 共 9284字 ⁄ 字号 评论关闭


<!--
/* Font Definitions */
@font-face
{font-family:宋体;
panose-1:2 1 6 0 3 1 1 1 1 1;
mso-font-alt:SimSun;
mso-font-charset:134;
mso-generic-font-family:auto;
mso-font-pitch:variable;
mso-font-signature:3 135135232 16 0 262145 0;}
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;
mso-font-charset:0;
mso-generic-font-family:roman;
mso-font-pitch:variable;
mso-font-signature:-1610611985 1107304683 0 0 159 0;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;
mso-font-charset:0;
mso-generic-font-family:swiss;
mso-font-pitch:variable;
mso-font-signature:-1610611985 1073750139 0 0 159 0;}
@font-face
{font-family:"/@宋体";
panose-1:2 1 6 0 3 1 1 1 1 1;
mso-font-charset:134;
mso-generic-font-family:auto;
mso-font-pitch:variable;
mso-font-signature:3 135135232 16 0 262145 0;}
@font-face
{font-family:Verdana;
panose-1:2 11 6 4 3 5 4 4 2 4;
mso-font-charset:0;
mso-generic-font-family:swiss;
mso-font-pitch:variable;
mso-font-signature:536871559 0 0 0 415 0;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{mso-style-unhide:no;
mso-style-qformat:yes;
mso-style-parent:"";
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
mso-pagination:none;
font-size:10.5pt;
mso-bidi-font-size:11.0pt;
font-family:"Calibri","sans-serif";
mso-fareast-font-family:宋体;
mso-bidi-font-family:"Times New Roman";
mso-font-kerning:1.0pt;}
span.EmailStyle15
{mso-style-type:personal;
mso-style-noshow:yes;
mso-style-unhide:no;
mso-ansi-font-size:11.0pt;
mso-bidi-font-size:11.0pt;
font-family:"Calibri","sans-serif";
mso-ascii-font-family:Calibri;
mso-fareast-font-family:宋体;
mso-hansi-font-family:Calibri;
mso-bidi-font-family:"Times New Roman";
color:windowtext;}
.MsoChpDefault
{mso-style-type:export-only;
mso-default-props:yes;
mso-bidi-font-size:10.5pt;
mso-ascii-font-family:Calibri;
mso-fareast-font-family:宋体;
mso-hansi-font-family:Calibri;}
.MsoPapDefault
{mso-style-type:export-only;}
/* Page Definitions */
@page
{mso-page-border-surround-header:no;
mso-page-border-surround-footer:no;}
@page Section1
{size:612.0pt 792.0pt;
margin:72.0pt 90.0pt 72.0pt 90.0pt;
mso-header-margin:36.0pt;
mso-footer-margin:36.0pt;
mso-paper-source:0;}
div.Section1
{page:Section1;}
-->

---------------objdump
是用查看目标文件或者可执行的目标文件的构成的
GCC
工具
----------

以下
3
条命令足够那些喜欢探索目标文件与源代码之间的丝丝的关系的朋友。

objdump  -x 
obj 

以某种分类信息的形式把目标文件的数据组织(被分为几大块)输出
   

objdump  -t 
obj 

输出目标文件的符号表

objdump  -h 
obj 

输出目标文件的所有段概括

objdump  -j .text/.data
-S  obj 

输出指定段的信息,大概就是反汇编源代码把

自己的一个例子:

#include <stdio.h>

#define __sched __attribute__((__section__(".sched.text")))
void __sched  my_sched(void)
{
printf("Hello me");
}
void __attribute__ ((constructor)) my_init(void)
{
printf("Hello ");
}
void __attribute__ ((destructor)) my_exit(void)
{
printf("bye2/n");
}
int main()
{
printf("World!/n");
printf("bye1/n");
return 0;
}


gcc attribute.c -o attribute -g3


[root@localhost objdump]# objdump attribute -x | grep .sched.text
 13 .sched.text   00000015  080484ec  080484ec  000004ec  2**0
080484ec l    d  .sched.text    00000000              .sched.text
080484ec g     F .sched.text    00000015              my_sched


上面先用-x找到.sched.text的地址和长度,下面用--start-address 和--stop-address 输入这个段的范围用-S -r -d等选项即可查看段中的内容

[root@localhost objdump]# objdump attribute  --start-address=0x080484ec --stop-address=0x08048501 -S

attribute:     file format elf32-i386

Disassembly of section .sched.text:

080484ec <my_sched>:
#include <stdio.h>

#define __sched __attribute__((__section__(".sched.text")))
void __sched  my_sched(void)
{
 80484ec:       55                      push   %ebp
 80484ed:       89 e5                   mov    %esp,%ebp
 80484ef:       83 ec 18                sub    $0x18,%esp
printf("Hello me");
 80484f2:       b8 2c 85 04 08          mov    $0x804852c,%eax
 80484f7:       89 04 24                mov    %eax,(%esp)
 80484fa:       e8 15 fe ff ff          call   8048314 <printf@plt>
}
 80484ff:       c9                      leave
 8048500:       c3                      ret

 

 

 

 

 

先编译一个简单的 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: 程序执行代码。
  • .rodata: 代码中的字符串常量等。
  • .data: 初始化的全局变量。
  • .bss: 未初始化的全局变量。

我们反汇编看看 main
函数中的相关代码。

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

看看数据。

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
................

全局变量和静态变量的地址在编译时就决定了的。我们还可以用 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

抱歉!评论已关闭.