QQ登录

只需一步,快速开始

PE文件结构之标准PE头介绍及编程读取

[ 复制链接 ]
上一帖子介绍PE文件大体由PE文件头与节表组成,
PE文件头由DOS头+pe标识+标准PE头+可选PE头+节表+节内容组成。
这帖子在前面帖子代码基础上编写标准PE头方读取,并介绍标准PE文件头结构成员含义。
例程界面如下:

PE文件结构之标准PE头介绍及编程读取

PE文件结构之标准PE头介绍及编程读取

通过界面按钮打开一个可执行文件后,可以点击标准PE头按钮,显示从PE文件的标准PE头读取的信息。
标准PE头对应为一个结构体类型变量IMAGE_FILE_HEADER。
在上一帖子介绍pe标识+标准PE头+可选PE头为PE头部分,对应结构体为IMAGE_NT_HEADERS。
标准PE头在PE文件中,开始地址由DOS_MZ成员e_lfanew指定。
那么PE头的定位代码,在例程中就可以这样写:
PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)((ULONG)pDosHeader+pDosHeader->e_lfanew);
标准PE头成员变量就可以这样访问:
pNtHeaders->FileHeader.Machine;
pDosHeader为DOS头指针,在上一帖子中有介绍是在文件打开时获取。
下面代码为标准PE头成员显示函数:
  1. void CFileHeaderDlg::UpdateData(PIMAGE_DOS_HEADER pDosHeader,bool bSetGet)
  2. {
  3.         if(pDosHeader == NULL)
  4.                 return;
  5.         PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)((ULONG)pDosHeader+pDosHeader->e_lfanew);
  6.         CString sText;
  7.         if(bSetGet)
  8.         {
  9.                 sText.Format("%04X",pNtHeaders->Signature);
  10.                 SetDlgItemText(IDC_EDIT11,sText);
  11.                 sText.Format("%04X",pNtHeaders->FileHeader.Machine);
  12.                 SetDlgItemText(IDC_EDIT1,sText);
  13.                 sText.Format("%04X",pNtHeaders->FileHeader.NumberOfSections);
  14.                 SetDlgItemText(IDC_EDIT2,sText);
  15.                 sText.Format("%08X",pNtHeaders->FileHeader.TimeDateStamp);
  16.                 SetDlgItemText(IDC_EDIT3,sText);
  17.                 sText.Format("%08X",pNtHeaders->FileHeader.PointerToSymbolTable);
  18.                 SetDlgItemText(IDC_EDIT4,sText);
  19.                 sText.Format("%08X",pNtHeaders->FileHeader.NumberOfSymbols);
  20.                 SetDlgItemText(IDC_EDIT5,sText);
  21.                 sText.Format("%04X",pNtHeaders->FileHeader.SizeOfOptionalHeader);
  22.                 SetDlgItemText(IDC_EDIT6,sText);
  23.                 sText.Format("%04X",pNtHeaders->FileHeader.Characteristics);
  24.                 SetDlgItemText(IDC_EDIT7,sText);
  25.         }
  26.         else
  27.         {

  28.         }
  29. }
