- UID
- 1
- 精华
- 积分
- 76361
- 威望
- 点
- 宅币
- 个
- 贡献
- 次
- 宅之契约
- 份
- 最后登录
- 1970-1-1
- 在线时间
- 小时
|
LIB文件就是多个OBJ文件的集合。为什么会有LIB呢?因为有了LIB,链接器就可以筛选掉不需要的OBJ文件,把需要的OBJ提取出来并连接起来。
VC6、MinGW编译通过。- /*
- LIB文件的结构:
- 文件标记:"!<arch>\n"
- 第一节
- 第二节
- 各种节
- 其中第一节的数据为:
- 节头
- LIB文件的所有符号以及偏移信息(都是Big-Endian)
- 第二节的数据为:
- 节头
- LIB文件所有符号所在OBJ文件的索引,OBJ文件的数量以及偏移
- 其中每个OBJ文件占用一个节(也就是后面的“各种节”的内容)
- 解析LIB文件的流程:
- 打开LIB文件,得到一个FILE*
- 读取前8个字节,判断文件标识是不是"!<arch>\n"
- 调用ReadSecHead读取第一个节头
- 调用ReadFirstSecData读取第一个节的信息
- 调用ReadSecHead读取第二个节头
- 调用ReadSecondSecData读取第二个节的信息
- 调用ExtractOBJFiles提取所有OBJ
- 关闭文件
- 有些LIB有一个名为"//"的节,内容是OBJ文件名的表,可无视。
- */
- #include<stdio.h>
- #include<stdlib.h>
- #include<string.h>
- #include<malloc.h>
- #ifndef MAX_PATH
- #define MAX_PATH 260 //标准的路径不超过260字节
- #endif
- typedef unsigned long DWORD;
- typedef unsigned short WORD;
- typedef unsigned char BYTE;
- typedef unsigned int BOOL;
- #define TRUE 1
- #define FALSE 0
- //主要函数:
- void ReadSecHead(FILE *fp); //读取节头
- BOOL ReadFirstSecData(FILE *fp); //读取第一节的数据,也就是LIB的所有符号以及偏移信息(都是Big-Endian)
- BOOL ReadSecondSecData(FILE *fp); //读取第二节的数据,也就是OBJ文件的数量、偏移信息
- BOOL ExtractOBJFiles(FILE *fp,char *szObjDir); //提取所有OBJ文件
- //辅助函数:
- BOOL MoveFileSec(FILE* fpr,size_t Size,FILE* fpw); //把文件1中的内容移动到文件2(并不是逐字节移动,所以比较快,但是占内存)
- void ReadOneSymbol(FILE *fp); //从文件的当前位置读取一个字符串,读到0就停止,读一个字节打印一个字节。
- void PrintSecHead(); //打印节头信息
- //读取到的LIB文件的一些信息
- //节头信息(字符串,用空格补齐)
- char g_szName[16 +1]; //节名
- char g_szTime[12 +1]; //时间戳
- char g_szUserID[6 +1]; //用户ID
- char g_szGroupID[6 +1]; //组ID
- char g_szMode[8 +1]; //模式
- char g_szSize[10 +1]; //大小(除去节头外,十进制)
- char g_szEnd[2 +1]; //结束标记("`\n")
- //第一节的数据
- DWORD g_dwFirstSecSymbols;
- DWORD* g_pdwFirstSecSymbolOffsets;
- //第二节的数据
- DWORD g_dwObjFiles;
- DWORD* g_pdwObjOffsets;
- DWORD g_dwSymbols;
- WORD* g_pwSymbolIndices;
- //Big-Endian转Little-Endian的宏,汇编可以使用BSWAP指令来完成(影响可移植性,所以只用宏)
- #define BE2LE(x) ((((x)&0x000000FFL)<<24)|(((x)&0x0000FF00L)<<8)|(((x)&0x00FF0000L)>>8)|(((x)&0xFF000000L)>>24))
- //=============================================================================
- //MoveFileSec:
- //分段拷贝文件内容
- //-----------------------------------------------------------------------------
- BOOL MoveFileSec(FILE* fpr,size_t Size,FILE* fpw)
- {
- char *pBuf;
- size_t lBufferSize,lBytesRest;
- lBufferSize=lBytesRest=Size;
- do
- pBuf=(char*)malloc(lBufferSize--);
- while(!pBuf&&lBufferSize);
- if(!lBufferSize)
- return FALSE;
- lBufferSize++;
- while(lBytesRest>lBufferSize)
- {
- fread(pBuf,1,lBufferSize,fpr);
- fwrite(pBuf,1,lBufferSize,fpw);
- lBytesRest-=lBufferSize;
- }
- fread(pBuf,1,lBytesRest,fpr);
- fwrite(pBuf,1,lBytesRest,fpw);
- free(pBuf);
- return TRUE;
- }
- //=============================================================================
- //ReadOneSymbol:
- //读取一个符号
- //-----------------------------------------------------------------------------
- void ReadOneSymbol(FILE *fp)
- {
- int ch;
- for(ch=fgetc(fp);ch;ch=fgetc(fp))
- putchar(ch);
- }
- //=============================================================================
- //ReadSecHead:
- //读取节头
- //-----------------------------------------------------------------------------
- void ReadSecHead(FILE *fp)
- {
- fread(g_szName,1,16,fp); g_szName[16]=0;
- fread(g_szTime,1,12,fp); g_szTime[12]=0;
- fread(g_szUserID,1,6,fp); g_szUserID[6]=0;
- fread(g_szGroupID,1,6,fp); g_szGroupID[6]=0;
- fread(g_szMode,1,8,fp); g_szMode[8]=0;
- fread(g_szSize,1,10,fp); g_szSize[10]=0;
- fread(g_szEnd,1,2,fp); g_szEnd[2]=0;
- }
- //=============================================================================
- //PrintSecHead:
- //打印节头
- //-----------------------------------------------------------------------------
- void PrintSecHead()
- {
- printf(
- "Name:\t\t%s\n"
- "Time:\t\t%s\n"
- "User ID:\t%s\n"
- "Group ID:\t%s\n"
- "Mode:\t\t%s\n"
- "Size:\t\t%s\n"
- "End:\t\t%s\n"
- ,
- g_szName,
- g_szTime,
- g_szUserID,
- g_szGroupID,
- g_szMode,
- g_szSize,
- g_szEnd);
- }
- //=============================================================================
- //ReadFirstSecData:
- //读取第一节数据
- //-----------------------------------------------------------------------------
- BOOL ReadFirstSecData(FILE *fp)
- {
- DWORD i;
- fread(&g_dwFirstSecSymbols,1,sizeof(g_dwFirstSecSymbols),fp);
- g_dwFirstSecSymbols=BE2LE(g_dwFirstSecSymbols);
- printf("Symbols:%lu\n",g_dwFirstSecSymbols);
- g_pdwFirstSecSymbolOffsets=(DWORD*)malloc(sizeof(DWORD)*g_dwFirstSecSymbols);
- if(!g_pdwFirstSecSymbolOffsets)
- {
- printf("Insufficient memory.\n");
- return FALSE;
- }
- fread(g_pdwFirstSecSymbolOffsets,sizeof(g_dwFirstSecSymbols),g_dwFirstSecSymbols,fp);
- printf("Offset:\t\tSymbol name:\n");
- for(i=0;i<g_dwFirstSecSymbols;i++)
- {
- printf("0x%08X\t",BE2LE(g_pdwFirstSecSymbolOffsets[i]));
- ReadOneSymbol(fp);
- putchar('\n');
- }
- return TRUE;
- }
- //=============================================================================
- //ReadFirstSecData:
- //读取第二节数据
- //-----------------------------------------------------------------------------
- BOOL ReadSecondSecData(FILE *fp)
- {
- DWORD i;
- fread(&g_dwObjFiles,1,sizeof(g_dwObjFiles),fp);
- printf("OBJ files: %lu\n",g_dwObjFiles);
- g_pdwObjOffsets=(DWORD*)malloc(sizeof(DWORD)*g_dwObjFiles);
- if(!g_pdwObjOffsets)
- {
- printf("Insufficient memory.\n");
- return FALSE;
- }
- fread(g_pdwObjOffsets,sizeof(DWORD),g_dwObjFiles,fp);
- printf("OBJ file offsets:\n");
- for(i=0;i<g_dwObjFiles;i++)
- printf("\t0x%08X\n",g_pdwObjOffsets[i]);
- fread(&g_dwSymbols,1,sizeof(g_dwSymbols),fp);
- printf("Symbols: %lu\n",g_dwSymbols);
- g_pwSymbolIndices=(WORD*)malloc(sizeof(WORD)*g_dwSymbols);
- if(!g_pwSymbolIndices)
- {
- printf("Insufficient memory.\n");
- return FALSE;
- }
- fread(g_pwSymbolIndices,sizeof(WORD),g_dwSymbols,fp);
- for(i=0;i<g_dwSymbols;i++)
- {
- printf("Symbol "");
- ReadOneSymbol(fp);
- switch(g_pwSymbolIndices[i])
- {
- case 1:
- printf("" can be found in the 1st OBJ file.\n");
- break;
- case 2:
- printf("" can be found in the 2nd OBJ file.\n");
- break;
- case 3:
- printf("" can be found in the 3rd OBJ file.\n");
- break;
- default:
- printf("" can be found in the %uth OBJ file.\n",g_pwSymbolIndices[i]);
- break;
- }
- }
- return TRUE;
- }
- //=============================================================================
- //ExtractOBJFiles:
- //提取OBJ文件
- //-----------------------------------------------------------------------------
- BOOL ExtractOBJFiles(FILE *fp,char *szObjDir)
- {
- FILE *fpw;
- char szFile[MAX_PATH];
- size_t Size;
- DWORD i;
- for(i=0;i<g_dwObjFiles;i++)
- {
- sprintf(szFile,"%s_%u.obj",szObjDir,i+1);
- printf("Writing %s:\n",szFile);
- fpw=fopen(szFile,"wb");
- if(!fpw)
- {
- printf("Couldn't open %s.\n");
- return FALSE;
- }
- fseek(fp,g_pdwObjOffsets[i],SEEK_SET);
- ReadSecHead(fp);
- printf("OBJ section information:\n");
- PrintSecHead();
- Size=atol(g_szSize);
- if(Size)
- {
- if(!MoveFileSec(fp,Size,fpw))
- {
- printf("Couldn't write to OBJ.\n");
- fclose(fpw);
- return FALSE;
- }
- }
- else
- {
- printf("Incorrect LIB sector header.\n");
- fclose(fpw);
- return FALSE;
- }
- printf("Success.\n\n");
- fclose(fpw);
- }
- return TRUE;
- }
- //=============================================================================
- //main:
- //程序入口点
- //-----------------------------------------------------------------------------
- int main(int argc,char** argv)
- {
- FILE* fp;
- char szSignature[8 +1];
- char szDir[MAX_PATH],*pch;
- if(argc<2)
- {
- printf("Usage:\n\tANALIB LIBFILE.LIB\n");
- return -1;
- }
- fp=fopen(argv[1],"rb");
- if(!fp)
- {
- printf("Unable to open %s.\n",argv[1]);
- return -1;
- }
- fread(szSignature,1,8,fp); //读取文件标记
- szSignature[8]=0;
- if(strcmp(szSignature,"!<arch>\n")) //判断文件标记
- {
- printf("Not a LIB file.\n");
- fclose(fp);
- return -1;
- }
- #define V(arg) if(!(arg)){fclose(fp);return -1;}
- //读取第一个节
- printf("Now is reading the 1st section in the LIB file.\n");
- ReadSecHead(fp);
- PrintSecHead();
- V(ReadFirstSecData(fp));
- //读取第二个节
- printf("Now is reading the 2nd section in the LIB file.\n");
- ReadSecHead(fp);
- PrintSecHead();
- V(ReadSecondSecData(fp));
- //提取所有OBJ
- printf("Now is extracting OBJ files from the LIB file.\n");
- strcpy(szDir,argv[1]);
- pch=strrchr(szDir,'.');
- if(pch)*pch=0;
- V(ExtractOBJFiles(fp,szDir));
- fclose(fp);
- return FALSE;
- }
复制代码 SRC+BIN下载:
ANALIB.7z
(425.61 KB, 下载次数: 7, 售价: 10 个宅币)
|
|