2010-05-23 60 views

回答

0

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

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

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

+0

非常感谢!我已经实现了DLL注入,并且API挂钩看起来像是一个很好的解决方案。令我困扰的是性能开销 - 我注入的应用程序分配了超过600MB的内存,但我仍会尝试。来自乌克兰的问候:) – Micktu 2010-05-25 10:59:42

+0

欢迎您!我特别高兴能帮助一个和我背景相同的人。因为开销,你应该尝试一下。堆上的内存分配不是一个cheep操作,所以如果你不是在每个函数调用时都在日志文件中写入一个记录文件,而是用一些标准过滤掉调用(你应该知道哪一个更好),那么你的应用程序的总体性能将不会有太大的改变。如果您使用内存映射文件写入日志(您只需将字符串复制到映射文件内存),写入文件将非常快速。最诚挚的问候和更多的成功希望来自德国。 – Oleg 2010-05-25 21:31:57

1

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

如果你正在谈论一个通用的读/写内存页面,我认为你是,那么我不知道一种方法来找出它“属于”什么 - 我也不认为这是这里拥有严格的所有权概念。

+0

谢谢!是的,我正在谈论通用读/写。当然,知道DLL的基地址没有问题。我想找到一种方法来告诉内存中已经加载的库的进程内存 - 迄今为止没有成功。 – Micktu 2010-05-23 10:40:43

相关问题