PE文件格式(加密与解密3)(一)

本次的了解主要讲解 PE的基本概念、MS-DOS文件头、PE文件头、区块、输入表、输出表等。

这里我将会结合一个简单的小程序来加深我对PE文件结构的了解。

 

使用学习工具:有StudyPE、LordPE、PEID。

 学习PE建议看书。。和自己动手。。。

 

PE文件:

  在WIN上,32位的可执行文件是PE文件,64位的是PE32+文件 ,DLL文件的格式和PE格式差不多,唯一的区别是PE和DLL的有一个字段标识这个文件是EXE还是DLL。

  

如上就是一个PE文件的结构图,PE文件使用的是一个平面地址空间,所有的数据都融合在一起,文件的内容又被分割为不同的区块(Section),

各个区块按页的边界来对齐。每个块都有自己的属性(是否可读,是否可写,是否可执行等等)。

 

基地址:

      当PE文件被装载器装载了之后,内存中的板块被称为模块。映射文件的起始地址被称为模块句柄---内存中的模块代表这进程从这个可执行文件中所需要的代码、数据、资源、输入表、输出表及其他东西所使用的东西放在一个连续的内存块中。在装载中,PE文件的一个字段会告诉系统把文件映射到内存需要多少内存,不能被映射的数据被放置在文件的尾部。

      在WIN32中,可以使用HMODULE GetModuleHandle(LPCTSTR lpModuleName)来获得一个模块的名称。当传递一个可执行文件或者DLL作为参数,

如果系统成功找到这个文件,就会返回该可执行文件或者DLL文件映像加载到的基地址。

      在PE文件中,有一个字符设置了基地址,VC++建立的exe文件的基地址是0x00400000h,DLL文件的基地址是0x10000000h。

 

相对虚拟地址:

    为了让程序的载入更加的灵活-也为了在PE文件中出现有确定的内存地址,出现了相对虚拟地址(Relative Vritual Address, RVA),当你的程序加载后,假设你的text块的RVA = 0x00001000h,映射到程序中时,VA(虚拟地址) = ImagineBase(基地址)+RVA(相对虚拟地址),你的代码区块在内存中就开始与0x00401000h。

 

文件偏移地址:

    因为我们的文件是存储在磁盘上的,某个数据相对于文件头的偏移量就是这个数据的偏移地址,称为文件偏移地址(File Offset)或者物理地址(RAW Offset),偏移地址的起始值是0。

 

MS-DOS头部(IMAGE_DOS_HEADER):

   每个PE文件是以一个DOS程序开始的,还有MZ header之后的DOS stub(DOS块)。如果这个可执行文件不能被这个系统支持,会打印一串提示符

"This program cannot be run is MS-DOS mode",DOS头部中主要是WORD e_magic和 LONG e_lfanew这个字段比较重要。这些数据结构可以在winnt.h中找到。

#define IMAGE_DOS_SIGNATURE 0x5A4D
#define IMAGE_OS2_SIGNATURE 0x454E
#define IMAGE_OS2_SIGNATURE_LE 0x454C
#define IMAGE_VXD_SIGNATURE 0x454C
#define IMAGE_NT_SIGNATURE 0x00004550#include "pshpack2.h"
//这里就是IMAGE_DOS_HEADER的结构了。typedef struct _IMAGE_DOS_HEADER {WORD e_magic; // DOS可执行文件标记“MZ”WORD e_cblp;WORD e_cp;WORD e_crlc;WORD e_cparhdr;WORD e_minalloc;WORD e_maxalloc;WORD e_ss;WORD e_sp;WORD e_csum;WORD e_ip;       //DOS代码入口IPWORD e_cs;      //DOS代码的入口CSWORD e_lfarlc;WORD e_ovno;WORD e_res[4];WORD e_oemid;WORD e_oeminfo;WORD e_res2[10];LONG e_lfanew;   // 指向PE文件头, “PE”,0,0} IMAGE_DOS_HEADER,*PIMAGE_DOS_HEADER;

 LONG e_lfanew是指向PE文件头的一个地址,它的文件偏移地址是0x3C--也就是60字节开始,然后占据了4个字节,指向PE文件头,具体看下图

我们可以看到0x000000F8在偏移60字节的地方,看到PE文件头在0x000000F8,具体可以自己找一个文件来测试(加深印象)

 DOS文件头就到这里了,接下来继续介绍PE头,也就是IMAGE_NT_HEADER,下面的代码是对于定义32还是64的PE头,我们可以看到相应的宏语句

