首页 > 其他分享 >PE文件结构解析 Part3 NT Headers

PE文件结构解析 Part3 NT Headers

时间:2024-11-29 16:24:20浏览次数:5  
标签:HEADER WORD Header IMAGE Headers Part3 PE DWORD NT

文章来源:https://0xrick.github.io/win-internals/pe4/

目录

简介

在前面的文章中,我们看过了DOS Header的结构以及逆向了DOS stub。
这篇文章我们准备讨论一下PE文件结构中NT Header的部分。
在我们进入正题之前,我们需要讲一讲等下我们会用到很多次的一个重要的概念,相对虚拟地址(Relative Virtual Address)或者RVA。 RVA(相对虚拟地址)就是相对于EXE在内存中起始地址的一个偏移(相对于Image Base)。也就是说,将相对虚拟地址Relative Virtual Address转化为绝对虚拟地址,我们需要将RVA的值加上ImageBase的值。接下来我们会看到,PE很多地方都会用到RVA。

NT Headers(IMAGE_NT_HEADERS)

NT Headers是一个定义在winnt.h的结构体IMAGE_NT_HEADERS,观察它的定义,我们可以看到它有三个成员(DWORD类型的签名,IMAGE_FILE_HEADER类型的FileHeader,以及IMAGE_OPTIONAL_HEADER类型的OptionalHeader)。

值得一提的是,这个结构体有两个版本的定义。一个用于32bit,IMAGE_NT_HEADERS 。 一个用于64bit,IMAGE_NT_HEADERS64

typedef struct _IMAGE_NT_HEADERS64 {
    DWORD Signature;
    IMAGE_FILE_HEADER FileHeader;
    IMAGE_OPTIONAL_HEADER64 OptionalHeader;
} IMAGE_NT_HEADERS64, *PIMAGE_NT_HEADERS64;

