找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 6997|回复: 2

LIB格式的文件的读取(提取OBJ)

[复制链接]
发表于 2014-1-26 03:47:57 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×
LIB文件就是多个OBJ文件的集合。为什么会有LIB呢?因为有了LIB,链接器就可以筛选掉不需要的OBJ文件,把需要的OBJ提取出来并连接起来。
VC6、MinGW编译通过。
  1. /*
  2. LIB文件的结构:
  3.     文件标记:"!<arch>\n"
  4.     第一节
  5.     第二节
  6.     各种节
  7.     其中第一节的数据为:
  8.         节头
  9.         LIB文件的所有符号以及偏移信息(都是Big-Endian)
  10.     第二节的数据为:
  11.         节头
  12.         LIB文件所有符号所在OBJ文件的索引,OBJ文件的数量以及偏移
  13.     其中每个OBJ文件占用一个节(也就是后面的“各种节”的内容)
  14.     解析LIB文件的流程:
  15.     打开LIB文件,得到一个FILE*
  16.     读取前8个字节,判断文件标识是不是"!<arch>\n"
  17.     调用ReadSecHead读取第一个节头
  18.     调用ReadFirstSecData读取第一个节的信息
  19.     调用ReadSecHead读取第二个节头
  20.     调用ReadSecondSecData读取第二个节的信息
  21.     调用ExtractOBJFiles提取所有OBJ
  22.     关闭文件
  23.     有些LIB有一个名为"//"的节,内容是OBJ文件名的表,可无视。
  24. */
  25. #include<stdio.h>
  26. #include<stdlib.h>
  27. #include<string.h>
  28. #include<malloc.h>
  29. #ifndef MAX_PATH
  30. #define MAX_PATH    260             //标准的路径不超过260字节
  31. #endif
  32. typedef unsigned    long    DWORD;
  33. typedef unsigned    short   WORD;
  34. typedef unsigned    char    BYTE;
  35. typedef unsigned    int     BOOL;
  36. #define TRUE    1
  37. #define FALSE   0
  38. //主要函数:
  39. void    ReadSecHead(FILE *fp);                          //读取节头
  40. BOOL    ReadFirstSecData(FILE *fp);                     //读取第一节的数据,也就是LIB的所有符号以及偏移信息(都是Big-Endian)
  41. BOOL    ReadSecondSecData(FILE *fp);                    //读取第二节的数据,也就是OBJ文件的数量、偏移信息
  42. BOOL    ExtractOBJFiles(FILE *fp,char *szObjDir);       //提取所有OBJ文件
  43. //辅助函数:
  44. BOOL    MoveFileSec(FILE* fpr,size_t Size,FILE* fpw);   //把文件1中的内容移动到文件2(并不是逐字节移动,所以比较快,但是占内存)
  45. void    ReadOneSymbol(FILE *fp);                        //从文件的当前位置读取一个字符串,读到0就停止,读一个字节打印一个字节。
  46. void    PrintSecHead();                                 //打印节头信息
  47. //读取到的LIB文件的一些信息
  48. //节头信息(字符串,用空格补齐)
  49. char    g_szName[16     +1];    //节名
  50. char    g_szTime[12     +1];    //时间戳
  51. char    g_szUserID[6    +1];    //用户ID
  52. char    g_szGroupID[6   +1];    //组ID
  53. char    g_szMode[8      +1];    //模式
  54. char    g_szSize[10     +1];    //大小(除去节头外,十进制)
  55. char    g_szEnd[2       +1];    //结束标记("`\n")
  56. //第一节的数据
  57. DWORD   g_dwFirstSecSymbols;
  58. DWORD*  g_pdwFirstSecSymbolOffsets;
  59. //第二节的数据
  60. DWORD   g_dwObjFiles;
  61. DWORD*  g_pdwObjOffsets;
  62. DWORD   g_dwSymbols;
  63. WORD*   g_pwSymbolIndices;
  64. //Big-Endian转Little-Endian的宏,汇编可以使用BSWAP指令来完成(影响可移植性,所以只用宏)
  65. #define BE2LE(x) ((((x)&0x000000FFL)<<24)|(((x)&0x0000FF00L)<<8)|(((x)&0x00FF0000L)>>8)|(((x)&0xFF000000L)>>24))
  66. //=============================================================================
  67. //MoveFileSec:
  68. //分段拷贝文件内容
  69. //-----------------------------------------------------------------------------
  70. BOOL MoveFileSec(FILE* fpr,size_t Size,FILE* fpw)
  71. {
  72.     char    *pBuf;
  73.     size_t  lBufferSize,lBytesRest;
  74.     lBufferSize=lBytesRest=Size;
  75.     do
  76.         pBuf=(char*)malloc(lBufferSize--);
  77.     while(!pBuf&&lBufferSize);
  78.     if(!lBufferSize)
  79.         return FALSE;
  80.     lBufferSize++;
  81.     while(lBytesRest>lBufferSize)
  82.     {
  83.         fread(pBuf,1,lBufferSize,fpr);
  84.         fwrite(pBuf,1,lBufferSize,fpw);
  85.         lBytesRest-=lBufferSize;
  86.     }
  87.     fread(pBuf,1,lBytesRest,fpr);
  88.     fwrite(pBuf,1,lBytesRest,fpw);
  89.     free(pBuf);
  90.     return TRUE;
  91. }
  92. //=============================================================================
  93. //ReadOneSymbol:
  94. //读取一个符号
  95. //-----------------------------------------------------------------------------
  96. void ReadOneSymbol(FILE *fp)
  97. {
  98.     int ch;
  99.     for(ch=fgetc(fp);ch;ch=fgetc(fp))
  100.         putchar(ch);
  101. }
  102. //=============================================================================
  103. //ReadSecHead:
  104. //读取节头
  105. //-----------------------------------------------------------------------------
  106. void ReadSecHead(FILE *fp)
  107. {
  108.     fread(g_szName,1,16,fp);    g_szName[16]=0;
  109.     fread(g_szTime,1,12,fp);    g_szTime[12]=0;
  110.     fread(g_szUserID,1,6,fp);   g_szUserID[6]=0;
  111.     fread(g_szGroupID,1,6,fp);  g_szGroupID[6]=0;
  112.     fread(g_szMode,1,8,fp);     g_szMode[8]=0;
  113.     fread(g_szSize,1,10,fp);    g_szSize[10]=0;
  114.     fread(g_szEnd,1,2,fp);      g_szEnd[2]=0;
  115. }
  116. //=============================================================================
  117. //PrintSecHead:
  118. //打印节头
  119. //-----------------------------------------------------------------------------
  120. void PrintSecHead()
  121. {
  122.     printf(
  123.         "Name:\t\t%s\n"
  124.         "Time:\t\t%s\n"
  125.         "User ID:\t%s\n"
  126.         "Group ID:\t%s\n"
  127.         "Mode:\t\t%s\n"
  128.         "Size:\t\t%s\n"
  129.         "End:\t\t%s\n"
  130.         ,
  131.         g_szName,
  132.         g_szTime,
  133.         g_szUserID,
  134.         g_szGroupID,
  135.         g_szMode,
  136.         g_szSize,
  137.         g_szEnd);
  138. }
  139. //=============================================================================
  140. //ReadFirstSecData:
  141. //读取第一节数据
  142. //-----------------------------------------------------------------------------
  143. BOOL ReadFirstSecData(FILE *fp)
  144. {
  145.     DWORD i;
  146.     fread(&g_dwFirstSecSymbols,1,sizeof(g_dwFirstSecSymbols),fp);
  147.     g_dwFirstSecSymbols=BE2LE(g_dwFirstSecSymbols);
  148.     printf("Symbols:%lu\n",g_dwFirstSecSymbols);
  149.     g_pdwFirstSecSymbolOffsets=(DWORD*)malloc(sizeof(DWORD)*g_dwFirstSecSymbols);
  150.     if(!g_pdwFirstSecSymbolOffsets)
  151.     {
  152.         printf("Insufficient memory.\n");
  153.         return FALSE;
  154.     }
  155.     fread(g_pdwFirstSecSymbolOffsets,sizeof(g_dwFirstSecSymbols),g_dwFirstSecSymbols,fp);
  156.     printf("Offset:\t\tSymbol name:\n");
  157.     for(i=0;i<g_dwFirstSecSymbols;i++)
  158.     {
  159.         printf("0x%08X\t",BE2LE(g_pdwFirstSecSymbolOffsets[i]));
  160.         ReadOneSymbol(fp);
  161.         putchar('\n');
  162.     }
  163.     return TRUE;
  164. }
  165. //=============================================================================
  166. //ReadFirstSecData:
  167. //读取第二节数据
  168. //-----------------------------------------------------------------------------
  169. BOOL ReadSecondSecData(FILE *fp)
  170. {
  171.     DWORD i;
  172.     fread(&g_dwObjFiles,1,sizeof(g_dwObjFiles),fp);
  173.     printf("OBJ files: %lu\n",g_dwObjFiles);
  174.     g_pdwObjOffsets=(DWORD*)malloc(sizeof(DWORD)*g_dwObjFiles);
  175.     if(!g_pdwObjOffsets)
  176.     {
  177.         printf("Insufficient memory.\n");
  178.         return FALSE;
  179.     }
  180.     fread(g_pdwObjOffsets,sizeof(DWORD),g_dwObjFiles,fp);
  181.     printf("OBJ file offsets:\n");
  182.     for(i=0;i<g_dwObjFiles;i++)
  183.         printf("\t0x%08X\n",g_pdwObjOffsets[i]);
  184.     fread(&g_dwSymbols,1,sizeof(g_dwSymbols),fp);
  185.     printf("Symbols: %lu\n",g_dwSymbols);
  186.     g_pwSymbolIndices=(WORD*)malloc(sizeof(WORD)*g_dwSymbols);
  187.     if(!g_pwSymbolIndices)
  188.     {
  189.         printf("Insufficient memory.\n");
  190.         return FALSE;
  191.     }
  192.     fread(g_pwSymbolIndices,sizeof(WORD),g_dwSymbols,fp);
  193.     for(i=0;i<g_dwSymbols;i++)
  194.     {
  195.         printf("Symbol "");
  196.         ReadOneSymbol(fp);
  197.         switch(g_pwSymbolIndices[i])
  198.         {
  199.         case 1:
  200.             printf("" can be found in the 1st OBJ file.\n");
  201.             break;
  202.         case 2:
  203.             printf("" can be found in the 2nd OBJ file.\n");
  204.             break;
  205.         case 3:
  206.             printf("" can be found in the 3rd OBJ file.\n");
  207.             break;
  208.         default:
  209.             printf("" can be found in the %uth OBJ file.\n",g_pwSymbolIndices[i]);
  210.             break;
  211.         }
  212.     }
  213.     return TRUE;
  214. }
  215. //=============================================================================
  216. //ExtractOBJFiles:
  217. //提取OBJ文件
  218. //-----------------------------------------------------------------------------
  219. BOOL ExtractOBJFiles(FILE *fp,char *szObjDir)
  220. {
  221.     FILE    *fpw;
  222.     char    szFile[MAX_PATH];
  223.     size_t  Size;
  224.     DWORD   i;
  225.     for(i=0;i<g_dwObjFiles;i++)
  226.     {
  227.         sprintf(szFile,"%s_%u.obj",szObjDir,i+1);
  228.         printf("Writing %s:\n",szFile);
  229.         fpw=fopen(szFile,"wb");
  230.         if(!fpw)
  231.         {
  232.             printf("Couldn't open %s.\n");
  233.             return FALSE;
  234.         }
  235.         fseek(fp,g_pdwObjOffsets[i],SEEK_SET);
  236.         ReadSecHead(fp);
  237.         printf("OBJ section information:\n");
  238.         PrintSecHead();
  239.         Size=atol(g_szSize);
  240.         if(Size)
  241.         {
  242.             if(!MoveFileSec(fp,Size,fpw))
  243.             {
  244.                 printf("Couldn't write to OBJ.\n");
  245.                 fclose(fpw);
  246.                 return FALSE;
  247.             }
  248.         }
  249.         else
  250.         {
  251.             printf("Incorrect LIB sector header.\n");
  252.             fclose(fpw);
  253.             return FALSE;
  254.         }
  255.         printf("Success.\n\n");
  256.         fclose(fpw);
  257.     }
  258.     return TRUE;
  259. }
  260. //=============================================================================
  261. //main:
  262. //程序入口点
  263. //-----------------------------------------------------------------------------
  264. int main(int argc,char** argv)
  265. {
  266.     FILE*   fp;
  267.     char    szSignature[8   +1];
  268.     char    szDir[MAX_PATH],*pch;
  269.     if(argc<2)
  270.     {
  271.         printf("Usage:\n\tANALIB LIBFILE.LIB\n");
  272.         return -1;
  273.     }
  274.     fp=fopen(argv[1],"rb");
  275.     if(!fp)
  276.     {
  277.         printf("Unable to open %s.\n",argv[1]);
  278.         return -1;
  279.     }
  280.     fread(szSignature,1,8,fp);          //读取文件标记
  281.     szSignature[8]=0;
  282.     if(strcmp(szSignature,"!<arch>\n")) //判断文件标记
  283.     {
  284.         printf("Not a LIB file.\n");
  285.         fclose(fp);
  286.         return -1;
  287.     }
  288. #define V(arg)  if(!(arg)){fclose(fp);return -1;}
  289.     //读取第一个节
  290.     printf("Now is reading the 1st section in the LIB file.\n");
  291.     ReadSecHead(fp);
  292.     PrintSecHead();
  293.     V(ReadFirstSecData(fp));
  294.     //读取第二个节
  295.     printf("Now is reading the 2nd section in the LIB file.\n");
  296.     ReadSecHead(fp);
  297.     PrintSecHead();
  298.     V(ReadSecondSecData(fp));
  299.     //提取所有OBJ
  300.     printf("Now is extracting OBJ files from the LIB file.\n");
  301.     strcpy(szDir,argv[1]);
  302.     pch=strrchr(szDir,'.');
  303.     if(pch)*pch=0;
  304.     V(ExtractOBJFiles(fp,szDir));
  305.     fclose(fp);
  306.     return FALSE;
  307. }
复制代码
SRC+BIN下载: ANALIB.7z (425.61 KB, 下载次数: 7, 售价: 10 个宅币)
回复

使用道具 举报

发表于 2016-2-13 22:42:36 | 显示全部楼层
没想到我是沙发
回复 赞! 靠!

使用道具 举报

发表于 2018-5-3 20:16:44 | 显示全部楼层
提取BCB编译的LIB失败啊,当然它是OMF格式,而不是COFF,不过还是麻烦楼主研究一下这个问题!!
回复 赞! 靠!

使用道具 举报

本版积分规则

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-11-24 12:13 , Processed in 0.033443 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表