| 
UID1精华积分77054威望 点宅币 个贡献 次宅之契约 份最后登录1970-1-1在线时间 小时 
 | 
 
| LIB文件就是多个OBJ文件的集合。为什么会有LIB呢?因为有了LIB,链接器就可以筛选掉不需要的OBJ文件,把需要的OBJ提取出来并连接起来。 VC6、MinGW编译通过。
 SRC+BIN下载:复制代码/*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字节#endiftypedef 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];    //用户IDchar    g_szGroupID[6   +1];    //组IDchar    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;}
 ANALIB.7z
(425.61 KB, 下载次数: 7, 售价: 10 个宅币) | 
 |