coff文件简单分析

来源:互联网 发布:耳机性能测试软件 编辑:程序博客网 时间:2024/05/01 15:10

    最近事情比较多,驱动开发要放点时间在详细研究。说下coff格式的详细内容吧,window下就是编译过程中产生的obj文件,linux下为out文件。首先看下

http://baike.baidu.com/view/1240794.htm的内容吧,其中内容基本正确,这里只做一些补充

  

首先提供各我写的例子,本来就是自己看,所以变量值就用断点看吧。

 

用来生成例子obj的工程

#include <stdio.h>
#include <string.h>

#define PASSWORD_SIZE 100
#define PASSWORD      "myGOODpassword/n"
// The CR above is needed
// so as not to cut off
// the user-entered CR.
#pragma data_seg (".kpnc")
// Note that the period before the name
// isn't mandatory, just customary.
char passwd[ ]=PASSWORD;
#pragma data_seg ()


int main ()
{
// The counter for authentication failures
int count=0;
// The buffer for the user-entered password
char buff [PASSWORD_SIZE];

// The main authentication loop
for (;;)
{
// Prompting the user for a password
// and reading it
printf ("Enter password:");
fgets (&buff [0], PASSWORD_SIZE,stdin);

// Matching the entered password against the reference value
if (strcmp (&buff [0], passwd))
// "Scolding" if the passwords don't match;
printf ("Wrong password/n");
// otherwise (if the passwords are identical),
// getting out of the authentication loop
else break;

// Incrementing the counter of authentication failures
// and terminating the program if 3 attempts have been used
if (++count>3) return -1;
}

// Once we're here, the user has entered the right password.
printf ("Password OK/n");
}

分析coff文件的工程

.h文件

                                                                                                     iCur+=(strlen(str+iCur)+1); // 计算偏移时不要忘了计算‘/0’字符所占的1个字节!
                                                                                                    }
                                                                                                      free(str); // 释放字符串表空间
                                                                                                     直到这里,整个COFF的结构已经全部介绍完了。很多了解PE格式的朋友一定会奇怪,好像少了很多内容!?是的,标准的COFF文件只有这么多的东西。但MS为了和DOS的可执行文件兼容,以及对可执行文件功能的扩展,在COFF格式中加了很多它自己的标准。让我差点就认不出COFF了。但了解了COFF文件以后,再来学习PE文件的格式,那就很简单了。
                                                                                                       想了解PE文件的格式?网上有很多它的资料,我将在本文的基础上再写几篇文章,分别介绍PE,OMF以及ELF的格式。
                                                                                                      现在大家可以自己动手,写一个COFF文件解析器或是一个简单的连接程序了!
*/
#pragma pack(push)
#pragma pack(1)
typedef struct{
 unsigned short usMagic;
 unsigned short usNumSec;
 unsigned long ulTime;
 unsigned long ulSymolOffset;
 unsigned long ulNumSymbol;
 unsigned short usOptHdrSZ;
 unsigned short usFlags;
}COFF_FILE_HEADER;

typedef struct {
    unsigned short usMagic;
 unsigned short usVersion;
 unsigned long ulTextSize;
 unsigned long ulInitDataSZ;
 unsigned long ulUnintiDataSZ;
 unsigned long uEntry;
 unsigned long ulTextBase;
 unsigned long ulDataBase;
}OPTHDR;


typedef struct {
 char cName[8];
 unsigned long ulVSize;
 unsigned long ulVAddr;
 unsigned long ulSize;
 unsigned long ulSecOffset;
 unsigned long ulRelOffset;
 unsigned long ulLNOffset;
 unsigned short ulNumRel;
 unsigned short ulNumLN;
 unsigned long ulFlags;
}SECHDR;

typedef struct {
 unsigned long ulAddr;/* virtual address of reference */
 unsigned long uSymbol;
 unsigned short usType;
} RELOC;

typedef struct {
 unsigned long ulAddrORSymbol;
 unsigned short usLineNq;

} LINENO;

typedef struct {
 union {
  char cName[8];
  struct {
   unsigned long ulZero;
   unsigned long ulOffset;
  }e;
 }e;
 unsigned long ulValue;
 short iSection;
 unsigned short usType;
 unsigned char usClass;
 unsigned char usNumAux;
}SYMENT;
#pragma pack(pop)
.cpp


#include "stdafx.h"
#include "coffHeader.h"
#include "stdlib.h"
#include <iostream>
#include <vector>

using namespace std;
#define MaxMemoryBlock 200
void* pMemBlock[MaxMemoryBlock];

