逆向之Windows PE结构
写在前面
对于Windows
PE文件结构,个人认为还是非常有必要掌握和了解的,不管是在做逆向分析、免杀、病毒分析,脱壳加壳都是有着非常重要的技能。但是PE文件的学习又是一个非常枯燥过程,希望本文可以帮你有一个了解。
PE文件结构的基本介绍
先来大概说说什么是PE文件格式,PE(Portable
Executable),也就是我们说的可执行文件,在Windows中exe,dll,sys,ocx文件都是PE文件格式。而PE文件结构就是所有的PE文件按照结构的方式组织是有规律的排列组成。
从整个PE件结构大概来分成2部分,PE头和PE体。PE头又存在MS-
DOS头和NT头(PE头),PE体主要就是一些表结构构成,存放代码,数据,资源等。后面我们开始对这些信息进行逐一分析和讲解。
MS-DOS头
首先来看DOS头,DOS头位于整个PE文件的首位部分,是PE文件结构的第一个头,对于现在的系统来说,作用就是用来定位真正的PE头。在peview中可以看到对应IMAGE_DOS_HEADER和MS-
DOS Stub Program,IMAGE_DEBUG_TYPE这里可以忽略,是调试类型,对应debug和relese。

在二进制中查看,以4D 5A开头,十六进制转ASCII码就是MZ,是MS-DOS设计者名字缩写

在010
editor或者peview中,可以看到header占位在00000000-0000003C,而整个大小是64字节,额外需要注意的字节顺序,以小尾方式存在。

来看具体的IMAGE_DOS_HEADER是在winnt.h中定义,对于我们来说,我们只关心两个参数,e_magic是程序的头指纹和e_lfanew是指向真正PE头偏移地址。

这里我们可以尝试修改上面程序,将除了e_magic和e_lfanew对应的地址全部修改成0,可以看到程序还是可以正常运行。所以有用的数据只占6个字节(e_magic为WORD型占2个字节,e_lfanew为DWORD型占4个字节)


MS-DOS stub Program是DOS头的代码块,告诉用户程序不能在DOS下运行。

NT头(PE头)
PE头以50 45 00 00 开头,也就是PE…

来看下PE头结构IMAGE_NT_HEADERS,包括3个部分,Signature,IMAGE_FILE_HEADER,IMAGE_OPTIONAL_HEADER32(或64),而PE…就是Signature字段,这个字段是PE文件标准特征,是不能进行修改的,强行修改后程序无法正常运行。

IMAGE_FILE_HEADER共20字节,其中重要有4个部分,从010editor中可以看到Machine,NumberOfSections,TimeDateStamp,Characteristics这4个部分是最重要的。


Machine
共4个字节头两个字节表示机器类型,用于标识CPU的类型,后两个字节表示CPU为Intel
386或后继处理器及其兼容处理器。具体机器类型的值可以在010中自行查看。

NumberOfSections
表示节的数目,这里的节的数目指的就是区段表的数量,这里我们显示5,说明有个区段表数。

也可以利用lordpe查看区段表。

TimeDateStamp
为时间戳,也就是PE文件创建的时间。
Characteristics
文件属性的标志,共15个常用属性标志,每个bit都有不同含义,如下在010中可以看到:
我们从上往下进行看:
IMAGE_FILE_RELOCS_STRIPPED:为1表示文件中没有重定向信息
IMAGE_FILE_EXECUTABLE_IMAGE:为1表示该文件是可执行文件
IMAGE_FILE_LINE_NUMS_STRIPPED:为1表示文件中不存在行信息
IMAGE_FILE_LOCAL_SYMS_STRIPPED:为1表示没有局部符号信息
IMAGE_FILE_AGGRESIVE_WS_TRIM:表示调整工作集
IMAGE_FILE_LARGE_ADDRESS_AWARE:为1表示程序能处理大于2G的地址
IMAGE_FILE_BYTES_REVERSED_LO:小尾方式
IMAGE_FILE_32BIT_MACHINE:为1只在32位平台上运行
IMAGE_FILE_DEBUG_STRIPPED:为1不包含调试信息
IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP:为1不能从可移动盘运行
IMAGE_FILE_NET_RUN_FROM_SWAP:为1不能从网络运行
IMAGE_FILE_SYSTEM:为1表示文件为系统文件而不是程序
IMAGE_FILE_DLL:为1表示是一个dll文件
IMAGE_FILE_UP_SYSTEM_ONLY:为1表示文件只能运行于单处理器机器上
IMAGE_FILE_BYTES_REVERSED_HI:大尾方式

