char s_lnnoptr[4]; /* 节行信息偏移量 */
char s_nreloc[2]; /* 节重定位条目数 */
char s_nlnno[2]; /* 节行信息条目数 */
char s_flags[4]; /* 段标记 */
};
有一点需要注意:LINUX系统中头文档coff.h中对字段s_paddr的注释是"physical address",但似乎应该理解为"节被加载到内存中所占用的空间长度"。字段s_flags标记该节的类型,如文本段、数据段、BSS段等。在 COFF的节中也出现了行信息,行信息描述了二进制代码和源代码的行号之间的对映关系,在调试时很有用。
参考资料 19是一份对 COFF格式周详描述的中文资料,更周详的内容请参阅参考资料 20。
ELF文档格式分析
ELF 文档有三种类型:可重定位文档:也就是通常称的目标文档,后缀为.o。共享文档:也就是通常称的库文档,后缀为.so。可执行文档:本文主要讨论的文档格式,总的来说,可执行文档的格式和上述两种文档的格式之间的区别主要在于观察的角度不同:一种称为连接视图(Linking View),一种称为执行视图(Execution View)。
首先看看ELF文档的总体布局:
ELF header(ELF头部)
Program header table(程式头表)
Segment1(段1)
Segment2(段2)
………
Sengmentn(段n)
Setion header table(节头表,可选)
段由若干个节(Section)构成,节头表对每一个节的信息有相关描述。对可执行程式而言,节头表是可选的。参考资料 1中作者谈到把节头表的任何数据全部配置为0,程式也能正确运行!ELF头部是个关于本文档的路线图(road map),从总体上描述文档的结构。下面是ELF头部的数据结构:
typedef struct
{
unsigned char e_ident[EI_NIDENT]; /* 魔数和相关信息 */
Elf32_Half e_type; /* 目标文档类型 */
Elf32_Half e_machine; /* 硬件体系 */
Elf32_Word e_version; /* 目标文档版本 */
Elf32_Addr e_entry; /* 程式进入点 */
Elf32_Off e_phoff; /* 程式头部偏移量 */
Elf32_Off e_shoff; /* 节头部偏移量 */
Elf32_Word e_flags; /* 处理器特定标志 */
Elf32_Half e_ehsize; /* ELF头部长度 */
Elf32_Half e_phentsize; /* 程式头部中一个条目的长度 */
Elf32_Half e_phnum; /* 程式头部条目个数 */
Elf32_Half e_shentsize; /* 节头部中一个条目的长度 */
Elf32_Half e_shnum; /* 节头部条目个数 */
Elf32_Half e_shstrndx; /* 节头部字符表索引 */
} Elf32_Ehdr;
下面我们对ELF头表中一些重要的字段作出相关说明,完整的ELF定义请参阅参考资料 6和参考资料7。
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; /* 段在内存中对齐标记 */
文章整理:西部数码--专业提供域名注册、虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!