复制代码
主要还是结构体IMAGE_FILE_HEADER成员的含义理解:
typedef struct _IMAGE_FILE_HEADER {
    WORD    Machine;
    WORD    NumberOfSections;
    DWORD   TimeDateStamp;
    DWORD   PointerToSymbolTable;
    DWORD   NumberOfSymbols;
    WORD    SizeOfOptionalHeader;
    WORD    Characteristics;
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;


1.Machine:
单字长度, 用来指定PE文件运行平台。有哪些平台可支持,或有哪些值可供使用?
例程对应代码如下:
  1. m_Combox.AddString("IMAGE_FILE_MACHINE_UNKNOWN           |0X00");
  2.         m_Combox.AddString("IMAGE_FILE_MACHINE_I386              |0x014c");
  3.         m_Combox.AddString("IMAGE_FILE_MACHINE_R3000             |0x0162");
  4.         m_Combox.AddString("IMAGE_FILE_MACHINE_R4000             |0x0166");
  5.         m_Combox.AddString("IMAGE_FILE_MACHINE_R10000            |0x0168");
  6.         m_Combox.AddString("IMAGE_FILE_MACHINE_WCEMIPSV2         |0x0169");
  7.         m_Combox.AddString("IMAGE_FILE_MACHINE_ALPHA             |0x0184");
  8.         m_Combox.AddString("IMAGE_FILE_MACHINE_SH3               |0x01a2");
  9.         m_Combox.AddString("IMAGE_FILE_MACHINE_SH3DSP            |0x01a3");
  10.         m_Combox.AddString("IMAGE_FILE_MACHINE_SH3E              |0x01a4");
  11.         m_Combox.AddString("IMAGE_FILE_MACHINE_SH4               |0x01a6");
  12.         m_Combox.AddString("IMAGE_FILE_MACHINE_SH5               |0x01a8");
  13.         m_Combox.AddString("IMAGE_FILE_MACHINE_ARM               |0x01c0");
  14.         m_Combox.AddString("IMAGE_FILE_MACHINE_THUMB             |0x01c2");
  15.         m_Combox.AddString("IMAGE_FILE_MACHINE_AM33              |0x01d3");
  16.         m_Combox.AddString("IMAGE_FILE_MACHINE_POWERPC           |0x01F0");
  17.         m_Combox.AddString("IMAGE_FILE_MACHINE_POWERPCFP         |0x01f1");
  18.         m_Combox.AddString("IMAGE_FILE_MACHINE_IA64              |0x0200");
  19.         m_Combox.AddString("IMAGE_FILE_MACHINE_MIPS16            |0x0266");
  20.         m_Combox.AddString("IMAGE_FILE_MACHINE_ALPHA64           |0x0284");
  21.         m_Combox.AddString("IMAGE_FILE_MACHINE_MIPSFPU           |0x0366");
  22.         m_Combox.AddString("IMAGE_FILE_MACHINE_MIPSFPU16         |0x0466");
  23.         m_Combox.AddString("IMAGE_FILE_MACHINE_TRICORE           |0x0520");
  24.         m_Combox.AddString("IMAGE_FILE_MACHINE_CEF               |0x0CEF");
  25.         m_Combox.AddString("IMAGE_FILE_MACHINE_EBC               |0x0EBC");
  26.         m_Combox.AddString("IMAGE_FILE_MACHINE_AMD64             |0x8664");
  27.         m_Combox.AddString("IMAGE_FILE_MACHINE_M32R              |0x9041");
  28.         m_Combox.AddString("IMAGE_FILE_MACHINE_CEE               |0xC0EE");
复制代码
例如选择"IMAGE_FILE_MACHINE_I386 |0x014c",
例程会提取数值0X014C赋值给IMAGE_FILE_HEADER的成员变量Machine。
那么这些如IMAGE_FILE_MACHINE_I386的含义是什么,表示什么处理器呢?
下面截图于一PDF文件,这里就不码字了:

PE文件结构之标准PE头介绍及编程读取

PE文件结构之标准PE头介绍及编程读取


2.NumberOfSections:
PE文件中存在的节的个数,单字长度。
在XP系统中,可以没有节,但数值不可小于1,或大于96。
仅能等于内存中存在的节个数,不然系统装载PE文件时会提示错误。
如果我们想在PE文件增,删节,得记得对应修改一下此数值。

3.TimeDateStamp:
双字长度,编译器在创建此文件时填写的时间戳,表示从1970年,1月1日,0时,0分,0秒开始,到文件创建时的总的秒数。
此数值无意义,可任意修改。要注意的是此值与文件属性:创建时间,修改时间,访问时间无关。
如果想知道时间戳与年月日,时分秒间如何相互转换,可以下载与参考例程源代码。
如上面第一图片,点击界面两个按钮,可以进行相互间转换。

4.PointerToSymbolTable,NumberOfSymbols:
PointerToSymbolTable双字长度,COFF符号表文件偏移,如无COFF符号表,此值为0。
对于映像文件,此值为0,微软已不建议使用。
NumberOfSymbols双字长度,符号表中元数数目。
这两成员已无用,主要用于调试,可不用关注。
COFF:Common Object File Format标准通用文件对象,记录了PE文件的全局属性。

5.SizeOfOptionalHeader:
单字,指定可选PE头(对应结构体IMAGE_OPTIONAL_HEADER32)的长度。
默认值为0X00E0,如果是64位PE文件,默认值则为0x00f0.
可以修改此值,但要自行保证文件中IMAGE_OPTIONAL_HEADER32大小与此值相同。
以及满足PE文件对齐特征。

6.Characteristics:
单字长度,表示文件属性标识字段。以二进制位的形式来使用,共16个属性。
这是一个很重要的字段,系统会根据此值来决定对文件的装载方式。
对于一般可执行文件,此值一般是0x10f,
对于DLL文件,一般是0x210e.
那么这16个进进制位,每个位的含义是什么呢?
可以参考下面图片。

PE文件结构之标准PE头介绍及编程读取

PE文件结构之标准PE头介绍及编程读取

例程中有实现对每个位的读取与设置,
可以下载例程来参考使用。

PE文件结构之标准PE头介绍及编程读取

PE文件结构之标准PE头介绍及编程读取

以上就是标准PE头结果成员 的含义与读取的关键代码。
自己编写代码来读取一个可执行文件的每个部分是最好的学习PE文件。
例程下载地址:
请点击此处下载

请先注册会员后在进行下载

已注册会员,请先登录后下载

文件名称:PEEdit.rar 
文件大小:140.34 KB  售价:3金币
下载权限: 不限 以上或 VIP会员   [购买捐助会员]   [充值积分]   有问题联系我



下一帖子会介绍可选PE头的读取与成员变量的含义。

回复

使用道具 举报

快速回复 返回列表 客服中心 搜索