再来看看PE头下的可选头IMAGE_OPTIONAL_HEADER,它是PE头部重要的部分,之所以被称为可选头是指该结构体的部分数据在不同文件中是不同的。

同样,对照010中对不同的PE文件可进行分析查看修改。

节表
PE文件所有的节属性都定义节表中,节表是由IMAGE_SECTION_HEADER结构排列而组成的,且节表的位置在MS-DOS+PE头下面。

IMAGE_SECTION_HEADER结构

对于上面的字段来说,我们来说一说重要的的字段。在说字段前,再把三个地址概念复习下,后面会具体说地址转换计算。
1.VA:VirtualAddress虚拟内存地址,范围00000000h - 0fffffffh,就是进程的基地址 + RVA相对虚拟内存地址。 2.RVA:相对虚拟内存地址。 是PE文件中的数据、模块等运行在内存中的实际地址相对PE文件装载到内存的基址之间的距离。如果PE文件装入虚拟地址(VA)空间的400000h处,且进程从虚址401000h开始执行,我们可以说进程执行起始地址在RVA 1000h。 3.FOA:文件偏移地址,文件头的偏移地址。
NAME
8个字节ASCII的名称,必须要8个字节,不够可以用null值来填充,这里的名称可以自己起也可以编译器来定义。

VirtualSize
对应表的区块的大小,这是区块的数据在没有进行对齐处理前的实际大小,通俗的来说就是节的数据真实大小。
VirtualAddress
该区块装载到内存中的RVA 地址。
SizeOfRawData
文件偏移量(文件大小)
PointerToRawData
指出节在磁盘文件中所处的位置。这个数值是从文件头开始算起的偏移量。
Characteristics
节的属性,可读写等。
地址转换
前面说到三个地址,学习地址转化可以对程序的一些功能修改或添加,地址转化非常重要,后面的加密,对壳的操作,对感染性病毒修复都非常关键。
还是以前面的程序节表来看。

我们来计算hello world!字符串偏移地址。

首先可以看到字符串起始位置是983006,结束在983011。

计算过程:
1.通过VA转RVA
用起始位置-程序入口地址,程序入口地址980000,也就是
983006-980000 = 3006 RVA地址
这里说明一点,计算是十六进制计算,后面都一样。
2.找RVA所在的节
可以看到3006是在.data0983000到0098400之间,所以所属的节是.data

3.计算.data节起始的RVA和起始的FOA的差值
3000-A00=2600
4.通过RVA减去差值
3006-2600 = A06
用010打开exe程序,可以看到字段起始和我们计算出来的一致

在lordpe中直接算偏移量,可以看到和我们算出的一致。

添加节,给程序做入口弹框
对于加壳保护,病毒来说,一般情况下都会添加节,会将可执行程序保护的代码或者将病毒代码写在新添加的节中。
步骤:1.增加节表项;2.修正文件的映像程度;3.修正一个节的数量;4.增加文件的节数据。
以PEview程序为例,添加一个弹框。
用lordpe打开程序,首先看到区段表数量是5

选择一个表名称,右键-添加区段

将所有的地址记下来
00015000 00000000 00010A00 00000000 E00000E0
对于不清楚含义的可以再回头看看

先将映射入内存后的长度(虚拟大小)改为1000,将磁盘文件中的长度(物理大小)改为200

在区段标志(节属性)中,将可写和初始化去掉,节属性变成60000020。

字节大小转换:
前面我们插入200长度大小,为16进制,转换成10进制为512个字节
将程序使用010打开,在文件末尾添加512个字节,可以看到最末一个是109FF,109FF+1刚好是10A00

所以添加数据从最后一位插入512个字节数据

修正大小,前面将虚拟内存的大小修改为1000,镜像大小还是15000,发现程序是无法运行的

将镜像大小修正为16000

再次打开可以运行

接下来添加我们需要的程序。
反编译进行调试,发现程序入口的位置是00401000,再往下走程序就运行了。

