【问题标题】:Pages used by a DLL in the address space of a processDLL 在进程地址空间中使用的页面
【发布时间】:2010-05-23 09:11:24
【问题描述】:

是否有可靠的方法来获知内存页面或页面范围属于进程地址空间内的特定 DLL?

【问题讨论】:

    标签: c++ windows winapi dll memory-management


    【解决方案1】:

    取决于页面的类型。 dll的代码页地址等在加载时是已知的,并且可以通过查看“加载的模块”窗口或任何调试器中的等效窗口来查看。

    如果您谈论的是一般的读/写内存页面,而我认为您是,那么我不知道有什么方法可以找出它“属于”哪个 dll - 我也不认为有这里有严格的所有权概念。

    【讨论】:

    • 谢谢!是的,我说的是通用读/写。当然,知道 DLL 的基地址是没有问题的。我想找到一种方法来从它已加载的库的内存中告诉进程的内存 - 到目前为止没有成功。
    【解决方案2】:

    有一种方法称为API 挂钩。来自 John Robbins 的著名 BugslayerUtil.DLL(参见他的书“调试应用程序”)战争最初用作自己进程内部的 API 挂钩。我的意思是,所有内存分配都可以分配给少数众所周知的函数,如LocalAllocGlobalAllocVirtualAlloc 等。可以在进程地址空间内覆盖此函数的起始地址。您可以在进程开始时的某个地方执行此操作,也可以使用 DLL 注入来执行此操作(就像在分析模式下执行 Dependency Walker 一样)。因此,您将能够记录(跟踪)每次内存分配尝试,将调用转发到原始函数,再次查看结果返回值记录(跟踪)并返回结果。在每次调用尝试中,您都可以在调用堆栈上看到调用此函数的所有函数。因此,调用堆栈的包含以及分配的内存地址和大小为您提供了您正在寻找的完整信息。您将在动态中看到所有内容。

    你不应该自己实现所有东西。只需在互联网上搜索“API 挂钩”或“DLL 注入”,您就会找到足够的工作示例。为了检查调用堆栈,您可以使用 imagehlp.dll / dbghelp.dll 中记录的 StackWalk64 函数(参见 http://msdn.microsoft.com/en-us/library/ms680650(VS.85).aspx)(例如参见 http://www.codeproject.com/KB/threads/StackWalker.aspx)。

    所以在我看来你的问题可以解决。

    【讨论】:

    • 非常感谢!我已经实现了 DLL 注入,API 挂钩看起来是一个很好的解决方案。困扰我的是性能开销——我注入的应用程序分配了超过 600MB 的内存,但无论如何我都会尝试。来自乌克兰的问候:)
    • 欢迎您!我特别高兴能帮助与我背景相同的人。由于开销太大,您应该尝试一下。堆上的内存分配不是一个廉价的操作,所以如果你不是在每个函数调用时都在日志文件中写一个,用一些标准过滤调用(你应该知道哪个更好),那么你的应用程序的总体性能不会有太大变化。如果您使用内存映射文件写入日志(您只需将字符串复制到映射文件内存),写入文件将非常快。来自德国的最诚挚的问候和成功的祝愿。
    猜你喜欢
    • 1970-01-01
    • 2011-05-26
    • 1970-01-01
    • 2010-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多