PE文件解析_Dos头

PE文件解析_Dos头

 Dos部分主要为现代PE文件可以对早期的DOS文件进行良好兼容存在,其对应结构体为IMAGE_DOS_HEADER,所在头文件为winnt.h

typedef struct _IMAGE_DOS_HEADER {      // DOS .EXE header
    WORD   e_magic;                     // Magic number
    WORD   e_cblp;                      // Bytes on last page of file
    WORD   e_cp;                        // Pages in file
    WORD   e_crlc;                      // Relocations
    WORD   e_cparhdr;                   // Size of header in paragraphs
    WORD   e_minalloc;                  // Minimum extra paragraphs needed
    WORD   e_maxalloc;                  // Maximum extra paragraphs needed
    WORD   e_ss;                        // Initial (relative) SS value
    WORD   e_sp;                        // Initial SP value
    WORD   e_csum;                      // Checksum
    WORD   e_ip;                        // Initial IP value
    WORD   e_cs;                        // Initial (relative) CS value
    WORD   e_lfarlc;                    // File address of relocation table
    WORD   e_ovno;                      // Overlay number
    WORD   e_res[4];                    // Reserved words
    WORD   e_oemid;                     // OEM identifier (for e_oeminfo)
    WORD   e_oeminfo;                   // OEM information; e_oemid specific
    WORD   e_res2[10];                  // Reserved words
    LONG   e_lfanew;                    // File address of new exe header
  } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;

各字段信息

1. e_magic字段:MS-DOS可执行文件的标识位(也叫做魔数MZ),表示这是一个MS-DOS下的可执行文件。

2. e_cblp字段:在可执行页(页大小为512B)最后一页中的字节数。如果其值为0,则表示最后一页被全部占用(即有效值为0x200=512)。

3. e_cp字段:可执行文件中的页数(包括最后一页)。

4. e_crlc字段:DOS Sub中重定位项的数目,可能为0。

5. e_cparhdr字段:程序的数据起始于头部之后,此字段可以用来计算出相应的文件偏移(包括重定位项)。如果头部大小不是512B的倍数,一些操作系统或程序可能会执行失败。

6. e_minalloc字段:除了代码大小外最少需分配的内存段大小,如果无法分配相应内存,则程序将不能启动。

7. e_maxalloc字段:除了代码大小外最多分配的内存段大小。通常,操作系统会为程序保留所有剩余的常规内存,但是此字段会对此做出限制。

8. e_ss字段:用来初始化SS(堆栈段)以启动可执行文件。

9. e_sp字段:用来初始化SP(堆栈指针寄存器)的值。

10. e_csum字段:可执行文件的校验和(或直接置为0)。

11. e_ip字段:初始化与启动可执行文件相关的IP寄存器值(程序入口点)。

12. e_cs字段:初始化与启动可执行文件相关的CS段(与上一字段组成CS:IP)。

13. e_lfarlc字段:重定位表的偏移。

14. e_ovno字段:代码附加数(为0x0则代表仅有主程序)。

15. e_res[4]字段:保留4个WORD大小的空间留作他用。

16. e_oemid字段:OEM厂商的ID。

17. e_oeminfo字段:OEM厂商的信息。

18. e_res2[10]字段:保留10个WORD大小的空间留作他用。

19. e_lfanew字段:PE头偏移地址。

我们主要记住两个重要字段就可以:e_magic字段和 e_lfanew字段

以下是我解析某exe文件的截图例子及运行结果

#include <iostream>
#include "windows.h"
using namespace std;

//#include "winnt.h"
int main()
{
   HANDLE hFile= CreateFileW(L"E:\\QQ\\Bin\\QQScLauncher.exe", GENERIC_READ,
        FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,0);
   DWORD FileSize = GetFileSize(hFile, NULL);
   char* FileBuff = new char[FileSize];
   DWORD realRead = 0;
   if (ReadFile(hFile, FileBuff, FileSize, &realRead, 0))
   {
      PIMAGE_DOS_HEADER Dos_Head = (PIMAGE_DOS_HEADER)FileBuff;
      // PIMAGE_DOS_HEADER Dos_Head=new PIMAGE_DOS_HEADER(0);
       //memcpy(Dos_Head, FileBuff, sizeof(IMAGE_DOS_HEADER));
      cout << sizeof(IMAGE_DOS_HEADER)<<endl;
       if (Dos_Head->e_magic == 0x5A4D)
       {  
           cout << "QQScLauncher.exe是有效的pe文件" << endl;
       }
       else
       { 
           cout << "QQScLauncher.exe不是有效的pe文件" << endl;
       }
      
       cout << Dos_Head->e_lfanew;
   }   
    CloseHandle(hFile);
   //delete FileBuff;  
    return 0;
}

PE文件解析_Dos头

 

上一篇:Linux bg 命令


下一篇:捕获和抛出异常