前面我们说过程序的入口是imagebase(基地址)+entrypoint(入口点)组成,我们回头再验证一下,加起来为00401000一致。

所以需要程序从我们给添加的节开始执行,我们添加的节是00015000,所以需要让入口点修改为我们的节地址。新的入口点00415000。

选定00415020,右键转储跟随选定的地址。

编辑内容,同样在00415030出编辑内容。

在程序入口处00415000写入弹框

然后再入口处F8单步调试,发现成功弹框。

然后还没有成功,这里只是弹框,没有打开我们PEview主程序,还需要进行跳转,跳转的位置就是最开始的00401000这个位置,jmp
00401000,然后步入,可以发现主程序打开。

接着保存数据,修改的数据全部选中,右键复制到可执行文件

右键保存文件

就完成了通过添加节,添加一个弹框案例。
后记
WindosPE文件结构还有几个节表本次没有涉及到,后面可以自行了解。对于逆向来说,PE文件结构是基础中的基础,不仅要对汇编熟悉,还要懂得调试程序,后面我会讲讲脱壳加壳的内容。大家一起努力吧!
后记
WindosPE文件结构还有几个节表本次没有涉及到,后面可以自行了解。对于逆向来说,PE文件结构是基础中的基础,不仅要对汇编熟悉,还要懂得调试程序,后面我会讲讲脱壳加壳的内容。大家一起努力吧!
##最后
对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。

同时每个成长路线对应的板块都有配套的视频提供:


当然除了有配套的视频,同时也为大家整理了各种文档和书籍资料&工具,并且已经帮大家分好类了。

因篇幅有限,仅展示部分资料,有需要的小伙伴,可以【扫下方二维码】免费领取:

