首页 > 其他分享 >PE结构初识

PE结构初识

时间:2023-01-12 19:55:05浏览次数:55  
标签:文件 导出 地址 初识 PE DOS 加载 结构

PE结构初识

EP说:“快去学PE!”,遂有了这篇博客。

啥是PE?

如果说EP是EPsilon的话,PE就一定是nolisPE了罢......
好吧,PE全称Windows PE文件,他是Windows下可执行程序的一个统称。常见的有可执行程序(.exe),驱动(.sys),动态链接库(.dll)等。最初设计用来提高程序在不同操作系统上的移植性,但实际上这种文件格式仅用在 Windows 系列操作系统下。PE文件是指 32 位可执行文件,也称为PE32。64位的可执行文件称为 PE+ 或 PE32+,是PE(PE32)的一种扩展形式(请注意不是PE64)。
先来几张图助助兴:


基础知识

PE文件结构

一般分为以下四个部分:

  1. DOS头:是用来兼容 MS-DOS 操作系统的,目的是当这个文件在 MS-DOS 上运行时提示一段文字,大部分情况下是:This program cannot be run in DOS mode. 还有一个目的,就是指明 NT 头在文件中的位置。
  2. NT头:包含 windows PE 文件的主要信息,其中包括一个 'PE' 字样的签名,PE文件头(IMAGE_FILE_HEADER)和 PE可选头(IMAGE_OPTIONAL_HEADER32)。
  3. 节表:是PE文件后续节的描述,windows根据节表的描述加载每个节。
  4. :每个节实际上是一个容器,可以包含 代码、数据 等等,每个节可以有独立的内存权限,比如代码节默认有读/执行权限,节的名字和数量可以自己定义。

VA(虚拟地址)与RVA(相对虚拟地址)

当一个PE文件被加载到内存中以后,我们称之为"映象 "(image),一般来说,PE文件在硬盘上和在内存里是不完全一样的,被加载到内存以后其占用的虚拟地址空间要比在硬盘上占用的空间大一些,这是因为各个节在硬盘上是连续的,而在内存中是按页对齐的,所以加载到内存以后节之间会出现一些“空洞”。
因为存在这种对齐,所以在PE结构内部,表示某个位置的地址采用了两种方式:

  • 针对在硬盘上存储文件中的地址,称为原始存储地址或物理地址,表示距离文件头的偏移
  • 针对加载到内存以后映象中的地址,称为 相对虚拟地址(RVA),表示相对内存映象头的偏移

然而CPU 的某些指令是需要使用绝对地址的,比如取全局变量的地址,传递函数的地址,以及编译后的汇编指令中肯定需要用到绝对地址而不是相对映象头的偏移,因此PE文件会建议操作系统将其加载到某个内存地址(这个叫基地址。段地址其实就是一种基地址,但基地址并不等于就是段地址)。编译器便根据这个地址求出代码中一些 全局变量和函数的地址,并将这些地址用到对应的指令中。
因此可以得出VA = RVA + IMAGEBASE

DOS头

DOS头



DOS头目前有用的东西只有e_magic和e_lfanew(这个怎么读?e_了发new?)两个。

  • e_magic用来标志这是一个PE文件
  • e_lfanew用来标志NT头的偏移。

在010 Editor中可以看见e_lfanew的值是0x00000120(大部分情况为小端存储),而在00120h的地方恰好为NT头的起始位置。

DOS存根

DOS存根则是一段简单的DOS程序,主要用来输出类似“This program cannot be run in DOS mode.”的提示语句。即使没有DOS存根,程序也能正常执行。在程序运行了但没完全运行的时候(比如在64位的机器上运行16位的程序)输出字符串。

NT头


可以看出NT头分为三个部分,标识符、文件头、可选头。

标识符

固定死的PE..

文件头

可选头

别被名字骗了,它不可选,包含了一大坨东西。

数据目录表

同样包含一大坨,导入导出表较为重要。

导出表

导出表是用来描述模块(.dll)中的导出函数的结构,如果一个模块导出了函数,那么这个函数会被记录在导出表中,这样通过GetProcAddress()函数就能动态获取到函数的地址。
函数导出的方式有两种:

  • 一种是按名字导出,
  • 一种是按序号导出。

