Chinaunix首页 | 论坛 | 博客
  • 博客访问: 296712
  • 博文数量: 71
  • 博客积分: 30
  • 博客等级: 民兵
  • 技术积分: 217
  • 用 户 组: 普通用户
  • 注册时间: 2012-07-31 15:43
文章分类

全部博文(71)

文章存档

2016年(4)

2015年(2)

2014年(2)

2013年(63)

分类: LINUX

2013-05-10 13:21:38

第五章在之前初步熟悉Linux ELF文件格式的基础上,开始介绍了Windows下的目标文件和可执行文件PE/COFF的基本格式。所有内容对我来说也是全新扫盲了。
  •     Windows系统中可执行文件格式为PE(Portable Executable),这是根据COFF文件格式稍作改动扩展发展而来的,框架与COFF基本一致,另外对于Windows平台下的编译器来说,编译生 成的目标文件仍然是COFF格式,PE是Windows下的可执行文件格式。
        Windows PE格式在各个版本的Windows均得到支持,即使是Windows CE的可执行文件格式也是PE。
  •     Visual C++下的编译工具为 cl ,针对C/C++有一些不支持ANSI C/ANSI C++标准的特殊扩展,为了使得应用程序与ANSI标准兼容,在使用VC编译应用程序时可以通过 /Za 参数屏蔽这些扩展,而在应用程序中可以通过对宏 __STDC__ 是否被定义来判定编译器是否禁止了扩展特性。
        VC下提供了类似于binutils之objdump的工具 dumpbin.exe ——通过dumpbin.exe /ALL 打印出来的*.obj目标文件的信息比objdump更精细易读一些
  • COFF文件组成依次为:
    COFF文件头——包括 Image Header 和 段表 两部分,这点与ELF格式有所不同,Image Header中不再需要有段表的偏移。
    各个不同的段——与ELF格式基本一致
    符号表——与ELF格式一致
        因为PE文件在装载时被直接映射到进程的虚拟地址空间中运行,因此PE文件是进程的虚拟地址空间的映像,故PE可执行文件又被称为Image File。
  •     COFF格式的段类型中相对于ELF而言,多了.drectve 段和 .debug$S 段。
        .drectve段保存的是编译器传递给链接器的链接指令,默认地,该段的原始数据内容就是“/DEFAULTLIB:'LIBCMT'”这样的链接指 令,意思是链接器在链接时需要将 libcmt.lib 库文件加入到输入文件中。其中libcmt.lib库文件表示VC的静态链接的多线程C库。
  •     COFF的符号表结构与ELF格式也基本一致,其中一个不同的地方是,对于C语言的符号,COFF只区分两种——变量或其他符号(notye),函数( notye() ),而ELF的符号表中区分的C语言符号包括NOTYPE、OBJECT、FUNC、FILE等几类。
  Windows的可执行文件格式PE源于COFF,最主要的变化包括两点:
1、文件开头不再是COFF文件头,而是DOS MZ可执行文件格式的文件头和DOS桩代码——这点完全是为了当初与DOS下可执行文件的MZ格式兼容。
    虽然Windows下和DOS下的可执行文件都是exe后缀,但是二者其实完全不同,在纯DOS下是不能运行PE文件的,如果在纯DOS环境下运行PE格 式的exe文件,DOS操作系统在识别了PE格式的DOS MZ文件头之后,会跳转到DOS桩代码,执行结果为“This program cannot be run in DOS”后退出。
        反之,在Windows下则可以执行DOS下的exe文件,这是通过判断IMAGE_DOS_HEADER结构体中的 e_lfanew 域实现的。e_lfanew 域指出了PE文件真正的头在文件中的偏移量,对于纯DOS MZ可执行文件,该域永远为0,Windows可以调用DOS子系统来执行该程序。

2、原来的COFF文件头被扩展为了PE的文件头,其中既包括了COFF文件头 IMAGE_FILE_HEADER 结构体,同时增加了一个 IMAGE_OPTINAL_HEADER 扩展头结构——PE扩展头虽然名为OPTINAL,但是实际上对于PE和DLL文件来说是必不可少的,其定义在WinNt.h中,区分为32/64位两种。该结构体中最重要的是 IMAGE_DATA_DIRECTORY  DataDirectory[ IMAGE_NUMBEROF_DIRECTORY_ENTRIES ],这个结构体数组被称为“PE数据目录”,定义了PE程序加载执行时所需要的众多数据结构("XX表",例如导入表、导出表、资源表、异常表、重定位表等),每个IMAGE_DATA_DIRECTORY结构体描述一个这样的“XX表”,其数据域如下:
VirtualAddress —— XX表所在的起始虚拟地址
Size; —— XX表的长度
阅读(1973) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~