PE文件学习--Dos头部

简介: PE文件学习--Dos头部

PE(Portable Executeable FileFormat)可移植的执行文体格式,我们平日时常见的exeldll\sys等都是PE文件的一种。PE文件的组成可以被分为PE Head和PE Body,我们先从PE文件头的Dos头部说起。


DOS头部分为两部分:第一部分是DOSMZ头第二部分是DOS Stub(指令令字节码Q)。


以下为DOS MZ头部微软给出的定义,其中我学习中用到的最关键两个字字段就是e_magic和e_lfanew,分别用来确定是否是PE文件和寻址 NT Headers的首地址


typedef struct _IMAGE_DOS_HEADER // DOS .EXE header
{      
    WORD   e_magic;                     //魔术字 0x4d5a MZ
    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;                    //DOS头部距离NT头部的偏移
  } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;


Dos Stub大多数时候是由编译器自动生成,其长度是PE文件链接生成时确定的,其长度在不同的PE文件中不一定相同,其紧跟在DOS MZ头部的下面,整个时一个字节块,PE中没有与之相关的结构体。所以以我们不可以直接用Dos Heaher基地址+sizeof(IMAGE DOSHEADER)的方式定位到Nt头部。


接下来附上一点我的测试代码和定位到NT头的代码:

TCHAR* CPEHelper::GetFileMemPointer(TCHAR* FileFullPath,DWORD* m_FileSize)
{
  //打开文件获取句柄
  HANDLE FileHandle = CreateFile(
    FileFullPath,
    GENERIC_READ,  //只读
    FALSE,
    NULL,
    OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL,
    NULL);
  if (FileHandle == INVALID_HANDLE_VALUE)
  {
    MessageBox(0, _T("文件打开失败\r\n"), 0, 0);
    return NULL;
  }
  //获取文件大小
  DWORD FileSize = GetFileSize(FileHandle, NULL);
  *m_FileSize = FileSize; //文件大小返出值
  //申请内存 用来存放PE文件数据
  TCHAR* BuferData = new TCHAR[FileSize] {};
  //读文件
  DWORD ReturnLength;
  ReadFile(FileHandle, BuferData, FileSize, &ReturnLength, NULL);
  //关闭文件句柄
  if (FileHandle != NULL)
  {
    CloseHandle(FileHandle);
    FileHandle = NULL;
  }
  //返回PE文件起始位置(基址)
  return BuferData;
}
//.......判断PE文件的一部分代码
  PIMAGE_DOS_HEADER ImageDosHeader = (PIMAGE_DOS_HEADER)FileBuffer;//FileBuffer = 上面函数返回的BufferData
  if (ImageDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
  {
  //#define IMAGE_DOS_SIGNATURE     0x5A4D      // MZ
    return FALSE;
  }
  //定位到Nt头部
  PIMAGE_NT_HEADERS ImageNtHeaders =
    (PIMAGE_NT_HEADERS)(ImageDosHeader->e_lfanew + (ULONG)FileBuffer);
目录
相关文章
|
2月前
|
Linux 索引 关系型数据库
Linux 终端命令之文件目录操作,对比Dos相关命令
Linux 终端命令之文件目录操作,对比Dos相关命令
95 0
Linux 终端命令之文件目录操作,对比Dos相关命令
|
IDE 开发工具 C++
Python命令行解析:IDE内点击Run运行代码直接得出结果、基于TF flags(或argparse、sys.argv)在Dos内命令行(一条命令)调用代码文件得出结果
Python命令行解析:IDE内点击Run运行代码直接得出结果、基于TF flags(或argparse、sys.argv)在Dos内命令行(一条命令)调用代码文件得出结果
|
Java
Java 学习(01)--DOS/环境/常量
1:计算机概述(了解) (1)计算机 (2)计算机硬件 (3)计算机软件 系统软件:window,linux,mac 应用软件:qq,yy,飞秋 (4)软件开发(理解) 软件:是由数据和指令组成的。
1263 0
|
Java Windows
java在指定目录下执行dos命令或者bat文件
直接看源程序吧 public static void main(String[] args) throws IOException { File dir = new File("D:\\"); // String command="netstat -an"; String command = "c:\\windows\\system32\\cmd.
1094 0
|
2月前
|
存储 Shell Linux
【Shell 命令集合 磁盘维护 】Linux 创建DOS文件系统 mkdosfs命令使用指南
【Shell 命令集合 磁盘维护 】Linux 创建DOS文件系统 mkdosfs命令使用指南
48 2