我正在编写一个内存跟踪应用程序,使用IAT修补机制将所有对HeapAlloc的调用挂钩。 这个想法是捕获所有对HeapAlloc的调用,并获得一个调用堆栈。
不过,我目前面临使用DBGHELP Apis获取调用堆栈的问题。 我发现dbghelp DLL本身链接到MSVCRT DLL,这种依赖导致recursion调用。 当我尝试从目标应用程序调用任何调用的调用堆栈时,dbghelp在内部调用MSVCRT中的某个方法,该方法再次调用HeapAlloc。 而且由于我已经修补了MSVCRT,所以会导致无限循环。
有没有人遇到这个问题并解决了它? 有什么办法摆脱这个僵局?
这是函数拦截代码中的一个标准问题。 我们在使用共享内存来存储日志级别信息的日志库中遇到类似的问题,而共享内存库必须记录信息。
我相信,我们解决这个问题的方法可以适用于你的情况。
在你的拦截代码中,保持一个静态标志,指示你是否在拦截中。 当你的拦截被调用并且没有设置标志时,设置标志然后执行你目前的操作,包括调用DbgHelp,然后清除标志。
如果在设置标志时调用拦截,则只调用后端HeapAlloc代码而不执行其他任何操作(包括调用导致无限递归的DbgHelp)。
(伪代码)的一些东西:
function MyHookCode: static flag inInterceptMode = false if inInterceptMode: call HeapAlloc return inInterceptMode = true call DbgHelp stuff call HeapAlloc inInterceptMode = false return function main: hook HeapAlloc with MyHookCode : : : return
那么使用一些真正的内存跟踪产品,如GlowCode ?
您可以使用Deviare API Hook并获取完整的堆栈跟踪,而无需使用具有大量问题的API。