https://www.bpsend.net/thread-288-1-2.html

portable excute 可移植,可执行的文件(exe dll)

能够解析的文件,其内部都是有格式的,不是随随便便放的,都是按照某种规律放的,可执行文件也是如此,他有自己的格式,exe 和 dll 的格式是一样的

微软由dos 到 windows 文件格式发生了改变,所以要出新的文件格式,因此微软要求文件要兼容 dos 系统,其次要兼容其他的所有操作系统

IMAGE_FILE_MACHINE_AM33 希望兼容所有的cpu

因此PE的文件格式里面有很多字段时 windows 系统用不到的,有些是给已经被淘汰的 dos系统用的,还有一些是给其他系统用的,所以不是每个字段都非常有用,我们只需要关注在 windows 上的用的,即windows会检查的一些字段

PE头

IMAGE_DOS_HEADER IMAGE_NT_HEADERS IMAGE_FILE_HEADER IMAGE_OPTIONAL_HEADER IMAGE_DATA_DIRECTORY[1] //柔性数组 IMAGE_SECTION_HEADER[] //描述整个数据.解析这个表可以拿到所有数据

用于解析的PE文件

PE文件代码

.586
.model flat,stdcall
option casemap:none

  include windows.inc
  include user32.inc
  include kernel32.inc

  includelib user32.lib
  includelib kernel32.lib

.data
  g_szText db "pe for pe teach",0
  g_szCaption  db "tiptip",0

.code
start:
   invoke MessageBox, NULL, offset g_szText, offset g_szCaption, MB_OK
   invoke ExitProcess,eax

end start

我们自己编译

ml /c /coff pe.asm

link /subsystem:windows pe.obj

在winhex查看

此时可以发现0很多,这是因为文件生成的时候有对齐值我们可以通过修改对齐值来修改其大小

还可以更小,就是把数据节合并(因为数据段里面也存在对齐)

继续合并

此时已经达到了编译器的最小大小了

DOS头 IMAGE_DOS_HEADER: 00000000--0000003F

IMAGE_DOS_HEADER 结构体

// DOS头结构体: _IMAE_DOS_HEADER
typedef struct _IMAE_DOS_HEADER {       //DOS .EXE header                 偏移  
   WORD e_magic;     //幻数  Magic number;                               0x00  

   // 中间部分成员是为了兼容16位操作系统...可修改可忽略...

   LONG e_lfanew;     //File address of new exe header                   0x3C  
} IMAGE_DOS-HEADER, *PIMAGE_DOS_HEADER;  

该结构体中两个重要字段(不可更改),分别是 e_magic,和 e_lfanew字段:

  • 第一个字段 e_magic:该字段WORD类型,2字节 ,存储字符是“MZ”,对应PE文件的开头,是PE文件的标识符。该标识符在Winnt.h头文件中有一个宏定义,定义如下所示:

    #define IMAGE_DOS_SIGNATURE      0x4D5A  // MZ
    #define IMAGE_OS2_SIGNATURE      0x4E45  // NE
    #define IMAGE_OS2_SIGNATURE_LE   0x4C45  // LE

    最后一个字段 e_lfanew:该字段LONG类型,4字节,对应PE文件的0x3C处 :表示NT头在文件中的偏移,即32位及以上系统文件头在文件中真正的偏移,这个值可以修改,但是修改的话要把整个IMAGE_NT_HEADERS 结构体移到 该值对应的偏移值处

IMAGE_DOS_HEADER 到 IMAGE_NT_HEADERS 中间有一部分数据 叫做 stub code 也叫残留代码,残留数据,这个里面是跑在16位 dos系统里面的代码,起一个提示作用

NT头 IMAGE_NT_HEADERS

偏移值 : IMAGE_DOS_HEADER 中e_lfanew值 -- IMAGE_DOS_HEADER 中e_lfanew值 + 0x98

IMAGE_NT_HEADERS 结构体