和对应的数据结构定义。

#ifdef _WIN64             //如果采用64的架构typedef IMAGE_OPTIONAL_HEADER64 IMAGE_OPTIONAL_HEADER;typedef PIMAGE_OPTIONAL_HEADER64 PIMAGE_OPTIONAL_HEADER;
#define IMAGE_SIZEOF_NT_OPTIONAL_HEADER IMAGE_SIZEOF_NT_OPTIONAL64_HEADER
#define IMAGE_NT_OPTIONAL_HDR_MAGIC IMAGE_NT_OPTIONAL_HDR64_MAGIC
#else  /* _WIN64 */      //如果不是采用64而是32位的架构typedef IMAGE_OPTIONAL_HEADER32 IMAGE_OPTIONAL_HEADER;typedef PIMAGE_OPTIONAL_HEADER32 PIMAGE_OPTIONAL_HEADER;
#define IMAGE_SIZEOF_NT_OPTIONAL_HEADER IMAGE_SIZEOF_NT_OPTIONAL32_HEADER
#define IMAGE_NT_OPTIONAL_HDR_MAGIC IMAGE_NT_OPTIONAL_HDR32_MAGIC
#endif /* _WIN64 */ //上面的typedef都是改变结构体的名称typedef struct _IMAGE_NT_HEADERS64 {//这里是64位的PE头的结构体的定义DWORD Signature;IMAGE_FILE_HEADER FileHeader;IMAGE_OPTIONAL_HEADER64 OptionalHeader;} IMAGE_NT_HEADERS64,*PIMAGE_NT_HEADERS64;typedef struct _IMAGE_NT_HEADERS {//这里是32位的PE头的结构体的定义DWORD Signature;IMAGE_FILE_HEADER FileHeader;IMAGE_OPTIONAL_HEADER32 OptionalHeader;} IMAGE_NT_HEADERS32,*PIMAGE_NT_HEADERS32;

在PE的文件头中,第一个DWORD Signature, 被定义为了0x00004550h,也就是"PE\0\0"这四个字符。这个标志没有什么作用。(DOS中指向的地方)。

主要是IMAGE_FILE_HEADER和IMAGE_OPTIONAL_HEADER这两个结构体中的几个字段重要。

我么接下来观看PE文件头中的IMAGE FILE_HEADER FileHeader这个结构体

