[继续讨论]关于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>比较好.

 

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

 

目录
相关文章
|
18天前
|
C# Windows
.NET开源免费的Windows快速文件搜索和应用程序启动器
今天大姚给大家分享一款.NET开源(MIT License)、免费、功能强大的Windows快速文件搜索和应用程序启动器:Flow Launcher。
|
18天前
|
存储 文字识别 C#
.NET开源免费、功能强大的 Windows 截图录屏神器
今天大姚给大家分享一款.NET开源免费(基于GPL3.0开源协议)、功能强大、简洁灵活的 Windows 截图、录屏、Gif动图制作神器:ShareX。
|
1月前
|
Windows
windows server 2019 安装NET Framework 3.5失败,提示:“安装一个或多个角色、角色服务或功能失败” 解决方案
windows server 2019 安装NET Framework 3.5失败,提示:“安装一个或多个角色、角色服务或功能失败” 解决方案
140 0
|
2月前
|
C# Windows
.NET开源的一个小而快并且功能强大的 Windows 动态桌面软件
.NET开源的一个小而快并且功能强大的 Windows 动态桌面软件
|
4月前
|
JavaScript Linux C#
【傻瓜级JS-DLL-WINCC-PLC交互】1.C#用windows窗体控件创建.net控件
【傻瓜级JS-DLL-WINCC-PLC交互】1.C#用windows窗体控件创建.net控件
65 0
|
4月前
|
人工智能 机器人 C#
Windows编程课设(C#)——基于WPF和.net的即时通讯系统(仿微信)
一款参考QQ、微信的即时通讯软件。采用CS结构,客户端基于.Net与WPF开发,服务端使用Java开发。
|
4月前
|
C# Windows
C#安装“Windows 窗体应用(.NET Framework)”
C#安装“Windows 窗体应用(.NET Framework)”
51 0
|
4月前
|
SQL Shell 数据库
七天.NET 8操作SQLite入门到实战 - 第二天 在 Windows 上配置 SQLite环境
七天.NET 8操作SQLite入门到实战 - 第二天 在 Windows 上配置 SQLite环境
|
4月前
|
缓存 C# Windows
一款.NET开源的小巧、智能、免费的Windows内存清理工具 - WinMemoryCleaner
一款.NET开源的小巧、智能、免费的Windows内存清理工具 - WinMemoryCleaner
|
4月前
|
Windows
5.1 Windows驱动开发:判断驱动加载状态
在驱动开发中我们有时需要得到驱动自身是否被加载成功的状态,这个功能看似没啥用实际上在某些特殊场景中还是需要的,如下代码实现了判断当前驱动是否加载成功,如果加载成功, 则输出该驱动的详细路径信息。该功能实现的核心函数是`NtQuerySystemInformation`这是一个微软未公开的函数,也没有文档化,不过我们仍然可以通过动态指针的方式调用到它,该函数可以查询到很多系统信息状态,首先需要定义一个指针。
39 0
5.1 Windows驱动开发:判断驱动加载状态