关于DLL加载进程地址空间的问题 [英] Questions Regarding DLL Loading in a Process Address Space

查看:164
本文介绍了关于DLL加载进程地址空间的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

嗯,我读了几本Matt Pietrek关于便携式可执行文件(PE)文件的文章,例如:





<另外,我已经阅读了关于这个问题的其他一些资料。或者我忽略了一些部分,或者问题没有在那里回答。



所以,这里是问题:


$ b $已知当加载EXE时,Windows Loader会从Importa Address Table(IAT)中读取导入的DLL的列表,并将其加载到进程地址空间。


  1. 进程地址空间是一个虚拟空间。 DLL可能已经加载到某些物理空间中。对于像 KERNEL32.dll USER32.dll 这样的DLL,会发生这种情况。物理和虚拟地址之间的关系是什么?加载器只是分配页面并复制DLL,还是进行引用?


  2. 如果没有加载DLL,Loader会加载整个DLL,还是仅需要功能?例如,如果您从 bar.dll 中使用函数 foo(),则加载器将加载整个 bar.dll 进入进程的地址空间?或者,是否将 foo 的代码加载到进程地址空间?


  3. 假设您的EXE文件使用来自 USER32.DLL 的函数 MessageBox(),它位于%WINDIR% \system32\user32.dll 。您可以开发一个自定义的 USER32.DLL ,将其放在与EXE文件相同的目录中,并期望您自定义的 MessageBox 被您的应用程序调用,而不是系统的默认值 MessageBox



解决方案

Re 1:物理地址不起作用,这里涉及的一切都是虚拟内存。物理地址仅在虚拟内存页面映射到RAM时被页面错误触发而建立。许多基本的DLL在几个进程中出现在同一个虚拟内存地址,如kernel32.dll。这些过程只是共享相同的代码页(而不是数据)。



Re 2:没有实际的加载发生,所使用的功能是同一个支持内存的功能映射文件。这些页面的后台是DLL文件本身,而不是分页文件。直到页面错误迫使Windows将文件从页面读入RAM为止,才会加载任何内容。但是是的,DLL的整个代码段被映射。



Re 3:是的,这将工作。但是,实际上这是不可能的,因为您将不得不为您的程序使用的user32导出写入所有的替换函数。包括其他Win32功能使用的功能,您不能知道。 API钩子是使用的典型技术,微软实验室的曲折是一个很好的例子。



Windows内部版本5是一本很好的书,可以了解有关管道的更多信息。 >

Well, I read several of Matt Pietrek's articles on Portable Executable (PE) files, like:

In addition, I have read a few other sources on the subject. It is either me overlooking some parts, or the questions aren't answered there.

So, here are the questions:

It is known that, when loading an EXE, the Windows Loader reads the list of imported DLL's from the Importa Address Table (IAT), and loads them into the process address space.

  1. The process address space is a virtual space. The DLL may have already loaded into some physical space. This happens for DLLs like KERNEL32.dll or USER32.dll. What is the relation between the physical and virtual address? Does the loader just allocate pages and copy the DLL, or does it make references?

  2. If a DLL is not loaded, does the Loader load the whole DLL, or just the functions needed? For instance, if you used function foo() from bar.dll, does the loader load the whole bar.dll into the process address space? Or, does it just load the foo's code into the process address space?

  3. Assume your EXE file uses function MessageBox() from USER32.DLL, which resides in %WINDIR%\system32\user32.dll. Can you develop a customized USER32.DLL, put it in the same directory as your EXE file, and expect that your customized MessageBox is called by your app instead of the system'd default MessageBox?

解决方案

Re 1: physical addresses play no role, everything involved here is virtual memory. The physical address is only established when a virtual memory page gets mapped into RAM, triggered by a page fault. Many basic DLLs appear at the same virtual memory address in several processes, like kernel32.dll. The processes simply share the same pages of code (not data).

Re 2: no actual 'loading' takes place, the feature used is the same one that supports memory mapped files. The backing of these pages is the DLL file itself, not the paging file. Nothing gets loaded until a page fault forces Windows to read the page from the file into RAM. But yes, the entire code section of the DLL gets mapped.

Re 3: yes, that would work. But it is next to impossible to make it work in practice since you will have to write replacement functions for all the user32 exports that your program uses. Including the ones that other Win32 functions use, you cannot know. API hooking is the typical technique used, Detours from Microsoft Labs is a good one.

Windows Internals edition 5 is an excellent book to learn more about the plumbing.

这篇关于关于DLL加载进程地址空间的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