[继续讨论]关于Windows PE和.net assembly的加载

简介: 在firelong写的关于近期C#大论战的回应的评论中有许多观点。有些话题当时没有看清楚。后来抽时间看了一下。那些评论里面的观点实在太多,没有办法一一验证。我只谈我的发现。   1. SizeOfImage对Windows PE内存加载的影响   我开始建立起来的概念是Windows PE都会全部加载进内存执行。

在firelong写的关于近期C#大论战的回应的评论中有许多观点。有些话题当时没有看清楚。后来抽时间看了一下。那些评论里面的观点实在太多,没有办法一一验证。我只谈我的发现。

 

1. SizeOfImage对Windows PE内存加载的影响

 

我开始建立起来的概念是Windows PE都会全部加载进内存执行。当那个评论中有人提到了RAR自解压EXE。我当时是想当然地认为RAR自解压EXE同样也会全部加载进内存. 后来经其他人的指出,还有做试验,证实即使物理内存不够大同时没有页面文件的情况下也能解压一个很大的文件。我真有点想不透是什么原因。当时有一个网友gussing提到了SizeOfImage参数, 让我有点启发。后来经过进一步的查看,才知道RAR自解压EXE是Windows PE的一种特例。这个特别之处就在SizeOfImage参数上。用Windbg装入一个35M的RAR自解压EXE, 然后用RAMMap查看其物理内存占用.发现其内存占用大约是0x00020000. 再用CFF explorer VII查看其PE文件, 果然SizeOfImage字段是0x00020000.

其他的Windows PE文件呢,如ntdll.dll,其SizeOfImage是0x00127000, 其文件大小是1,202,168, 十六进制是0x1257F8. 看来SizeOfImage刚好和文件大小相匹配,刚刚足以装下这个ntdll.dll本身。再看Windows文件夹下许多其他的EXE/DLL, 很多都是SizeOfImage与其文件大小刚好相匹配。

综上所述, SizeOfImage决定了PE加载到内存里的大小。

 

2. Windoes PE是用File mapping加载的

 

网友Ivony一直说这个观点。现在经过证实了。上一张图来说明问题:

img_d2116b82d556c091c1181166eec1665e.jpg

图一

这个图二可以帮组你理解File mapping是怎么运作的。

img_531a50124363984b7f24407343231bb6.jpg

图二

 

3. 许多Windows PE是全部加载进内存的

 

上面那个图一已经告诉我们MSPAINT.EXE在内存里的物理地址,而且上下卷动一下,你会发现每个物理内存页都是Active. 就是都在内存里。当然了,不是所有的Windows PE都全部加载进内存。因为这受SizeOfImage参数影响。

 

4. .net assembly(即.net PE)也是全部加载进内存的

 

首先.net PE的SizeOfImage也是与其文件大小相匹配的。这是前提。接下来看看实际的证据:

我的.net PE文件大小27M左右:

img_fbc229ec4c0278fad2c2d3cf215e0150.jpg

图三

运行之后,用RAMMap查看物理内存页状态:

img_785a857c418b0b3919efedfc236cc71d.jpg

图四

img_93e78550f8c30bbdb4a51bfedfb21679.jpg

图五

这个文件很大。内存页有很多。上下翻动看了一下,除了前面有一些Standby之外,大部分是Active,就是说大部分在内存里面. 但是为什么会有Standby呢?开始还是不太明白。直到我看到了VMMap给出的图:

img_ea5c58e228be4f307431c29e968ab213.jpg

图六

img_b0e7b71471085dfaa875aa14d3976257.jpg

图七

看到.net PE的这些节没有: header, .text, .rsrc, .reloc, 还有标记为Reserved的节没有。对比了非托管的Windows PE和.net PE, 在内存映像上是有差别的。非托管的Windows PE基本是全部装入内存,而.net PE的内存映像总要空几段。在header和.text之间要空一段,.rsrc和.reloc之间要空一段。

 

5.  另外一个问题, Working set 为什么只有7-8M大呢?

这个.net PE大部分实际上已经进了内存。但是为什么这个进程的Working set为什么只有7-8M大呢?

