惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

B
Blog
I
InfoQ
Y
Y Combinator Blog
The Last Watchdog
The Last Watchdog
博客园_首页
The Cloudflare Blog
博客园 - 【当耐特】
Engineering at Meta
Engineering at Meta
罗磊的独立博客
月光博客
月光博客
V
V2EX
大猫的无限游戏
大猫的无限游戏
腾讯CDC
GbyAI
GbyAI
云风的 BLOG
云风的 BLOG
Stack Overflow Blog
Stack Overflow Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Attack and Defense Labs
Attack and Defense Labs
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Google Online Security Blog
Google Online Security Blog
B
Blog RSS Feed
Webroot Blog
Webroot Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
N
Netflix TechBlog - Medium
量子位
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Vercel News
Vercel News
C
CERT Recently Published Vulnerability Notes
人人都是产品经理
人人都是产品经理
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Recent Announcements
Recent Announcements
Cyberwarzone
Cyberwarzone
G
Google Developers Blog
H
Heimdal Security Blog
MyScale Blog
MyScale Blog
The Register - Security
The Register - Security
博客园 - 三生石上(FineUI控件)
小众软件
小众软件
aimingoo的专栏
aimingoo的专栏
T
Tenable Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
O
OpenAI News
C
Check Point Blog
Forbes - Security
Forbes - Security
SecWiki News
SecWiki News
K
Kaspersky official blog
The GitHub Blog
The GitHub Blog
Security Archives - TechRepublic
Security Archives - TechRepublic
F
Full Disclosure
阮一峰的网络日志
阮一峰的网络日志

博客园 - wyi23

Web2.0特征列表(收藏的) RSS2.0说明 RSS 2.0规范 - wyi23 - 博客园 用XMLHttpRequest和struts实现AJAX(转) Gmail 使用的AJAX技术研究(转贴) AJAX框架汇总 Ajax 网址备忘 Ajax介绍(转载) .NET 試題 什么是Ajax 在Windows SharePoint Service平台上构建协作式应用 SPS/WSS资源 检查本机是否被黑客利用为DDOS攻击的工具(转载) SYN Flood攻击的基本原理及防御 黑客是如何组织一次DDoS攻击的(转载) DDoS攻击实例 - SYN Flood攻击(转载) 海盗的难题(转载) .NET建模 关于开发系统后门软件的几点思路
对PE文件中若干存储信息的一些理解(转载)
wyi23 · 2005-03-23 · via 博客园 - wyi23

作为PE格式文件,存在的目的就是为了在系统中执行。所以要在一个环境中执行,这个环境就会为这个文件的执行进行一些相关的操作,而操作需要条件和操作的量化!所以在PE文件中存储着一些数据,这些数据的存在就是为系统执行PE文件进行量化和设置约束条件。

在了解PE文件中为系统加载执行所存储信息之前,有必要先了解一下一个PE文件被分配进程空间后进程空间的布局(Layout)情况,这样会更容易理解我们所阐述的内容。一个PE文件被系统加载进属于自己的进程空间后,进程空间分成用户地址空间和系统地址空间,分别占据进程4G地址空间的高低2G(对于32位系统),由于PE文件中存储的所有信息都是为了控制系统对PE文件的加载和执行,和系统自身并无多大联系,因此,我们这里只列出用户地址空间的布局。因此,当前进程空间的用户地址空间布局大概如下:
1.进程参数
2.进程堆
3.进程载入的模块,就是为执行当前进程需要的外部引用和当前进程数据本身
这里需要注意的一点,假如存在一个PE文件,名称为A.EXE,其中需要使用外部引用B.DLL和C.DLL,那么系统加载器将先按照在A中引用B和C的顺序先加载B和C,并把对A的加载紧跟在B和C之后。例如,假设A中引用B和C的顺序为C、B,那么最后的地址空间中模块区的内容分别是:C的.text、C的.data、B的.text、B的.data、A的.text和A的.data
4.进程PEB,即进程环境块
5.线程堆栈及线程TEB,即线程环境块

当我们在某个IDE中写好代码,经过编译器、连接器的加工,多个目标文件组合成可执行文件,然后可执行文件被加载器加载到内存空间做好开始执行的准备。在PE文件中的PE头存储着一些与系统相关的信息,系统在加载可执行文件到内存时,首先会根据PE头中的.ImageBase字段获取PE映像文件在进程空间中的加载起始地址,从而确立PE文件应该加载到进程空间的什么位置;进程需要堆空间,而线程需要栈空间,对这些空间的分配是依据PE头中的SizeOfStackReserve、SizeOfStackCommit以及SizeOfHeapReserve和SizeOfHeapCommit来进行的,这些字段分别代表着为PE文件执行保留的进程堆和线程堆栈的大小以及对应增量大小。但需要注意的是加载器对进程堆和线程堆栈的分配工作并不是连贯进行的,中间穿插着载入模块的加载工作;接着从PE头字段SizeOfCode、SizeOfInitializedData和SizeOfUninitializedData获取PE文件.text、.data和.bss区域的大小,并在系统的进程空间中保留等同尺寸的内存区域,待之后将相关内容加载到此内存范围中。当前应用需要的外部引用中也包含着SizeOfCode的类似信息。因此,对引用的加载信息来源于引用本身;除了加载PE代码节和数据节的内容,系统加载器还会将PE文件的PE/COFF头加载到对应进程空间,具体加载到什么位置依据的是前面提到的.ImageBase字段值,而为PE/COFF头预留空间大小则根据字段.SizeOfHeaders来进行分配;当然,仅仅确立PE映像的起始加载地址是不够的,因为如果不确定PE文件需占VA空间的大小,那么就无法确定线程堆栈的分配地址,因为线程堆栈的分配是在用户地址空间的最后进行的。因此,为了确认PE文件载入跨度,系统加载器需要读取PE头中的SizeOfImage字段值。

至此,系统完成了对PE的加载,开始执行PE内容。

由上不难看出,在进程空间中,进程堆在代码区和数据区之前,而代码区和数据区又在线程堆栈之前。这点对我们开发调试软件很重要,我们可以在具体的软件设计过程中使用相关工具进行查看验证.....由于.NET PE的结构和传统的PE相差并不大,因此,这里的内容对传统PE同样适用.....