UNIXLINUX平台可执行文件格式分析Word文档下载推荐.docx

上传人:b****5 文档编号:16135059 上传时间:2022-11-20 格式:DOCX 页数:12 大小:26KB
下载 相关 举报
UNIXLINUX平台可执行文件格式分析Word文档下载推荐.docx_第1页
第1页 / 共12页
UNIXLINUX平台可执行文件格式分析Word文档下载推荐.docx_第2页
第2页 / 共12页
UNIXLINUX平台可执行文件格式分析Word文档下载推荐.docx_第3页
第3页 / 共12页
UNIXLINUX平台可执行文件格式分析Word文档下载推荐.docx_第4页
第4页 / 共12页
UNIXLINUX平台可执行文件格式分析Word文档下载推荐.docx_第5页
第5页 / 共12页
点击查看更多>>
下载资源
资源描述

UNIXLINUX平台可执行文件格式分析Word文档下载推荐.docx

《UNIXLINUX平台可执行文件格式分析Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《UNIXLINUX平台可执行文件格式分析Word文档下载推荐.docx(12页珍藏版)》请在冰豆网上搜索。

UNIXLINUX平台可执行文件格式分析Word文档下载推荐.docx

不同的文件格式中段和节的含义可能有细微区别,但根据上下文关系可以很清楚的理解,这不是关键问题。

最后,可执行文件通常都有一个文件头部以描述本文件的总体结构。

相对可执行文件有三个重要的概念:

编译(compile)、连接(link,也可称为链接、联接)、加载(load)。

源程序文件被编译成目标文件,多个目标文件被连接成一个最终的可执行文件,可执行文件被加载到内存中运行。

因为本文重点是讨论可执行文件格式,因此加载过程也相对重点讨论。

下面是LINUX平台下ELF文件加载过程的一个简单描述。

1:

内核首先读ELF文件的头部,然后根据头部的数据指示分别读入各种数据结构,找到标记为可加载(loadable)的段,并调用函数mmap()把段内容加载到内存中。

在加载之前,内核把段的标记直接传递给mmap(),段的标记指示该段在内存中是否可读、可写,可执行。

显然,文本段是只读可执行,而数据段是可读可写。

这种方式是利用了现代操作系统和处理器对内存的保护功能。

著名的Shellcode的编写技巧则是突破此保护功能的一个实际例子。

2:

内核分析出ELF文件标记为PT_INTERP的段中所对应的动态连接器名称,并加载动态连接器。

现代LINUX系统的动态连接器通常是/lib/ld-linux.so.2,相关细节在后面有详细描述。

3:

内核在新进程的堆栈中设置一些标记-值对,以指示动态连接器的相关操作。

4:

内核把控制传递给动态连接器。

5:

动态连接器检查程序对外部文件(共享库)的依赖性,并在需要时对其进行加载。

6:

动态连接器对程序的外部引用进行重定位,通俗的讲,就是告诉程序其引用的外部变量/函数的地址,此地址位于共享库被加载在内存的区间内。

动态连接还有一个延迟(Lazy)定位的特性,即只在"

真正"

需要引用符号时才重定位,这对提高程序运行效率有极大帮助。

7:

动态连接器执行在ELF文件中标记为.init的节的代码,进行程序运行的初始化。

在早期系统中,初始化代码对应函数_init(void)(函数名强制固定),在现代系统中,则对应形式为

void

__attribute((constructor))

init_function(void)

{

……

}

其中函数名为任意。

8:

动态连接器把控制传递给程序,从ELF文件头部中定义的程序进入点开始执行。

在a.out格式和ELF格式中,程序进入点的值是显式存在的,在COFF格式中则是由规范隐含定义。

从上面的描述可以看出,加载文件最重要的是完成两件事情:

加载程序段和数据段到内存;

进行外部定义符号的重定位。

重定位是程序连接中一个重要概念。

我们知道,一个可执行程序通常是由一个含有main()的主程序文件、若干目标文件、若干共享库(SharedLibraries)组成。

(注:

采用一些特别的技巧,也可编写没有main函数的程序)一个C程序可能引用共享库定义的变量或函数,换句话说就是程序运行时必须知道这些变量/函数的地址。

在静态连接中,程序所有需要使用的外部定义都完全包含在可执行程序中,而动态连接则只在可执行文件中设置相关外部定义的一些引用信息,真正的重定位是在程序运行之时。

静态连接方式有两个大问题:

如果库中变量或函数有任何变化都必须重新编译连接程序;

如果多个程序引用同样的变量/函数,则此变量/函数会在文件/内存中出现多次,浪费硬盘/内存空间。

比较两种连接方式生成的可执行文件的大小,可以看出有明显的区别。

a.out文件格式分析

a.out格式在不同的机器平台和不同的UNIX操作系统上有轻微的不同,例如在MC680x0平台上有6个section。

下面我们讨论的是最"

标准"

的格式。

a.out文件包含7个section,格式如下:

