内存模块是否映射到进程的虚拟空间?

时间:2012-12-28 16:34:08

标签: c++ windows debugging memory-management

我在Windows上看到函数EnumProcessModules返回为指定进程加载的一些模块(其中一些应该是系统dll,如guard32.dll,version.dll等)。

我的问题是:这些模块是否已映射到流程中'虚拟空间?我可以从主应用程序代码跳转到其中一个模块(当然知道地址)的指令吗?

3 个答案:

答案 0 :(得分:5)

是的,DLL应该映射到进程虚拟地址空间。如果该页面中的代码尚未执行,则映射可能无法由真实物理页面支持,当然,如果没有正确的初始化或设置以使代码正确执行(例如调用处理函数),则执行“随机”位代码那些使用一些需要在另一个函数中分配的数据)在一些不好的定义中会明显地结束。还要记住,DLL可能会在运行相同代码等的不同时间加载到不同的地址,因此您不能依赖DLL的地址是恒定的 - 并且它可能在另一台机器中完全不同。

答案 1 :(得分:1)

是的,只需使用GetProcAddress获得的模块致电EnumProcessModules即可。 GetProcAddress计算模块中的函数偏移量。

答案 2 :(得分:1)

是的,任何可以直接从您自己的可执行文件调用的DLL代码都必须映射到您的进程空间。您可以使用SysInternal的VMMap实用程序获取流程虚拟内存空间的精确图表:http://technet.microsoft.com/en-us/sysinternals/dd535533

正如其他答案中所提到的,虚拟地址空间在很大程度上(如果不是完全的话)是动态的。

有些情况下,您的流程无法直接访问某些共享库。这些通常是沙盒(安全)内核或驱动程序库,它们通过执行参数验证的特殊安全层/ API调用,然后执行环/上下文切换到不同的虚拟进程地址空间,或通过安全传递命令线程间通信队列。这些是昂贵的操作,因此它们通常仅在系统稳定性有益时才保留使用。