void ClearMallocBlock()
{
 int iFreeCnt = 0;
 while(iFreeCnt++<MaxMemoryBlock && pMemBlock[iFreeCnt]!=NULL)
 {
  free(pMemBlock[iFreeCnt]);
 }
}

int _tmain(int argc, _TCHAR* argv[])
{
 
 int nMemCount = 0;
 FILE *pCoffFile = fopen("F://0501//Debug//erw.obj","rb+");

 int nSectionTotal0ffset = 0;
/*
 char rt[500];
 fread(rt,1,500,pCoffFile);
 int ct = 0;
 while(ct++ < 500)
 {
  if(rt[ct]=='.')
   int er = 0;
 }
*/
 vector<SECHDR*> vSecHdr;
 vector<void*>   vSecData;
 vector<RELOC*>  vReloc;
 vector<LINENO*> vLineNo;

 unsigned long ulCheckNum = 0;
 
 
 COFF_FILE_HEADER *pCoffHeader = (COFF_FILE_HEADER*)malloc(sizeof(COFF_FILE_HEADER));
 if(pCoffHeader==NULL)
 {
  return -1;
 }
 fread(pCoffHeader,1,sizeof(COFF_FILE_HEADER),pCoffFile);
    nSectionTotal0ffset += sizeof(COFF_FILE_HEADER);

    printf("the magic number is %d/n",pCoffHeader->usMagic);
 printf("the usNumSec is %d/n",pCoffHeader->usNumSec);
 
 if(pCoffHeader->usOptHdrSZ != 0)
 {
  printf("There is a Opt Header!/n");
  OPTHDR *pOptHdr = (OPTHDR*)malloc(sizeof(OPTHDR));
  if(pOptHdr==NULL)
   return -1;
  
  fread(pOptHdr,1,sizeof(OPTHDR),pCoffFile);
  nSectionTotal0ffset+=sizeof(OPTHDR);
 }
 
 int nSectionNum = pCoffHeader->usNumSec;
 int nTempSectionNum = nSectionNum;

 while(nTempSectionNum-->0)
 {
  SECHDR *pSectionHeader = (SECHDR*)malloc(sizeof(SECHDR)); 
  if(pSectionHeader==NULL)
  {
   return -1;
  }
  fseek(pCoffFile,nSectionTotal0ffset,SEEK_SET);
  fread(pSectionHeader,1,sizeof(SECHDR),pCoffFile);
  printf("Section Name is %s/n",pSectionHeader->cName);
  nSectionTotal0ffset+=sizeof(SECHDR);
        vSecHdr.push_back(pSectionHeader);
  
  unsigned long lSectionDataSize = pSectionHeader->ulSize; 

  fseek(pCoffFile,pSectionHeader->ulSecOffset,SEEK_SET);

  void* pSectionData = (void*)malloc(lSectionDataSize);
  if(pSectionData==NULL)
  {
   return -1;
  }
  fread(pSectionData,1,lSectionDataSize,pCoffFile);
  vSecData.push_back(pSectionData);


  // RELOC Content
  if(pSectionHeader->ulSecOffset > 0)
  {
   fseek(pCoffFile,pSectionHeader->ulRelOffset,SEEK_SET);
   
   int nRelocStruct = pSectionHeader->ulNumRel;
   while(nRelocStruct-->0)
   {
    RELOC* pReloc = (RELOC*)malloc(sizeof(RELOC));
    if(pReloc==NULL)
     return -1;
    fread(pReloc,1,sizeof(RELOC),pCoffFile);
                ulCheckNum = pReloc->uSymbol;
    vReloc.push_back(pReloc);
   }
  }

  // LINENUM Content
  if(pSectionHeader->ulLNOffset > 0)
  {
   fseek(pCoffFile,pSectionHeader->ulLNOffset,SEEK_SET);

   int nLineNumStruct = pSectionHeader->ulNumLN;
   while(nLineNumStruct-->0)
   {
    LINENO* pLineNum = (LINENO*)malloc(sizeof(LINENO));
    if(pLineNum==NULL)
     return -1;
    fread(pLineNum,1,sizeof(LINENO),pCoffFile);
    vLineNo.push_back(pLineNum);
   }
  }
 }

 //Symbol table
 FILE *pSymbolFind = pCoffFile;
 fseek(pSymbolFind,pCoffHeader->ulSymolOffset,SEEK_SET);
 unsigned long nSymbolNum = pCoffHeader->ulNumSymbol;
    vector<SYMENT*> vSymentTotal;
 while(nSymbolNum--)
 {
  SYMENT *pSyment = (SYMENT*)malloc(sizeof(SYMENT));
  fread(pSyment,1,sizeof(SYMENT),pSymbolFind);

  vSymentTotal.push_back(pSyment);

 }

 int iStrlen,iCur=4; // iStrLen是字符串表的长度,iCur是当前字符串偏移
 char *str; // 字符串表
 fread(&iStrlen,1, 4,pSymbolFind); // 得到字符串表长度
  str = (char *)malloc(iStrlen); // 为字符串表分配空间
     // 读字符串表,直到全部读入内存
 fread(str,1,iStrlen,pSymbolFind);

 iCur=4; // 把当前字符串偏移指到每一个字符串
 while (iCur<iStrlen ) { // 显示每一个字符串
  printf("String offset 0x%04X : %s/n", iCur, str + iCur);
  iCur+=(strlen(str+iCur)+1); // 计算偏移时不要忘了计算‘/0’字符所占的1个字节!
 }
 free(str); // 释放字符串表空间

 fclose(pCoffFile);
 
 return 0;
}

 

