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

在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一直说这个观点。现在经过证实了。上一张图来说明问题:

图一

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

图二

 

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

 

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

 

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

 

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

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

图三

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

图四

图五

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

图六

图七

看到.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>比较好.

 

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

 

时间: 2024-10-28 00:58:18

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

存储区域网络-怎样让Windows在启动时不默认加载san磁盘

问题描述 怎样让Windows在启动时不默认加载san磁盘 172.30.1.9是服务器,在旁边有一个存储,172.30.1.9的h盘属于外置存储的盘,上网查下并且验证怎么样能够让windows启动时不默认加载这个属于存储的磁盘.

讨论html与javascript在浏览器中的加载顺序问题_javascript技巧

前一阵子横扫了javascript,当时自我感觉良好.现在一想,又觉得没什么.今天的任务是把asp.net ajax中客户端页面生命周期那一章研究完.然而,因为这一章的内容使我产生了一些迷惑.这些疑惑在书中都没有只字提及. 一.html页面的详细加载过程是什么呢?页面元素在加载时的优先级是什么? 二.javascript的作用域.变量的作用域.不同脚本段之间的关系? 三.html页面的生命周期? 这些问题真的打中了我的死穴.不了解这些,我就无法透过asp.net ajax的框架看到其底层原理.只

Windows下解决php_curl扩展模块无法加载的处理方法

apache 中php_curl不能加载 提示错误Fatal error:Call to undefined function curl_init().我估计应该有人也有类似问题,赶紧百度一下,果然好多人遇到这个问题 1.将PHP安装目录中找libeay32.dll,ssleay32.dll,php_curl.dll,php5ts.dll四个DLL文件,有的在ext目录,找到后将他们复制到system32下,如果找不到请下载对应版本的PHP复制过去; 2.检查php.exe, php5ts.dl

Windows CE下流驱动的动态加载

    我想很多WinCE的开发人员,尤其是刚入门并且做驱动开发的工程师,都曾碰到这样一个问题,要编写一个外围设备的驱动,拿最简单的GPIO驱动来说,编写驱动本身可能只花了一会儿功夫,可要把编译生成的DLL打包到先前做好的操作系统映像当中,最简单也得MakeImg一下,还要修改BIB文件.注册表文件,以让系统启动的时候就加载该驱动,所有工作都做完了,还得花几分钟下载整个操作系统到内存去运行,这也得要个好几分钟.能力强的人一次成功,不走回头路也就算了.如果驱动编写得有问题,那又得改代码,重新编译,

Windows 8如何禁用Internet Explorer加载项?win8禁用ie加载项的方法

1. 在桌面模式下,点击左下角的[IE]图标.    2. 点击右上方的[小齿轮]图标.    3. 选择[管理加载项].    4. 点击[工具栏和扩展].    5. 点击[当前已加载的加载项].    6. 选择[所有加载项].    7. 选择需要禁用的加载项.    8. 选择好后,点击右下方的[禁用].    9. 当该加载项的状态变为"已禁用"代表设置成功.    提示:某些加载项被禁用后会造成某些功能的失效,比如网银等.所以禁用前需了解该加载项的功能.  

Windows 2003 中IIS php5isapi.dll加载失败

1.很多朋友也就明白怎么来解决这个问题了,就是把users这个用户给php目录加上,然后给这个用户组设置读取权限.很多网上的朋友说加everone用户并设置权限,其实道理是一样的,我还是喜欢用users用户组. 总结一点就是权限设置的问题,所以当你的配置和我的配置一样但是还是没有加载成功的时候,那就要注意一下权限的问题了. 2.解决服务器扩展权限:来到IIS6.0的"服务器扩展"设置页面,如果你想图省事,可以直接点击"允许所有的未知ISAPI"的按钮,但我并不推荐这

windows编程,加载dll库示例

第一种方式,手动找到函数地址,进行调用. LoadLibrary(): GetProcAddress(): 生成dll库 #include<Windows.h> //导出函数,可以加载的时候调用 _declspec(dllexport) void msg() { MessageBoxA(0, "1", "2", 0); } //导出函数,可以加载的时候调用 _declspec(dllexport) int add(int a, int b) { retu

Windows PE 3.0的制作及第三方驱动集成

winpe2.0 基于windows XP内核 winpe3.0 基于WIN7内核 ================================================ 制作PE3.0 ISO Windows PE3.0制作方法 从Win7中提取制作 制作方法: 1.把windows7光盘(或光盘镜像)里的\sources\boot.wim文件复制到d:\ 2.在imgaex目录里右键点击inf文件,选安装.(Imagex 6.0 AIK 封装工具) 3.运行cmd,进入imgaex

用闪存Windows PE启动VMWare虚拟机

  问:我想用闪存的Windows PE启动VMWare虚拟机,可是VMWare提示"禁用USB设备的主机连接",请问我要怎样才能让虚拟机使用USB设备呢? 答:分析应该是VMWare USB Arbitration Service服务没有启用,解决方法是进入"控制面板→管理工具→服务",开启"vmware Usb arbitration server"服务,重新启动VMWare,就可以了. 如果无法启动这个服务,有可能是你的系统为AMD平台且安