欢迎来到天天文库
浏览记录
ID:14203246
大小:51.50 KB
页数:16页
时间:2018-07-26
《漫谈兼容内核之六:二进制映像的类型识别》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库。
1、漫谈兼容内核之六:二进制映像的类型识别漫谈兼容内核之六:二进制映像的类型识别[b][size=4][align=center]漫谈兼容内核之六:二进制映像的类型识别[/align][/size][/b][align=center][i]毛德操[/i][/align]除了某些嵌入式系统之外,一般而言操作系统都有个在创建(或转化成)新进程时如何装入目标程序的二进制映像并启动其运行的问题。由于在计算机技术的发展历史中并没有形成某种单一的、为所有操作系统和编译/连接工具所共同遵循的标准,这个装入/启动的过程就不可避免地呈现出多样性。而且,即使是同一种操作系统,也会在其发
2、展的过程中采用多种不同的目标映像格式和装入机理。而动态连接库技术的出现,则又使这个过程进一步地复杂化了,因为此时需要装入的不仅是目标程序的映像,还有动态连接库的映像,并且还要解决目标程序与具体库函数的动态连接问题。至于这个过程的重要性,那是不言而喻的,要不然操作系统就要么实际上不能做“有用功”,要么失去了通用性和灵活性。以Linux应用软件为例,就既有a.out格式,又有ELF格式,又支持动态连接库。我在“情景分析”一书中只讲了a.out映像的装入和启动,是因为a.out相对比较简单,否则篇幅太大。读者也许会问,既然有了更复杂、功能更强的ELF格式,为什么还要保
3、留a.out格式呢?这当然是为了向后兼容,一种技术一旦被广泛采用以后就不会很快消失。与Linux相比,Windows采用的格式就更多了,因为它还需要支持DOS时代的应用软件。兼容内核既要支持Linux和Windows两种操作系统的应用软件,这个问题当然就更复杂、难度更大了。幸而Wine已经在我们之前以它的方式解决了这个问题,使我们至少有了可以借鉴的榜样。在讲述Wine的软件映像的装入/启动过程之前,我们先考察一下,为了兼容Windows软件,Wine需要支持那一些映像格式,以及如何识别一个映像所属的格式和类型。为此,我们看一下Wine的一段代码,这段代码在dll
4、s/kernel/module.c中,是在用户空间执行的。这是一个名为MODULE_GetBinaryType()的函数,其作用是辨认一个已打开文件所属的映像格式并进而判定其类型,已定义的类型有:[code]enumbinary_type{BINARY_UNKNOWN,BINARY_PE_EXE,BINARY_PE_DLL,BINARY_WIN16,BINARY_OS216,BINARY_DOS,BINARY_UNIX_EXE,BINARY_UNIX_LIB};[/code]除BINARY_UNKNOWN表示无法辨认/判定以外,这里定义了7种映像类型。其中BIN
5、ARY_PE_EXE和BINARY_PE_DLL是Windows的32位“PE格式”映像,前者为目标应用程序,后者为动态连接库DLL。注意前者是“有源”的主体,可以成为一个进程;而后者是“无源”的库程序,不能独立成为一个进程。BINARY_WIN16和BINARY_OS216则为16位Windows应用;后者实际上是OS/2操作系统的应用程序,但是因为微软和IBM曾经紧密合作,所以Windows也支持OS/2的应用程序。再往下BINARY_DOS显然是DOS的应用软件,但是DOS上的可执行程序有.exe和.com两种,这里并未加以区分,其原因留待以后再说。最后是
6、BINARY_UNIX_EXE和BINARY_UNIX_LIB,Linux是Unix的继承者,所以也适用于Linux的应用程序和动态连接库。下面可以看代码了,我们分段阅读。[code]enumbinary_typeMODULE_GetBinaryType(HANDLEhfile,void**res_start,void**res_end){union{struct{unsignedcharmagic[4];unsignedcharignored[12];unsignedshorttype;}elf;struct{unsignedlongmagic;unsigne
7、dlongcputype;unsignedlongcpusubtype;unsignedlongfiletype;}macho;IMAGE_DOS_HEADERmz;}header;DWORDlen;/*Seektothestartofthefileandreadtheheaderinformation.*/if(SetFilePointer(hfile,0,NULL,SEEK_SET)==-1)returnBINARY_UNKNOWN;if(!ReadFile(hfile,&header,sizeof(header),&len,NULL)
8、
9、len!=size
10、of(header))r
此文档下载收益归作者所有