想起了Working set的定义: The working set of a program is a collection of those pages in its virtual address space that have been recently referenced.
然后又想起了图二。有点明白是什么回事情了。那就是每个进程建立的File view不一样。这个File View对Working set的大小有影响。

 

还是系统地读<Windows Internals>比较好.

 

这里说的,和看到的可能并不是真相。还请达人指点一二。

 

目录
相关文章
|
4月前
|
Linux C++ Windows
【Azure 应用服务】Azure App Service(Windows)环境中如何让.NET应用调用SAP NetWeaver RFC函数
【Azure 应用服务】Azure App Service(Windows)环境中如何让.NET应用调用SAP NetWeaver RFC函数
【Azure 应用服务】Azure App Service(Windows)环境中如何让.NET应用调用SAP NetWeaver RFC函数
|
2月前
|
开发框架 .NET API
Windows Forms应用程序中集成一个ASP.NET API服务
Windows Forms应用程序中集成一个ASP.NET API服务
96 9
|
2月前
|
算法 Linux API
.NET图像处理的艺术 — 从加载到添加文本,一步步领略图像处理的奇妙世界
.NET图像处理的艺术 — 从加载到添加文本,一步步领略图像处理的奇妙世界
33 2
|
2月前
|
Windows
.NET 隐藏/自定义windows系统光标
【10月更文挑战第20天】在.NET中,可以使用`Cursor`类来控制光标。要隐藏光标,可将光标设置为`Cursors.None`。此外,还可以通过从文件或资源加载自定义光标来更改光标的样式。例如,在表单加载时设置`this.Cursor = Cursors.None`隐藏光标,或使用`Cursor.FromFile`方法加载自定义光标文件,也可以将光标文件添加到项目资源中并通过资源管理器加载。这些方法适用于整个表单或特定控件。
|
4月前
|
缓存 NoSQL Linux
【Azure Redis 缓存】Windows和Linux系统本地安装Redis, 加载dump.rdb中数据以及通过AOF日志文件追加数据
【Azure Redis 缓存】Windows和Linux系统本地安装Redis, 加载dump.rdb中数据以及通过AOF日志文件追加数据
131 1
【Azure Redis 缓存】Windows和Linux系统本地安装Redis, 加载dump.rdb中数据以及通过AOF日志文件追加数据
|
4月前
|
Linux iOS开发 开发者
跨平台开发不再难:.NET Core如何让你的应用在Windows、Linux、macOS上自如游走?
【8月更文挑战第28天】本文提供了一份详尽的.NET跨平台开发指南,涵盖.NET Core简介、环境配置、项目结构、代码编写、依赖管理、构建与测试、部署及容器化等多个方面,帮助开发者掌握关键技术与最佳实践,充分利用.NET Core实现高效、便捷的跨平台应用开发与部署。
236 3
|
4月前
|
Java Windows 容器
【应用服务 App Service】快速获取DUMP文件(App Service for Windows(.NET/.NET Core))
【应用服务 App Service】快速获取DUMP文件(App Service for Windows(.NET/.NET Core))
|
4月前
|
开发框架 JavaScript 前端开发
【App Service】解决 .NET Profiler 报告打开后无数据加载的问题
【App Service】解决 .NET Profiler 报告打开后无数据加载的问题
|
4月前
|
网络安全 API 数据安全/隐私保护
【Azure App Service】.NET代码实验App Service应用中获取TLS/SSL 证书 (App Service Windows)
【Azure App Service】.NET代码实验App Service应用中获取TLS/SSL 证书 (App Service Windows)
|
4月前
|
Java 开发工具 Spring
【Azure Spring Cloud】使用azure-spring-boot-starter-storage来上传文件报错: java.net.UnknownHostException: xxxxxxxx.blob.core.windows.net: Name or service not known
【Azure Spring Cloud】使用azure-spring-boot-starter-storage来上传文件报错: java.net.UnknownHostException: xxxxxxxx.blob.core.windows.net: Name or service not known

热门文章

最新文章

下一篇
无影云桌面