// NT头结构体: _IMAGE_NT_HEADERS
typedef struct _IMAGE_NT_HEADERS {
 DWORD                   Signature;        // 签名 32位文件格式的头部标识,不可修改
 IMAGE_FILE_HEADER       FileHeader;       // 文件头
 IMAGE_OPTIONAL_HEADER32 OptionalHeader;   // 选项头
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;
DWORD Signature
  • 宏定义: #define IMAGE_NT_SIGNATURE 0x50450000 // PE00

文件头 IMAGE_FILE_HEADER:描述磁盘上PE文件的相关信息。
    • 重要字段不可修改:
  •    // 文件头结构体 20B: _IMAGE_FILE_HEADER
      typedef struct _IMAGE_FILE_HEADER {
        WORD  Machine;               // 表示CPU平台,不可修改:
                                     // 32位IMAGE_FILE_MACHINE_I386, 0x014c
                                     // 64位IMAGE_FILE_MACHINE_AMD64, 0x8664
        WORD  NumberOfSections;      // 表示节表数量,用于遍历节表,判断从PE中拷贝什么数据到内存中:
                                     //.text/.rdata/.data...每个2行半
                                     // 遍历节表经验:根据此处的个数拿对应的节表数据
        DWORD TimeDateStamp;         // 时间戳:链接器填写的文件生成的时间,作用不大(可修改)
        DWORD PointerToSymbolTable;   // 符号表位置(无用)
        DWORD NumberOfSymbols;       // 符号表个数:windows的符号表信息一般由PDB放置在文件后端(无用)
        WORD  SizeOfOptionalHeader;   // 选项头大小:用于定位节表位置=选项头地址+选项头大小(不可随便修改)
        WORD  Characteristics;       // 文件属性,指应用程序是一个什么程序(不可随便修改)
      } IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
    • 重要字段:7.DWORD AddressOfEntryPoint;10.DWORD ImageBase

    • IMAGE_OPTIONAL_HEADER 结构体

      typedef struct _IMAGE_OPTIONAL_HEADER {
       WORD  Magic;    // 32位PE: IMAGE_NT_OPTIONAL_HDR32_MAGIC  ,   0x10b.
                     // 以 _IMAGE_OPTIONAL_HEADER  结构体解析        
                     // 64位PE: IMAGE_NT_OPTIONAL_HDR64_MAGIC  ,   0x20b.
                     // 以 _IMAGE_OPTIONAL_HEADER64  结构体解析      
       BYTE  MajorLinkerVersion;   // 主链接器版本号 (无用)
       BYTE  MinorLinkerVersion; // 副链接器版本号  (无用)

       //系统分配内存不看着3个值,但是对于调试器有影响(影响反汇编所用内存大小,OD是机器码个数*2,字节数是通过SizeOfCode 得到)  
       DWORD SizeOfCode;               // 代码所占空间大小  (没啥用)
       DWORD SizeOfInitializedData;    // 已初始化数据所占空间大小 (没啥用)
       DWORD SizeOfUninitializedData;// 未初始化数据所占空间大小 (没啥用)

       DWORD AddressOfEntryPoint;  // *oep:原本的程序入口点(实际为偏移,+模块基址=实际入口点)
                                   // ep: 被加工后的入口点
                                     //这个值可以修改,但是修改过后必须跳转到在该偏移处跳转到真正入口
       DWORD BaseOfCode;   // 代码基址  (无用)
       DWORD BaseOfData;   // 数据基址   (无用)
       DWORD ImageBase;    // *建议装载地址:exe映射加载到内存中的首地址= PE 0处,即实例句柄hInstance
                       // 一般而言,exe文件可遵从装载地址建议,但dll文件无法满足
       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;
    • 选项头 IMAGE_OPTIONAL_HEADER:以供操作系统加载PE文件使用,32位必选。
    • 1.WORD Machine; 2.WORD NumberOfSections;
    • 6.WORD SizeOfOptionalHeader; 7.WORD Characteristics.

AddressOfEntryPoint EP

OEP 程序入口点 - Old Entry Point

如果 EP 没有被修改的话 OEP = EP ,但是很多时候为了隐藏程序入口点 通常会修改 EP 的值

例如 原本 AddressOfEntryPoint 的值为1000 可以改成 1100 ,那么模块基址 + 1100 的地方就成了程序入口点 再到 该地址 执行跳转指令 ,可以挑战转到 偏移 为 1000 处或者 跳转到其他地方在跳回 偏移 1000处

CC表示不重要的无用数据

作业

WindowsPE文件格式入门01.PE头的更多相关文章

  1. PE文件格式学习之PE头移位

    以前刚开始学网络安全,是从免杀开始的.记得那时候杀毒软件还很弱.金山江民瑞星还存在. 那会什么原理也不懂,就一直瞎鼓捣.(后来转入渗透行列了) 这段时间一直在学PE格式,突然想起来以前很古老的PE文件 ...

  2. 【网络爬虫入门01】应用Requests和BeautifulSoup联手打造的第一条网络爬虫

    [网络爬虫入门01]应用Requests和BeautifulSoup联手打造的第一条网络爬虫 广东职业技术学院 欧浩源 2017-10-14  1.引言 在数据量爆发式增长的大数据时代,网络与用户的沟 ...

  3. Windows Pe 第三章 PE头文件(下)

    3.5  数据结构字段详解 3.5.1  PE头IMAGE_NT_HEADER的字段 1.IMAGE_NT_HEADER.Signature +0000h,双字.PE文件标识,被定义为00004550 ...

  4. Windows Pe 第三章 PE头文件(中)

    这一章的上半部分大体介绍了下PE文件头,下半部分是详细介绍里面的内容,这一章一定要多读几遍,好好记记基础概念和知识,方便之后的学习. 简单回忆一下: 3.4  PE文件头部解析 3.4.1 DOS M ...

  5. Windows Pe 第三章 PE头文件(上)

    第三章  PE头文件 本章是全书重点,所以要好好理解,概念比较多,但是非常重要. PE头文件记录了PE文件中所有的数据的组织方式,它类似于一本书的目录,通过目录我们可以快速定位到某个具体的章节:通过P ...

  6. PE文件学习系列三-PE头详解

    合肥程序员群:49313181.    合肥实名程序员群:128131462 (不愿透露姓名和信息者勿加入) Q  Q:408365330     E-Mail:egojit@qq.com 最近比较忙 ...

  7. PE头的应用---插入代码到EXE或DLL文件中

    三.代码实现(DELPHI版本),采用第三种方式实现代码插入. 1. 定义两个类,一个用来实现在内存中建立输入表:一个用来实现对PE头的代码插入. DelphiCode: const MAX_SECT ...

  8. 不用搭环境的10分钟AngularJS指令简易入门01(含例子)

    不用搭环境的10分钟AngularJS指令简易入门01(含例子) `#不用搭环境系列AngularJS教程01,前端新手也可以轻松入坑~阅读本文大概需要10分钟~` AngularJS的指令是一大特色 ...

  9. 【爬虫入门01】我第一只由Reuests和BeautifulSoup4供养的Spider

    [爬虫入门01]我第一只由Reuests和BeautifulSoup4供养的Spider 广东职业技术学院  欧浩源 1.引言  网络爬虫可以完成传统搜索引擎不能做的事情,利用爬虫程序在网络上取得数据 ...

  10. JavaScript基础入门 - 01

    JavaScript入门 - 01 准备工作 在正式的学习JavaScript之前,我们先来学习一些小工具,帮助我们更好的学习和理解后面的内容. js代码位置 首先是如何编写JavaScript代码, ...

随机推荐

  1. 大数据之路Week10_day01 (通过直接创建Hfile文件的方式往Hbase中插入数据)

    package com.wyh.parctise; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.P ...

  2. SG定理

    先放一个 SG 函数的定义和 SG 定理 SG 函数: \(SG(p) = \text{mex}\ {SG(t)}\) SG 定理: \(\forall n\) 个独立的子图若 \(SG(1)\ \o ...

  3. 值得推荐的IT公司名单(成都篇)

    成都,作为新一线城市中的科技强市,拥有众多优秀的 IT 公司,为广大 IT 从业者提供了丰富的就业机会和良好的职业发展环境.以下是一些值得推荐的 IT 公司(排名不分先后): 一.互联网巨头在成都 1 ...

  4. H3C S520 V3 端口流量镜像

    背景: 最近公司需要采集某工业PLC设备报文,临时查询了一下如何使用H3C交换机配置流量镜像. PLC地址: 192.168.3.213 MAC: e0:dc:a0:5c:47:2f (可通过ARP ...

  5. 通用的SpringBoot集成的文件上传与下载

    废话不多说--直接看代码 controller package com.webank.wedatasphere.qualitis.controller.thymeleaf; import com.we ...

  6. 鸿蒙NEXT开发案例:程序员计算器

    [环境准备] • 操作系统:Windows 10 • 开发工具:DevEco Studio 5.0.1 Release Build Version: 5.0.5.306 • 目标设备:华为Mate60 ...

  7. Python+硅基流动API实现小说转有声读物

    一.注册硅基流动账号获取文本转语音api 1.注册登录硅基流动 注册.登录硅基流动 查看apikey 查看赠送的免费额度 点击文档中心 2.查看文本转语音api 查看文本转语音api 查看api使用指 ...

  8. while(bug)

    while(bug) { // 加了班也不一定写的完代码 // 写完了代码也不一定编译的过 // 编译过了也不一定没bug // 有了bug也不一定找的到 // 找到bug也不一定改的了 // 改了这 ...

  9. nginx 安装及负载配置

    1.官网下载nginx源码包 http://nginx.org/download/nginx-1.8.1.tar.gz 2.上传到opt目录,解压 cd /opt tar -zxvf nginx-1. ...

  10. 轻松的工作(deepseek)

    组长:"这里有一百多个地震波形文件,把每一个地震建立一个文件夹,并把地震波形放到对应日期的地震中." 我想:一个一个整好麻烦想摸会鱼 让我们来deepseek吧~ 首先,生成文件夹 ...