typedef struct _IMAGE_NT_HEADERS {
    DWORD Signature;
    IMAGE_FILE_HEADER FileHeader;
    IMAGE_OPTIONAL_HEADER32 OptionalHeader;
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;

签名 Signature

NT Headers结构体的第一个成员是PE签名,它是DWORD类型,意味着它需要4字节的空间。
这个字段的值总是固定为0x50450000,用ASCII码表示为PE\0\0
下面是来自PE-Bear的截图。

File Header(IMAGE_FILE_HEADER)

也被称作"COFF File Header", File Header这个结构体持有PE文件的一些信息。
它在winnt.h中定义为IAMGE_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;

这是一个有着7个成员的结构体:

  • Machine:用于表示可执行文件的目标机器,类型是WORD。这个字段可以有很多值,但是我们只对其中两个感兴趣,0x8864 for AMD64 and 0x14c for i386. 想要了解全部可能的值,可以访问微软官方文档
  • NumberOfSections:这个字段存储了sections的个数。(也可以说是section header的个数)
  • TimeDateStamp: 表示文件被创建时的unix时间戳。
  • PointerToSymbolTableNumberOfSymbols: 这两个字段保存了 到COFF符号表的偏移以及符号表中有几个对象。它们也可能被设置为0,意味着没有符号表,这是因为COFF调试信息被丢弃了。
  • SizeOfOptionalHeader:Optional Header的大小。
  • Characteristics:用于表示文件属性的flag。这些属性可以是文件能否被执行,是否是系统文件,以及很多其他信息。详情可以访问微软官方文档

下面是一个真实的PE文件的PE Header的截图。

Optional Header (IMAGE_OPTIONAL_HEADER)

Optional Header是NT headers中最重要的,PE加载器会查找这个header中提供的特定的信息来加载以及执行EXE文件。
它被称为可选头部信息是因为有些文件类型 像是obj文件不需要,但是这个header对于镜像文件image file很重要。
Optional Header没有固定的大小,所以会存在 IMAGE_FILE_HEADER.SizeOfOptionalHeader

Optional Header前8个成员对于COFF文件格式来说是必须实现的标准,header剩余的部分是微软对标准定义的一个扩展,结构体中扩展部分的成员会被用于Windows的PE加载器以及链接器。

正如之前提到的,Optional Header 有两个版本,一个用于32bit的Exe,一个用于64bit。这两个版本有以下两方面的区别:

  • 结构体本身的大小(或者说结构体中定义的成员的数量): IMAGE_OPTIONAL_HEADER32有31个成员,而IMAGE_OPTIONAL_HEADER64只有30个成员, 32bit版本多出的成员为DWORD类型的BaseOfData,存储了data section起始位置的Relative Virtual Address.
  • 一些成员的数据类型:下面5个成员在32bit版本中是DWORD,在64bit版本中是ULONGLONG:
    • ImageBase
    • SizeOfStackReserve
    • SizeOfStackCommit
    • SizeOfHeapReserve
    • SizeOfHeapCommit

我们来看一下两个结构体的定义:

typedef struct _IMAGE_OPTIONAL_HEADER {
    //
    // Standard fields.
    //

    WORD    Magic;
    BYTE    MajorLinkerVersion;
    BYTE    MinorLinkerVersion;
    DWORD   SizeOfCode;
    DWORD   SizeOfInitializedData;
    DWORD   SizeOfUninitializedData;
    DWORD   AddressOfEntryPoint;
    DWORD   BaseOfCode;
    DWORD   BaseOfData;

    //
    // NT additional fields.
    //

    DWORD   ImageBase;
    DWORD   SectionAlignment;
    DWORD   FileAlignment;
    WORD    MajorOperatingSystemVersion;
    WORD    MinorOperatingSystemVersion;
    WORD    MajorImageVersion;
    WORD    MinorImageVersion;
    WORD    MajorSubsystemVersion;
    WORD    MinorSubsystemVersion;
    DWORD   Win32VersionValue;
    DWORD   SizeOfImage;
    DWORD   SizeOfHeaders;
    DWORD   CheckSum;
    WORD    Subsystem;
    WORD    DllCharacteristics;
    DWORD   SizeOfStackReserve;
    DWORD   SizeOfStackCommit;
    DWORD   SizeOfHeapReserve;
    DWORD   SizeOfHeapCommit;
    DWORD   LoaderFlags;
    DWORD   NumberOfRvaAndSizes;
    IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;

每个字段的详细解释可以看对应的文档

让我们看一下实际PE文件中Optional Header的内容。

我们可以讨论一下其中的一些字段,首先是Magic字段,它的值是0x20B意味着这是一个64位的可执行程序。

我们可以看到程序入口点entry point的相对虚拟地址RVA是0x12C4并且代码段Code Section开始于相对虚拟地址0x1000,内存中的段对齐SectionAlignment的大小也是0x1000.

文件中的段对齐File Alignment被设置为0x200,并且我们可以观察任何一个section来验证。

你可以看到,data section的实际内容是从0x22000x2229,然而section剩余部分被0填充直到0x23ff来满足FileAlignment对齐的要求。
SizeOfImage镜像被加载到内存中的大小被设置为 7000 并且 SizeOfHeaders被设置为400,两个各自都是SectionAlignmentFileAlignment的倍数。

Subsystem字段被设置为3,表示这是一个Windows控制台程序。

DataDirectory下面会讲。

总结

本篇文章到此结束,至此我们看了NT Headers结构,详细讨论了File Header和Optional Header。
下一篇文章我们会看一下Data Directories, Section Headers, 以及sections。

标签:HEADER,WORD,Header,IMAGE,Headers,Part3,PE,DWORD,NT
From: https://www.cnblogs.com/dewxin/p/18575346

相关文章

  • 在数据库字段命名格式和实体类属性命名格式不一致的情况下,通过配置 MyBatis 的通用 Ma
    MyBatis的通用Mapper支持使用@Column注解进行字段映射,但需要满足以下条件:项目中已集成MyBatis的通用Mapper(例如Mapper插件)。在通用Mapper的配置中启用了@Column注解支持。通用Mapper会根据实体类中字段的@Column注解值来映射数据库表的列名。使用@Colum......
  • 在数据库字段命名格式和实体类属性命名格式不一致的情况下,通过配置 MyBatis 的通用 Ma
    如果在MyBatis的通用Mapper中结合Example模式查询时,未自动使用实体类中@Column注解定义的字段映射,可能的原因是配置或使用方式上存在一些问题。以下是解决方案和注意事项:原因分析通用Mapper的@Column支持:通用Mapper支持通过@Column注解映射字段和数据库列,但......
  • redis初级之HyperLogLog
    HyperLogLog1.描述​ HyperLogLog是一种概率数据结构,也被简称为HLL,用于估计集合的基数(总数)。和集合的用法基本一致,在使用时可以当做是在操作一个集合,但是HLL与集合的不同点在于HLL作为一种概率数据结构,以完美的精度换区了高效的空间利用率。这意味着HLL与集合在存储相同数据量的......
  • TypeScript核心语法(3)——类型系统
    本章是TypeScript类型系统的总体介绍。TypeScript继承了JavaScript的类型,在这个基础上,定义了一套自己的类型系统。先讲一下最基础的类型,any类型。any类型​基本含义​any类型表示没有任何限制,该类型的变量可以赋予任意类型的值。letx:any;x=1;//正确x=......
  • 深度学习-50-AI应用实战之基于mediapipe的手势识别
    文章目录1手势识别1.1手势识别技术1.2手势识别应用场景1.3手势识别基本原理2应用mediapipe2.1加载模型2.2处理图片2.2.1手势识别2.2.2人脸检测2.2.3姿态估计2.2.4表情识别2.3处理摄像头3参考附录1手势识别手势识别技术是一......
  • The Endspeaker (Easy Version)
    算法题意没什么可以转化的,已经很明确了。容易发现当\(k\)确定且要进行移除前缀操作时,一定要尽可能的使前缀更大不然一定不优。考虑动态规划,令\(dp_i\)表示移除\(a\)数组的前\(i\)项所需的最小总成本。可以发现\(dp_i\)可以从\(dp_j,0\leqj<i\)推出来,令\(k\)......
  • [TSDB] OpenGemini wal文件与tssp文件的用途与关系
    前言openGemini是一款面向物联网、车联网、工业互联网、运维监控等领域的开源分布式时序数据库。在openGemini中,WAL(Write-AheadLogging)文件和TSSP(TimeSeriesStorageProtocol)文件扮演着重要的角色,以下是关于它们的用途及关系的详细解释:WAL文件用途WAL文件主要用于记录数......
  • P3106 [USACO14OPEN] Dueling GPSs S —— 最短路 图论
    [USACO14OPEN]DuelingGPSsS题面翻译FarmerJohn最近在网上购买了一台新车,然而当他给这台新车挑选额外设备时他不小心快速地点击了“提交”按钮两次,因此这台新车配备了两台GPS导航系统!更糟糕的是,两台系统对FarmerJohn的出行路线经常做出相互冲突的决定。FarmerJohn......
  • openstack实例无法访问外网案列
    1、说明以管理员身份创建完成外部网络、子网、上传镜像、实例类型、创建租户、用户以创建的用户身份登录,创建内部网络、子网创建完成2台实例现象为两台实例之间能通,实例至内部网关能通,实例到路由器外网接口(192.168.6.30)能通,实例访问外网不通2、环境说明主机名IP      ......
  • OpenVPN如何打通两个局域网
    OpenVPN如何打通两个局域网环境说明:云平台环境:厂商:AWS配置:CPU:1核 内存1G磁盘:30GOpenVPN_Server:​ 内网地址:172.50.21.155/32​ 外网地址:52.83.x.x/32本地:厂商:Exsi配置:CPU:1核 内存1G磁盘:30GOpenVPN_Client: ......