相关文章:
逆向之Windows PE结构
写在前面 对于Windows PE文件结构,个人认为还是非常有必要掌握和了解的,不管是在做逆向分析、免杀、病毒分析,脱壳加壳都是有着非常重要的技能。但是PE文件的学习又是一个非常枯燥过程,希望本文可以帮你有一个了解。 PE文件结构…...
ACL是什么
目录 一、ACL是什么 二、ACL的使用:setacl与getacl 1)针对特定使用者的方式: 1. 创建acl_test1后设置其权限 2. 读取acl_test1的权限 2)针对特定群组的方式: 3)针对有效权限 mask 的设置方式…...
操作系统核心知识点整理--内存篇
操作系统核心知识点整理--内存篇按段对内存进行管理内存分区内存分页为什么需要多级页表TLB解决了多级页表什么样的缺陷?TLB缓存命中率高的原理是什么?段页结合: 为什么需要虚拟内存?虚拟地址到物理地址的转换过程段页式管理下程序如何载入内存?页面置…...
从零开始学习iftop流量监控(找出服务器耗费流量最多的ip和端口)
一、iftop是什么iftop是类似于top的实时流量监控工具。作用:监控网卡的实时流量(可以指定网段)、反向解析IP、显示端口信息等官网:http://www.ex-parrot.com/~pdw/iftop/二、界面说明>代表发送数据,< 代表接收数…...
第一篇博客------自我介绍篇
目录🔆自我介绍🔆学习目标🔆如何学习单片机Part 1 基础理论知识学习Part 2 单片机实践Part 3 单片机硬件设计🔆希望进入的公司🔆结束语🔆自我介绍 Hello!!!我是一名即已经步入大二的计算机小白。 --------…...
No suitable device found for this connection (device lo not available(网络突然出问题)
当执行 ifup ens33 出现错误:[rootlocalhost ~]# ifup ens33Error: Connection activation failed: No suitable device found for this connection (device lo not available because device is strictly unmanaged).1解决办法:[rootlocalhost ~]# chkc…...
【算法设计技巧】分治算法
分治算法 用于设计算法的另一种常用技巧为分治算法(divide and conquer)。分治算法由两部分组成: 分(divide):递归解决较小的问题(当然,基准情况除外)治(conquer):然后,从子问题的解构建原问题的解。 传统上&#x…...
已解决kettle新建作业,点击保存抛出异常Invalid state, the Connection object is closed.
已解决kettle新建作业,点击保存进资源数据库抛出异常Invalid state, the Connection object is closed.的解决方法,亲测有效!!! 文章目录报错问题报错翻译报错原因解决方法联系博主免费帮忙解决报错报错问题 一个小伙伴…...
【设计模式】 工厂模式介绍及C代码实现
【设计模式】 工厂模式介绍及C代码实现 背景 在软件系统中,经常面临着创建对象的工作;由于需求的变化,需要创建的对象的具体类型经常变化。 如何应对这种变化?如何绕过常规的对象创建方法(new),提供一种“封装机制”来…...
深入浅出PaddlePaddle函数——paddle.arange
分类目录:《深入浅出PaddlePaddle函数》总目录 相关文章: 深入浅出TensorFlow2函数——tf.range 深入浅出Pytorch函数——torch.arange 深入浅出PaddlePaddle函数——paddle.arange 语法 paddle.arange(start0, endNone, step1, dtypeNone, nameNone…...
X86 ATT常用寄存器及其操作指令
X86 AT&T常用寄存器及其操作指令 常用寄存器 esp寄存器:当我们需要访问堆栈帧中的变量时,可以使用esp寄存器来获取堆栈帧的基址,以便能够正确地访问堆栈帧中的变量。ebp寄存器:当我们需要调用一个函数时,可以使用…...
Kotlin 高端玩法之DSL
如何在 kotlin 优雅的封装匿名内部类(DSL、高阶函数)匿名内部类在 Java 中是经常用到的一个特性,例如在 Android 开发中的各种 Listener,使用时也很简单,比如://lambda button.setOnClickListener(v -> …...
理光M2701复印机载体初始化方法
理光M2701基本参数: 产品类型:数码复合机 颜色类型:黑白 复印速度:单面:27cpm 双面:16cpm 涵盖功能:复印、打印、扫描 网络功能:支持无线、有线网络打印 接口类型:USB2.0…...
2.25Maven的安装与配置
一.Mavenmaven是一个Java世界中,非常知名的"工程管理工具"/构建工具"核心功能:1.管理依赖在进行一个A 操作之前,要先进行一个B操作.依赖有的时候是很复杂的,而且是嵌套的2.构建/编译(也是在调用jdk)3. 打包把java代码给构建成jar或者warjar就是一个特殊的压缩包…...
《英雄编程体验课》第 12 课 | 递归
文章目录 零、写在前面一、搜索算法的原理二、深度优先搜索三、基于DFS的记忆化搜索四、基于DFS的剪枝五、基于DFS的A*(迭代加深,IDA*)零、写在前面 该章节节选自 《夜深人静写算法》,主要讲解最基础的搜索算法,其中用到的思想就是递归,当然,如果已经对本套体验课了如指…...
35测试不如狗?是你自己技术不够的怨怼罢了
一、做软件测试怎么样? 引用著名软件测试专家、清华大学郑人杰教授的说法:软件测试工程师是一个越老越吃香的职业。 其中就表达了软件测试工作相对稳定、对年龄没有限制、而且随着项目经验的不断增长和对行业背景的深入了解,会越老越吃香。…...
【代码训练营】day42 | 1049. 最后一块石头的重量 II 494. 目标和 474.一和零
所用代码 java 最后一块石头的重量II LeetCode 1049 题目链接:最后一块石头的重量II LeetCode 1049 - 中等 思路 无。 把石头分成重量总和近似两堆,然后两堆石头相撞,剩下的就是最小的石头。每个石头只能用一次,01背包…...
Golang协程常见面试题
协程面试题交替打印奇数和偶数N个协程打印1到maxVal交替打印字符和数字交替打印字符串三个协程打印ABCChannel练习交替打印奇数和偶数 下面让我们一起来看看golang当中常见的算法面试题 使用两个goroutine交替打印1-100之间的奇数和偶数, 输出时按照从小到大输出. 方法一&…...
种群多样性:智能优化算法求解基准测试函数F1-F23种群动态变化图(视频)
智能优化算法求解基准测试函数F1种群动态变化图智能优化算法求解基准测试函数F2种群动态变化图智能优化算法求解基准测试函数F3种群动态变化图智能优化算法求解基准测试函数F4种群动态变化图智能优化算法求解基准测试函数F5种群动态变化图智能优化算法求解基准测试函数F6种群动…...
Qt 中的XML
XML的基本介绍: 在前端开发中:HTML是用来显示数据,而XML是用来传输和存储数据的 XML 指可扩展标记语言(EXtensible Markup Language)XML 是一种标记语言,很类似 HTMLXML 的设计宗旨是传输数据,而…...
中国信通院启动公文写作智能体评估,推动技术落地与规范发展
【导语:中国信通院在前期《智能体技术要求与评估方法》研制基础上,开展公文写作智能体技术规范编制,并联合多家单位共同参与。现正式启动首批评估工作,成果计划于2026年6月发布,将推动该技术落地与规范发展。】联合编制…...
MDXEditor指令系统详解:如何扩展Markdown语法
MDXEditor指令系统详解:如何扩展Markdown语法 【免费下载链接】editor A rich text editor React component for markdown 项目地址: https://gitcode.com/gh_mirrors/editor/editor MDXEditor是一个功能丰富的React组件,专为Markdown编辑设计&am…...
ComfyUI ControlNet模型与预处理器搭配秘籍:提升AI绘画精度的关键技巧
ComfyUI ControlNet模型与预处理器搭配秘籍:提升AI绘画精度的关键技巧 在AI绘画领域,ControlNet已经成为精细控制图像生成的重要工具。对于已经熟悉ComfyUI基础操作的用户来说,掌握ControlNet模型与预处理器的搭配技巧,是突破创作…...
新手最值得入的一款ai音乐工具
2026年,ai音乐爆发的一年。国内国外各种AI音乐工具层出不穷。想要尝试AI音乐的新手宝宝该怎么去选择呢?市面上大大小小的ai音乐创作软件我基本都尝试过。我觉得只有一款工具是最值得推荐的,也是我使用的最多的。那就是蘑兔AI,你们…...
如何通过炉石传说自动化工具实现游戏效率提升?
如何通过炉石传说自动化工具实现游戏效率提升? 【免费下载链接】Hearthstone-Script Hearthstone script(炉石传说脚本)(2024.01.25停更至国服回归) 项目地址: https://gitcode.com/gh_mirrors/he/Hearthstone-Scrip…...
新手福音:借力卓晴式AI,在快马平台轻松完成你的首个网页项目
作为一个刚接触编程的新手,想要创建个人网页却不知从何下手是很常见的情况。最近我发现了一个特别适合新手的组合方案:用AI生成代码在线平台实时调试。下面记录我的完整实践过程,希望能帮到同样想入门的朋友。 明确需求清单 首先梳理出网页需…...
避坑指南:nRF52840蓝牙DFU配置中那些官方文档没细说的‘坑’(基于SDK 17.1.0)
nRF52840蓝牙DFU实战避坑手册:从原理到解决方案的深度解析 在嵌入式开发领域,无线固件升级(DFU)功能已成为蓝牙产品的标配需求。nRF52840作为Nordic Semiconductor的旗舰级蓝牙SoC,配合其完善的SDK支持,理论上应该能够轻松实现这一…...
3步解锁显卡潜力:OptiScaler跨平台开源上采样技术配置攻略
3步解锁显卡潜力:OptiScaler跨平台开源上采样技术配置攻略 【免费下载链接】OptiScaler OptiScaler bridges upscaling/frame gen across GPUs. Supports DLSS2/XeSS/FSR2 inputs, replaces native upscalers, enables FSR3 FG on non-FG titles. Supports Nukem mo…...
核心产品强势放量,扭亏为盈的康希诺未来怎么看?
3月30日晚间,康希诺发布2025年年度报告。报告期内,公司实现营业收入10.68亿元,同比增长26.18%;实现归母净利润2787.27万元,成功实现扭亏为盈,较2024年实现重大逆转。2025年,康希诺凭借核心产品放…...
Qt——窗口部件及窗口类型、坐标系统
1.QWidget类继承QObject和QPaintDevice类,是所有用户界面组件的父类QObject是所有支持Qt对象模型的基类QPaintDevice是Qt中所有可绘制组件的基类QWidget的功能:QWidget能够绘制自己和处理用户的输入QWidget是Qt中所有窗口组件类的父类QWidget是所有窗口组…...