设断点就可以看到各项内容,另外在看一下http://osr507doc.sco.com/en/topics/COFF_SymValFld.html的内容,这个比较详细。

 

 

说我补充的几个内容吧,

1.File Header

  Optional Header

  Section Header 1

  ......

  Section Header n

  Section Data 1

  Relocation Directives 1

  Line Numbers 1

 

    Section Data 2

  Relocation Directives 2

      Line Numbers 2

 

  Symbol Table

  String Table

 

每一部分的section data后面是接reloc Directive 和line number的信息的例如

例如:.text 的

ulSize = 162

ulSecOffset = 1328

ulRelOffset = 1490

ulLNOffset = 1600

ulNumRel  = 11

ulNumLN = 11

下一段 dataoffset为 1666

按照这个结果显示

1328 + 162 = 1490

1490 + 11 *10 = 1600

1600 + 11*6 = 1666

可以看出各部分是完全没有空隙的连接的

2.reloc 表的 ulSymbol 这个所谓符号表索引为就是只第一个,比如coff头说有48个符号,那么ulSymbol

的值小于48,就是指第一个,

在我这里lineNum的ulAddrorsymbol的对应项是address ,至于这个需要对照IDA的结果看了,所以vc编译器的断点可以放在大括号上吧。

 

3.IDA把.debug$S .debug$T这个没有地址分配的section没有列出来,不过我看了一下,基本都是说明文件路径,lib名等一些辅助信息的,并没有什么实际意义

 

 

 

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 小米手机打电话来是关机的怎么办 红米手机打电话自动灭屏怎么办 红米5s手机白屏怎么办 红米手机黑屏开不了机怎么办 红米note开机键不灵了怎么办 红米2忘记锁屏密码怎么办 红米1手机忘记锁屏密码怎么办 红米4x关不了机怎么办 红米4a手机屏幕黑屏打不开怎么办 红米手机为什么开不了机怎么办 红米note手机刷机失败怎么办 金立手机来电屏幕不亮怎么办 小米5s桌面相机图标不见了怎么办 小米手机锁屏密码忘了怎么办? 小米平板电脑锁屏密码忘了怎么办 小米手机进水了黑屏了嗡嗡响怎么办 华为诺娃2手机声音小怎么办 华为平板锁屏密码忘记了怎么办 华为麦芒6手机按键摔坏了怎么办 定频空调加错了佛里昂怎么办 定频空调外机噪音大怎么办 老美的定频空调出现p0怎么办 华为揽阅m2青春版卡顿了怎么办 华为揽阅M2青春版发热卡顿怎么办 全民突击网速不给力经常掉线怎么办 华为手机微信视频黑屏了怎么办 相机拍照后找不到拍的照片怎么办 苹果手机下载软件不被信任怎么办 苹果x手机下载软件不受信任怎么办 华为畅享7plus主板坏了怎么办 华为手机手机主板坏了没备份怎么办 华为手机一年内主板坏了怎么办 华为手机保修期内主板坏了怎么办 华为手机外置sd卡满了怎么办 红米4充不进去电怎么办 苹果5s锁屏密码忘记了怎么办 华为手机桌面和锁屏自动一样怎么办 苹果手机没电了没带充电器怎么办 华为p8手机后摄像头模糊的怎么办 中兴手机充电的地方坏了怎么办? 小米手机与电脑蓝牙传输失败怎么办