我看到在 Windows 上,函数EnumProcessModules返回为指定进程加载的许多模块(其中一些应该是系统 dll,如guard32.dll、version.dll 等。)
我的问题是:这些模块是否映射到进程的虚拟空间?我可以从主应用程序代码跳转到位于这些模块之一的指令(当然知道地址)吗?
我看到在 Windows 上,函数EnumProcessModules返回为指定进程加载的许多模块(其中一些应该是系统 dll,如guard32.dll、version.dll 等。)
我的问题是:这些模块是否映射到进程的虚拟空间?我可以从主应用程序代码跳转到位于这些模块之一的指令(当然知道地址)吗?
是的,DLL 应该映射到进程虚拟地址空间。如果该页面中的代码尚未执行,则映射可能不受实际物理页面的支持,当然,在没有正确初始化或设置的情况下执行“随机”代码位以使代码正确执行(例如,调用处理函数使用一些需要在另一个函数中分配的数据)显然会在某些不好的定义中以错误的方式结束。还要记住,DLL 很可能在运行相同代码的不同时间加载到不同的地址,等等,所以你不能依赖 DLL 的地址是恒定的——在另一台机器上它很可能完全不同.
是的,只需GetProcAddress
使用您从EnumProcessModules
. GetProcAddress
计算模块内的函数偏移量。
是的,任何可以直接从您自己的可执行文件调用的 DLL 代码都必须映射到您的进程空间。您可以使用 SysInternal 的 VMMap 实用程序获得进程虚拟内存空间的精确图表:http ://technet.microsoft.com/en-us/sysinternals/dd535533
正如其他答案中提到的,虚拟地址空间在很大程度上(如果不是完全的话)是动态的。
在某些情况下,您的进程无法直接访问某些共享库。这些通常是沙盒(安全)内核或驱动程序库,它们通过特殊的安全层/API 调用,执行参数验证,然后执行环/上下文切换到不同的虚拟进程地址空间,或通过安全传递命令线程间通信队列。这些是昂贵的操作,因此它们通常仅在对系统稳定性有好处时才使用。