execheader(执行头部,也可理解为文件头部)

textsegment(文本段)

datasegment(数据段)

textrelocations(文本重定位段)

datarelocations(数据重定位段)

symboltable(符号表)

stringtable(字符串表)

执行头部的数据结构:

structexec{

unsignedlonga_midmag;

/*魔数和其它信息*/

unsignedlonga_text;

/*文本段的长度*/

unsignedlonga_data;

/*数据段的长度*/

unsignedlonga_bss;

/*BSS段的长度*/

unsignedlonga_syms;

/*符号表的长度*/

unsignedlonga_entry;

/*程序进入点*/

unsignedlonga_trsize;

/*文本重定位表的长度*/

unsignedlonga_drsize;

/*数据重定位表的长度*/

};

文件头部主要描述了各个section的长度,比较重要的字段是a_entry(程序进入点),代表了系统在加载程序并初试化各种环境后开始执行程序代码的入口。

这个字段在后面讨论的ELF文件头部中也有出现。

由a.out格式和头部数据结构我们可以看出,a.out的格式非常紧凑,只包含了程序运行所必须的信息(文本、数据、BSS),而且每个section的顺序是固定的。

这种结构缺乏扩展性,如不能包含"

现代"

可执行文件中常见的调试信息,最初的UNIX黑客对a.out文件调试使用的工具是adb,而adb是一种机器语言调试器!

a.out文件中包含符号表和两个重定位表,这三个表的内容在连接目标文件以生成可执行文件时起作用。

在最终可执行的a.out文件中,这三个表的长度都为0。

a.out文件在连接时就把所有外部定义包含在可执行程序中,如果从程序设计的角度来看,这是一种硬编码方式,或者可称为模块之间是强藕和的。

在后面的讨论中,我们将会具体看到ELF格式和动态连接机制是如何对此进行改进的。

a.out是早期UNIX系统使用的可执行文件格式,由AT&

T设计,现在基本上已被ELF文件格式代替。

a.out的设计比较简单,但其设计思想明显的被后续的可执行文件格式所继承和发扬。

COFF文件格式分析

COFF格式比a.out格式要复杂一些,最重要的是包含一个节段表(sectiontable),因此除了.text,.data,和.bss区段以外,还可以包含其它的区段。

另外也多了一个可选的头部,不同的操作系统可一对此头部做特定的定义。

COFF文件格式如下:

FileHeader(文件头部)

OptionalHeader(可选文件头部)

Section1Header(节头部)

………

SectionnHeader(节头部)

RawDataforSection1(节数据)

RawDataforSectionn(节数据)

RelocationInfoforSect.1(节重定位数据)

RelocationInfoforSect.n(节重定位数据)

LineNumbersforSect.1(节行号数据)

LineNumbersforSect.n(节行号数据)

Symboltable(符号表)

Stringtable(字符串表)

文件头部的数据结构:

structfilehdr

{

unsignedshortf_magic;

/*魔数*/

unsignedshortf_nscns;

/*节个数*/

longf_timdat;

/*文件建立时间*/

longf_symptr;

/*符号表相对文件的偏移量*/

longf_nsyms;

/*符号表条目个数*/

unsignedshortf_opthdr;

/*可选头部长度*/

unsignedshortf_flags;

/*标志*/

};

COFF文件头部中魔数与其它两种格式的意义不太一样,它是表示针对的机器类型,例如0x014c相对于I386平台,而0x268相对于Motorola68000系列等。

当COFF文件为可执行文件时,字段f_flags的值为F_EXEC(0X00002),同时也表示此文件没有未解析的符号,换句话说,也就是重定位在连接时就已经完成。

由此也可以看出,原始的COFF格式不支持动态连接。

为了解决这个问题以及增加一些新的特性,一些操作系统对COFF格式进行了扩展。

Microsoft设计了名为PE(PortableExecutable)的文件格式,主要扩展是在COFF文件头部之上增加了一些专用头部,某些UNIX系统也对COFF格式进行了扩展,如XCOFF(extendedcommonobjectfileformat)格式,支持动态连接。

紧接文件头部的是可选头部,COFF文件格式规范中规定可选头部的长度可以为0,但在LINUX系统下可选头部是必须存在的。

下面是LINUX下可选头部的数据结构:

typedefstruct

charmagic[2];

charvstamp[2];

/*版本号*/

chartsize[4];

/*文本段长度*/

chardsize[4];

/*已初始化数据段长度*/

charbsize[4];

/*未初始化数据段长度*/

charentry[4];

chartext_start[4];

/*文本段基地址*/

chardata_start[4];

/*数据段基地址*/

COFF_AOUTHDR;

字段magic为0413时表示COFF文件是可执行的,注意到可选头部中显式定义了程序进入点,标准的COFF文件没有明确的定义程序进入点的值,通常是从.text节开始执行,但这种设计并不好。

前面我们提到,COFF格式比a

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 小学教育 > 英语

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1