Windows可执行文件简述(三)
4.LE格式
在Windows3.x的时代,从DOS启动Windows,Windows在把机器转到保护模式之前需要在实模式下做一些初始化。实模式的16位代码必须和32位代码一起放在可执行文件中。旧的DOS下的可执行文件和NE格式的可执行文件无法满足这个要求,于是从Win 3.x起到Win 9x,产生了一种新型的可执行文件格式LE,它只适用于工作于系统底层的、同时包含16位代码和32位代码的VxD驱动程序。OS/2 2.x也使用LE格式。
一般而言,保护模式下的可执行文件会在不同的Sections中放置程序代码和数据,利用可执行文件头中的各种属性标志来告诉可执行文件加载器在面对这些Sections时的各种细节动作。但是VxD却将程序代码和数据混杂在段之中,通过不同段前的标识来表明该段在运行时的特性。程序代码和数据之所以能够混杂在一起,而仍然能够有效运作,是因为VxD所使用的平坦模式的代码和平坦模式下的数据选择器有相同的基地址与限制因素。因此不论使用上述哪一个寄存器缓存器都可以取用程序代码或数据。
下图是LE格式的可执行文件的结构示意图:
MZ文件头 | DOS文件头 |
DOS Stub程序 | |
LE标志 | |
LE文件头 | LE文件头 |
LCODE | 程序段 |
PCODE | |
…… …… | |
16ICODE | |
MCODE |
在LE文件中,代码和数据被存放在几类运行属性不同的段中。下面是LE文件之中一些可用的段类:
LCODE:页面锁定的代码和数据段。这种段被锁定在内存里。换句话说,这段永远不会被放到硬盘上去,所以你一定要谨慎的使用这种段类以免浪费宝贵的内存。那些每时每刻都必须放在内存中的代码和数据应该放在这个段里。尤其是那些硬件中断处理程序。
PCODE:可调页代码段。VMM可以对这种段实行调页处理,在这种段里的代码不必时刻放在内存里,当VMM需要物理内存的时候,它就会把这段放到硬盘上去。
PDATA:可调页数据段。
ICODE:仅用于的初始化段。这种段里的代码仅仅用来进行VxD的初始化。当初始化完成后,VMM就把这段从内存中释放。
DBOCODE:仅用于调试的代码数据段。当你要调试VxD程序时,就要用到这种段里的代码和数据,例如,它包含要调试的消息的处理代码。
SCODE:静态代码和数据段。这种段时刻存在于内存中,即使VxD已经卸载,这种段对某些动态的VxD程序很有用,这些VxD程序需要在某一Windows进程里不停的加载/卸载而又要纪录上次的环境和状态。
RCODE:实模式初始化代码数据段。这种段包含实模式初始化需要的16位代码和数据。
16ICODE:保护模式初始化数据段。这是一个16位的段,它包含VxD要从保护模式拷贝到V86模式的代码。例如,如果你要把一些V86的代码拷贝到一个虚拟机上时,你想拷贝的代码就要放在这里。如果你把它放在其他的段里,编译程序就会产生错误的代码,例如,它会产生32位代码而不是16位代码。
MCODE:锁定的消息字串。这种段包含了由VMM消息宏帮助编译的消息字串,这有助于你构造你的驱程的国际版本。
5.PE格式
16位的程序是不健壮的,因此为了保证Windows的健壮性,Microsoft在Microsoft Windows NT 3.1及其以后的操作系统版本,也就是所有的基于Win32的操作系统中推出了一种新的可执行文件的格式,也就是PE文件格式。PE的意思就是Portable Executable(可移植的可执行文件),内含32位程序代码和数据,是UNIX Common Object File Format(COFF)的演化。PE格式比其它格式优越的关键点在于它有依字母次序排列的Exports,以及一个可以直接将程序影像映像成虚拟内存的内存文件映射功能。与此同时,Microsoft也推出了新的obj文件和lib文件的格式。PE文件结构的总体层次分布图如下:
DOS MZ Header |
DOS 实模式存根(Stub)程序 |
PE Header(PE文件标记等) |
Optional Header |
.text Section Header |
.bss Section Header |
.rdata Section Header |
…………………… |
.debug Section Header |
.text Section |
.bss Section |
.rdata Section |
……………… |
.debug Section |
从PE开始,可执行文件的结构开始有了正式的文档化。Microsoft在Visual C++ 6的联机文档(即《MSDN Library Visual Studio 6.0》)中给出了以C语言描述的PE结构,这给开发者提供了很大的方便。同时还在VC的Include目录里的WINNT.h文件中提供PE的各结构的定义,提供了PE文件中使用的原始数据结构。
=======================================================================
rivershan原创于2004年3月23日 3:38