UNIX/LINUX 平台可执行文件格式分析
e_ident[0]-e_ident[3]包含了ELF文件的魔数,依次是0x7f、'E'、'L'、'F'。注意,任何一个ELF文件必须包含此魔数。 参考资料 3中讨论了利用程序、工具、/Proc文件系统等多种查看ELF魔数的方法。e_ident[4]表示硬件系统的位数,1代表32位,2代表64位。e_ident[5]表示数据编码方式,1代表小印第安排序(最大有意义的字节占有最低的地址),2代表大印第安排序(最大有意义的字节占有最高的地址)。e_ident[6]指定ELF头部的版本,当前必须为1。e_ident[7]到e_ident[14]是填充符,通常是0。ELF格式规范中定义这几个字节是被忽略的,但实际上是这几个字节完全可以可被利用。如病毒Lin/Glaurung.676/666( 参考资料 1)设置e_ident[7]为0x21,表示本文件已被感染;或者存放可执行代码( 参考资料 2)。ELF头部中大多数字段都是对子头部数据的描述,其意义相对比较简单。值得注意的是某些病毒可能修改字段e_entry(程序进入点)的值,以指向病毒代码,例如上面提到的病毒Lin/Glaurung.676/666。
一个实际可执行文件的文件头部形式如下:(利用命令readelf)
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: 0x80483cc
Start of program headers: 52 (bytes into file)
Start of section headers: 14936 (bytes into file)
Flags: 0x0
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 6
Size of section headers: 40 (bytes)
Number of section headers: 34
Section header string table index: 31
紧接ELF头部的是程序头表,它是一个结构数组,包含了ELF头表中字段e_phnum定义的条目,结构描述一个段或其他系统准备执行该程序所需要的信息。
typedef struct {
Elf32_Word p_type; /* 段类型 */
Elf32_Off p_offset; /* 段位置相对于文件开始处的偏移量 */
Elf32_Addr p_vaddr; /* 段在内存中的地址 */
Elf32_Addr p_paddr; /* 段的物理地址 */
Elf32_Word p_filesz; /* 段在文件中的长度 */
Elf32_Word p_memsz; /* 段在内存中的长度 */
Elf32_Word p_flags; /* 段的标记 */
Elf32_Word p_align; /* 段在内存中对齐标记 */
} Elf32_Phdr;
在详细讨论可执行文件程序头表之前,首先查看一个实际文件的输出:
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000034 0x08048034 0x08048034 0x000c0 0x000c0 R E 0x4
INTERP 0x0000f4 0x080480f4 0x080480f4 0x00013 0x00013 R 0x1
[Requesting program interpreter: /lib/ld-linux.so.2]
LOAD 0x000000 0x08048000 0x08048000 0x00684 0x00684 R E 0x1000
LOAD 0x000684 0x08049684 0x08049684 0x00118 0x00130 RW 0x1000
DYNAMIC 0x000690 0x08049690 0x08049690 0x000c8 0x000c8 RW 0x4
NOTE 0x000108 0x08048108 0x08048108 0x00020 0x00020 R 0x4
Section to Segment mapping:
Segment Sections...
00
01 .interp
02 .interp .note.ABI-tag .hash .dynsym .dynstr .gnu.version .gnu.version_r .rel.dyn .rel.plt .init .plt .text .fini .rodata .eh_frame
03 .data .dynamic .ctors .dtors .jcr .got .bss
04 .dynamic
05 .note.ABI-tag
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 080480f4 0000f4 000013 00 A 0 0 1
[ 2] .note.ABI-tag NOTE 08048108 000108 000020 00 A 0 0 4
[ 3] .hash HASH 08048128 000128 000040 04 A 4 0 4
[ 4] .dynsym DYNSYM 08048168 000168 0000b0 10 A 5 1 4
[ 5] .dynstr STRTAB 08048218 000218 00007b 00 A 0 0 1
[ 6] .gnu.version VERSYM 08048294 000294 000016 02 A 4 0 2
[ 7] .gnu.version_r VERNEED 080482ac 0002ac 000030 00 A 5 1 4
[ 8] .rel.dyn REL 080482dc 0002dc 000008 08 A 4 0 4
[ 9] .rel.plt REL 080482e4 0002e4 000040 08 A 4 b 4
[10] .init PROGBITS 08048324 000324 000017 00 AX 0 0 4
[11] .plt PROGBITS 0804833c 00033c 000090 04 AX 0 0 4
[12] .text PROGBITS 080483cc 0003cc 0001f8 00 AX 0 0 4
[13] .fini PROGBITS 080485c4 0005c4 00001b 00 AX 0 0 4
[14] .rodata PROGBITS 080485e0 0005e0 00009f 00 A 0 0 32
[15] .eh_frame PROGBITS 08048680 000680 000004 00 A 0 0 4
[16] .data PROGBITS 08049684 000684 00000c 00 WA 0 0 4
[17] .dynamic DYNAMIC 08049690 000690 0000c8 08 WA 5 0 4
[18] .ctors PROGBITS 08049758 000758 000008 00 WA 0 0 4
[19] .dtors PROGBITS 08049760 000760 000008 00 WA 0 0 4
[20] .jcr PROGBITS 08049768 000768 000004 00 WA 0 0 4
[21] .got PROGBITS 0804976c 00076c 000030 04 WA 0 0 4
[22] .bss NOBITS 0804979c 00079c 000018 00 WA 0 0 4
[23] .comment PROGBITS 00000000 00079c 000132 00 0 0 1
[24] .debug_aranges PROGBITS 00000000 0008d0 000098 00 0 0 8
[25] .debug_pubnames PROGBITS 00000000 000968 000040 00 0 0 1
[26] .debug_info PROGBITS 00000000 0009a8 001cc6 00 0 0 1
[27] .debug_abbrev PROGBITS 00000000 00266e 0002cc 00 0 0 1
[28] .debug_line PROGBITS 00000000 00293a 0003dc 00 0 0 1
[29] .debug_frame PROGBITS 00000000 002d18 000048 00 0 0 4
[30] .debug_str PROGBITS 00000000 002d60 000bcd 01 MS 0 0 1
[31] .shstrtab STRTAB 00000000 00392d 00012b 00 0 0 1
[32] .symtab SYMTAB 00000000 003fa8 000740 10 33 56 4
[33] .strtab STRTAB 00000000 0046e8 000467 00 0 0 1