这两种导出方式在导出表中的描述方式也不相同。

导入表

导入表在PE文件加载时,会根据这个表里的内容加载依赖的模块(.dll),并填充所需函数的地址。

重定位表

为了解决像call这样的使用VA的代码,在模块基址发生变化时还能准确定位而产生的表。步骤如下:

  1. 编译的时候由编译器识别出哪些项使用了模块内的直接VA,比如push、一个全局变量、函数地址,这些指令的操作数在模块加载的时候就需要被重定位。
  2. 链接器生成PE文件的时候将编译器识别的重定位的项纪录在一张表里,这张表就是重定位表,保存在 DataDirectory中,序号是IMAGE_DIRECTORY_ENTRY_BASERELOC。
  3. PE文件加载时,PE加载器分析重定位表,将其中每一项按照现在的模块基址进行重定位。

其他人的博客

EPsiloniPlayForSG两位学长的博客是跟着同一个视频学的。其中有一些非常骚的操作,像是自行添加一个节和代码,然后让程序先执行自己添加的内容。在读其他人的博客的时候听说有些壳和病毒就会单独加一个节什么的。按理说搞完理论知识确实应该实践一波的,但是我懒,不想实践,摆烂了......

标签:文件,导出,地址,初识,PE,DOS,加载,结构
From: https://www.cnblogs.com/Clovershrub/p/17045273.html

相关文章

  • RMAN-06091: no channel allocated for maintenance (of an appropriate type)
    问题描述releasedchannel:c1releasedchannel:c2RMAN-00571:===========================================================RMAN-00569:===============ERRORMESSA......
  • 2022 openEuler领先实践奖出炉!
    随着欧拉操作系统的规模应用,涌现出一大批优秀实践,有力推动了基础软件产业的创新和行业数字化转型深入。国家工业信息安全发展研究中心、OpenAtomopenEuler社区联合发起,由院......
  • windows 安装superset
    安装过程新建虚拟环境:condacreate-nsupersetpython=3.7激活虚拟环境:condaactivatesuperset-安装superset:pipinstallapache-superset-i[https://pypi.douba......
  • 初识C语言
    1、对编程而言,可移植性意味着什么?在一种系统中编写的C程序稍作修改或不修改就可以在其他系统运行。2、编程的七个主要步骤是什么?定义程序的目标设计程序编写程序编......
  • 基于OpenHarmony设计的Qemu仿真实验环境搭建
    一.运行qemu仿真运行环境1.模拟运行设备选择Risc-V在源码目录下执行hbset选择ohemu下的qemu_riscv_mini_system_demo选项。hb选择编译对象2.编译运行在OpenHarmony源码目......
  • 09 OpenCV自带颜色表操作
    09OpenCV自带颜色表操作opencv知识点:opencv4的颜色表应用图像映射-applyColorMap()本科所解决的问题:如何使用OpenCV中的颜色表?如何循环转换各种颜色风格?1.Op......
  • 1.将树形结构数据打平成一维数组
    1.函数constflatTree=(treeData)=>{letresult=[];treeData.forEach((item)=>{//先克隆一份数据作为第一层级的填充letres=JSON.parse(JSON......
  • 低版本浏览器 报错 SyntaxError: Unexpected token...
    客户机器使用xp系统,谷歌最高支持49版本,项目启动浏览器报错SyntaxError:Unexpectedtoken...,主要原因是该浏览器版本无法识别“...”——es6语法。项目使用vuecli4创建,......
  • 报错:feign.FeignException$FeignClientException: [424 Failed Dependency] during [P
     报错的原因是没有添加@Inner注解在我们项目加载阶段,我们获取有Inner注解的类和方法,然后获取我们配置的uri,经过正则替换后面的可变参数为*,然后将此uri加入到ignore-url......
  • [Typescript] Generics in Type Arguments
    Herewehavea Component classthatcanbepassedin TProps.Insideoftheconstructoritassigns props to this,andprovidesa getProps methodthatca......