typedef struct _IMAGE_FILE_HEADER {WORD Machine;                     //这里定义的是运行平台,i386= 0x014Ch这个值,还有其他平台,看书吧。。WORD NumberOfSections;       //这个是标识区块的数目,紧跟在PE头的后面,也就是IMAGE_NT_HEADERS的后面DWORD TimeDateStamp;DWORD PointerToSymbolTable;DWORD NumberOfSymbols;WORD SizeOfOptionalHeader;     //这里表明了IMAGE_NT_HEADERS中的大小(RAW SIZE),32位一般是0x00E0, 64位PE+一般是0x00F0WORD Characteristics;       //普通的EXE是0x010fh, DLL文件是0x210Eh} IMAGE_FILE_HEADER,*PIMAGE_FILE_HEADER;

接下来我们看一下IMAGE_OPTIONAL_HEADER这个结构体,一样下面的是这个结构体在winnt.h中的定义,下面这个是32位的,还有64位的,但是差不多的,可以看winnt.htypedef struct _IMAGE_OPTIONAL_HEADER

typedef struct _IMAGE_OPTIONAL_HEADER {WORD Magic;BYTE MajorLinkerVersion;BYTE MinorLinkerVersion;DWORD SizeOfCode;           //这里定义了包含代码区块的大小DWORD SizeOfInitializedData;    //这里定义了已经初始化的变量的区块的大小DWORD SizeOfUninitializedData;   //这里是未初始化的变量的区块的大小DWORD AddressOfEntryPoint;     //这里是程序入口的RVA(相对虚拟地址)DWORD BaseOfCode;          //这里是程序代码块的起始RVADWORD BaseOfData;          //这里是数据块起始RVADWORD ImageBase;           //这里是程序默认装入的基地址(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;   //这里定义了数据目录表的项数,一直保持为16IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; //这个是数据目录表,指向输入、输出表、资源块等数据,很重要} IMAGE_OPTIONAL_HEADER32,*PIMAGE_OPTIONAL_HEADER32;

 这个IMAGE_OPTIONAL_HEADER只需要关注一些关键字段就行了,记住。。

接下来我么就看一看这个数据目录表,数据目录表简单点说就是一个长度为16的IMAGE_DATA_DIRECTORY结构体数组而已

typedef struct _IMAGE_DATA_DIRECTORY {DWORD VirtualAddress;            //数据块的其实RVA,很重要DWORD Size;             //数据块的长度} IMAGE_DATA_DIRECTORY,*PIMAGE_DATA_DIRECTORY;

这是一个16位的数组,最有一个数组元素作为保留,全部为0,其他的从开头一直到倒数第二个数据都是已经规定好了的,我们看一下这个数据目录表成员

#define IMAGE_DIRECTORY_ENTRY_EXPORT 0              //Export Table
#define IMAGE_DIRECTORY_ENTRY_IMPORT 1        //Import Table              输入表这里比较重要
#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2
#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3
#define IMAGE_DIRECTORY_ENTRY_SECURITY 4
#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5
#define IMAGE_DIRECTORY_ENTRY_DEBUG 6
#define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE 7
#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8
#define IMAGE_DIRECTORY_ENTRY_TLS 9
#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10
#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11
#define IMAGE_DIRECTORY_ENTRY_IAT 12          //IAT (import address table), 这里也很重要
#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13
#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14

还有也可以使用LordPE的PE editor来查看这个目录,现在的查看目录表的工具很多。。。。。

PE的第一阶段到这里,接下来会继续学习,增加熟悉度。。。。。。。。。。-----------好好学习,天天向上!

 

转载于:https://www.cnblogs.com/binlmmhc/p/6151113.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/397138.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql用户_MySQL用户权限管理详解

用户权限管理主要有以下作用:1. 可以限制用户访问哪些库、哪些表2. 可以限制用户对哪些表执行SELECT、CREATE、DELETE、DELETE、ALTER等操作3. 可以限制用户登录的IP或域名4. 可以限制用户自己的权限是否可以授权给别的用户一、用户授权mysql> grant all privile…

手把手教Electron+vue的使用

.现如今前端框架数不胜数,尤其是angular、vue吸引一大批前端开发者,在这个高新技术快速崛起的时代,自然少不了各种框架的结合使用。接下来是介绍electronvue的结合使用。 2.Electron是什么?? 对于我来说Electron相当于…

shell循环和分支

循环和分支对代码块的操作是构造组织shell脚本的关键. 循环和分支结构为脚本编程提供了操作代码块的工具.10.1. Loops循环就是重复一些命令的代码块,如果条件不满足就退出循环.for loopsfor arg in [list]这是一个基本的循环结构.它与C的for结构有很大不同.forarg in [list]do …

mysql主从_MySQL主从原理及配置详解

MySQL主从配置及原理,供大家参考,具体内容如下一、环境选择:1.Centos 6.52.MySQL 5.7二、什么是MySQL主从复制MySQL主从复制是其最重要的功能之一。主从复制是指一台服务器充当主数据库服务器,另一台或多台服务器充当从数据库服务…

引导修复 不是活动的_河南省视频数据修复中心

河南省视频数据修复中心 lk6afds河南省视频数据修复中心 文件预览我找到了我要恢复文件,可是,这个文件能能正确恢复呢。没有用的文件不可以删掉吗。我们先来看看盘文件夹都是什么吧。(以下仅限于~系统)一般来说,刚刚安装的电脑系统盘主要包含…

企业日志分析 五大问题需重点注意

资讯 | 安全 | 论坛 | 下载 | 读书 | 程序开发 | 数据库 | 系统 | 网络 | 电子书 | 微信学院 | 站长学院 | 源码 | QQ | 专栏 | 考试 | 系统安全| 网站安全| 企业安全| 网络安全| 工具软件| 杀毒防毒| 加密解密|首页 > 安全 > 企业安全 > 正文企业安全…

python学习笔记(一):python入门

上周六终于开始接触心心念念的python了,本人学习语言算是零基础,java语法比较复杂,所以选择了一个语法相对还是比较简单,而且现在使用也是越来越广泛的python进行了学习。下面就言归正传吧 在学习python之前先来了解下现今比较流行…

怎么验证proftpd安装成功_英雄联盟手游泰服安卓账号怎么注册

英雄联盟手游中泰服安卓账号怎么注册?泰服安卓账号的注册流程是怎样的?泰服安卓账号的注册与其他服安卓账号的注册是否一致?接下来就给介绍下手游中泰服安卓账号的注册,希望对各位玩家能有所帮助。英雄联盟游戏新泰服安卓账号怎样…

oracle实现mysql的if_oracle中decode函数 VS mysql中的if函数和case函数

oracle中有decode函数,如下:select sum(decode(sex,男,0,1)) 男生数 from school;统计男生数目,含义为:decode()中sex字段为男时,用1代替,然后计算总和而mysql中没有该函…

visio对象放入word显示不全_办公人士必学visio技能 手把手教你使用visio绘制项目全景图!...

Hi,大家好!我是爱踢汪。今天本汪想问问你用什么总结项目,Word、PPT还是视频?下面我们聊聊画图。画图固然是为了好看,视觉上的冲击加深印象。更重要的是,图像模型带来的“潜台词”,有意想不到的效果&#xf…

mongoDB操作详细

简介 它和我们使用的关系型数据库最大的区别就是约束性,可以说文件型数据库几乎不存在约束性,理论上没有主外键约束,没有存储的数据类型约束等等 关系型数据库中有一个 "表" 的概念,有 "字段" 的概念,有 "数据条目" 的概念 MongoDB中也同样有以上…

mysql 存储过程 on_MySQL存储过程的权限问题小结

MySQL的存储过程,没错,看起来好生僻的使用场景。问题源于一个开发同学提交了权限申请的工单,需要开通一些权限。本来是一个很正常的操作,但在我来看是比较着急且紧迫的,说来惭愧,忙着方向规划和开发的事情&…

mysql索引引擎_mysql搜索引擎和索引那些事

mysql的存储引擎三种存储方式**InnoDB **(默认)一个文件存储表结构,一个存储数据和目录(索引)# 一个文件 book_name | author| press | price | pub_date frm文件 frame的缩写# 另一个文件(数据 目录)# | 倚天屠龙记 | egon | 北京工业地雷出版社 | 70.00 | 2019-07…

深度ip转换器手机版app_房串串经纪人版app下载-房串串经纪人版app手机版 v1.0.0...

房串串经纪人版app:专门为房产经纪人打造的辅助办公软件,提供的功能非常的全面,涵盖了房产服务过程中的各个环节,随时可以手机在线处理自己的日常工作,提高了工作的效率,操作很简单,让你更好的实…

netduino之电源参考电路MC33269DT-5.0G

手里有块netduino的板子,一直闲置未用,netduino具体是什么不知道的就百度吧,我这也不是主要讲netduino开发的,简单说就是用.net开发硬件,了解到netduino也是原来学过C#,当然我主要的工作还是嵌入式硬件开发…

PowerShell使用教程

一、说明 1.1 背景说明 个人对PowerShell也不是很熟悉,开始的时候就突然看到开始菜单中多了个叫PowerShell的文件夹,后来一点就看到某个教程视频说PowerShell很厉害但也没怎么听,再后来就看到kali也有了一些PowerShell的脚本这才意识到PowerS…

python Gunicorn

1. 简介 Gunicorn(Green Unicorn)是给Unix用的WSGI HTTP 服务器,它与不同的web框架是非常兼容的、易安装、轻、速度快。 2. 示例代码1 def app(environ, start_response):data b"Hello World\n"start_response("200 OK", [("Content-Type…

如何使处于不同局域网的计算机实现远程通信_小区自来水二次加压泵站远程监控系统方案...

一、小区自来水二次加压泵站远程监控系统方案项目概述随着城市高效快速地发展,市区规模越来越大,小区二次加压泵房将继续增加,供水公司二次加压泵房管理工作将更加繁重。目前小区二次加压供水方式主要有两种,一种是不锈钢水箱不锈…

postgresql返回行数_怎么优化你的SQL查询?以PostgreSQL为例

实际工作中,我们每个人难免都会要写SQL,执行SQL,但是有时时候执行非常慢,甚至获得不了结果。这时候你会怎么办?放弃?去苦口婆心的求隔壁房间胡子擦擦的猥琐DBA大叔?NO,正确方法是先检…

echarts 词云_python Flask+爬虫制作股票查询、历史数据、股评词云网页

自学python的数据分析,爬虫后,花了几天时间看视频学习Flask做了一个简单的股票查询网页。本来还想着加入一些其他功能,比如财务指标分析,舆情分析,最完美的想法是做成一个股票评分系统,输入股票代码可以自动…