QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2285|回复: 1
打印 上一主题 下一主题

[转载]LIB文件的结构(1)

[复制链接]
字体大小: 正常 放大
Blackbird        

8

主题

2

听众

21

积分

升级  16.84%

该用户从未签到

新人进步奖

跳转到指定楼层
1#
发表于 2005-9-17 14:48 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
<><STRONG>重要声明:本文乃转载自其他社区,由于在下无法获得任何有关作者和出处的信息,所以不能在此登出,恳请作者原谅,并希望知情者能告知在下。本着资源的共享的精神,在下深信作者不会拒绝在下的转载行为。同时强烈BS数学中国的下载系统,它不但不能及时给予他人需要的帮助,还浪费了他人大量的时间,仅仅是为了获得无聊的点数,而且遗憾的是,那些点数并不能保证你真能获得帮助!</STRONG></P>: L( A& e5 C1 X- W4 E( m" f
<>下面让我们来仔细看看每一小节的内容:</P>
  ]+ z) j6 K0 z7 x<><STRONG>First Sec<BR></STRONG>    第一节,通常就是Lib中的每一个小节。它的名称是“/”。其数据部分的结构如下:<BR>    typedef struct {<BR>        unsigned long SymbolNum;         // 库中符号的数量<BR>        unsigned long SymbolOffset[n];   // 符号所在目标节的偏移<BR>        char StrTable[m];                // 符号名称字符串表<BR>    }FirstSec;<BR>    第一个成员SymbolNum是符号的数量。注意!它是以Big-Endian方式储存的(x86平台上的数据是以Little-Endian方式储存的。这里应该注意转换。后面给出的convert函数可以在Little-Endian格式与Big-Endian格式之间进行相互转换)。<BR>    第二个成员SymbolOffset是一个数组,它的长度n就是符号的数量,也就是SymbolNum。这个数组储存了每一个符号所在的目标节的偏移。我们可以方便地通过它来查找符号所在的目标文件。注意!它也是以Big-Endian格式储存的。<BR>    第三个成员StrTable是一个字符串表,它的长度m就是SectionHeader.Size的值减去(SymbolNum+1)*4。其结构很简单,就是一堆以‘\0’结尾的字符串(和COFF文件中的字符串表结构相同)。在有的系统中,它还可能是以“/\n”这两个字符结尾的字符串的集合。<BR>    很简单的一个结构,不过有两个成员的长度是不定的。怎么才能方便地从Lib中读出这些数据,留给大家自己想吧!下面我只给出一个进行Little-Endian与Big-Endian互转的函数。<BR>    inline void convert(void * p          // 要转换的数据的指针<BR>                        ,size_t size = 4  // 数据的长度,long为4,short为2<BR>                        ) {<BR>        char * buf=(char*)p;<BR>        char temp;<BR>        for ( size_t i=0;i&lt;size/2;i++ ) {<BR>            temp=buf;<BR>            buf=buf[size-i-1];<BR>            buf[size-i-1]=temp;<BR>        }<BR>    } </P>
& ?8 `8 }, x! d2 F) [<DIV> </DIV>
4 m  s% W/ |2 f! I$ c9 _<DIV><STRONG>Second Sec<BR></STRONG>    现在看看第二节。<BR>    这一节与第一节很相似!它通常也就是Lib文件的第二个节。它的名字也是“/”(注意:文件中第一个叫“/”的节是第一节,第二个就是第二节)。不过它的结构与第一节有些不同,如下:<BR>    typedef struct {<BR>        unsigned long ObjNum;        // Obj Sec的数量<BR>        unsigned long ObjOffset[x];  // 每一个Obj Sec的偏移<BR>        unsigned long SymbolNum;     // 库中符号的数量<BR>        unsigned short SymbolIdx[n]; // 符号在ObjOffset表中的索引<BR>        char StrTable[m];            // 符号名称字符串表<BR>    }SecondSec;<BR>    第一个成员ObjNum是库中Obj Sec的数量。<BR>    第二个成员ObjOffset是一个偏移表,它记录了库中所有Obj Sec的偏移。这个表的记录数x就是ObjNum。<BR>    第三个成员SymbolNum与First Sec中的SymbolNum意义相同。<BR>    第四个成员SymbolIdx变成了一个索引,它记录了相应名称字符串在ObjOffset这个表中的位置,我们要通过两次索引才能找到我们所要符号的Obj Sec位置。它的项目数n为SymbolNum。但请注意,这个索引是unsigned short型,不再是unsigned long型。<BR>    第五个成员StrTable结构与First Sec中的一样。不过,它的长度m为SectionHeader.Size的值减去((ObjNum+1)*4+(SymbolNum+2)*2)。<BR>    值得注意的是,这里的所有数据都是Little-Endian格式的。千万不要弄错了!<BR><BR><STRONG>Longname Sec</STRONG><BR>    这个小节就是一个字符串表,它的名称为“//”,其结构同FirstSec.StrTable。这里就不多说了。<BR><STRONG><BR>Obj Sec</STRONG><BR>    这一节中的数据就是COFF文件的原始数据,把它读出来存成文件,就是一个COFF文件。它的格式请参考《COFF格式》一文。<BR>    要指出的是它的命名方式有些特殊。如果Obj文件的名称少于16个字符,它就会被保存在SectionHeader的Name成员中,以‘/’字符结尾。如果无法保存在Name成员中,则Name成员的第一个字符就为‘/’,之后再跟上这个名称在Longname Sec中的偏移。<BR><STRONG><BR>例如</STRONG>:<BR>!&lt;arch&gt;\n<BR>……<BR>LongName Sec:<BR>This_Is_Long_Name0001\0<BR>This_Is_Long_Name0002\0<BR>……<BR>Obj Sec1:<BR> Name[16]:“shortname/”<BR> ……<BR>Obj Sec2:<BR> Name[16]:“/0”  // 这里使用了第一个长文件名This_Is_Long_Name0001<BR> ……<BR>Obj Sec3:<BR> Name[16]:“/22”  // 这里使用了第二个长文件名This_Is_Long_Name0002<BR> ……</DIV>: l( m2 e& y, B' I( v/ S
<DIV> </DIV>+ ^' G2 `5 l  C( P
<DIV>    OK!现在已经介绍完了Lib文件的结构。大家的连接器可以加新功能了。不过这里只给出了最基本的Lib文件结构,动态连接库(DLL)的导出库有点特别,我将在PE文件格式中进行详细介绍。</DIV>
zan
转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信

1

主题

2

听众

60

积分

升级  57.89%

该用户从未签到

新人进步奖

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册地址

qq
收缩
  • 电话咨询

  • 04714969085
fastpost

关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

手机版|Archiver| |繁體中文 手机客户端  

蒙公网安备 15010502000194号

Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

GMT+8, 2025-12-29 19:12 , Processed in 4.756206 second(s), 58 queries .

回顶部