2009-05-11 5 views
1

J'écris une application de suivi de la mémoire qui relie tous les appels à HeapAlloc en utilisant le mécanisme de patch IAT. L'idée est de capturer tous les appels à HeapAlloc et d'obtenir une callstack.Une impasse avec des appels d'accrochage à HeapAlloc pour une application de suivi de mémoire

Cependant, je suis actuellement confronté à un problème avec l'obtention de la callstack en utilisant DBGHELP Apis. J'ai trouvé que dbghelp dll lui-même lie à MSVCRT dll et cette dépendance résulte en un appel récursif. Lorsque j'essaie d'obtenir une pile d'appel pour l'un des appels de l'application cible, dbghelp appelle en interne une méthode de MSVCRT qui appelle à nouveau HeapAlloc. Et comme j'ai déjà corrigé MSVCRT, il en résulte une boucle infinie.

Est-ce que quelqu'un a fait face à ce problème et l'a résolu? Y a-t-il un moyen de sortir de cette impasse? Qu'en est-il de l'utilisation de produits de suivi de la mémoire réels comme GlowCode?

Répondre

3

Ceci est un problème standard dans le code d'interception de fonction. Nous avons rencontré un problème similaire avec une bibliothèque de journalisation qui utilisait la mémoire partagée pour stocker des informations de niveau journal, alors que la bibliothèque de mémoire partagée devait consigner des informations.

La façon dont nous l'avons réparée pourrait être appliquée à votre situation, je crois.

Dans votre code d'interception, conservez un indicateur statique qui indique si vous êtes ou non au milieu d'une interception. Lorsque votre interception est appelée et que l'indicateur n'est pas défini, définissez le drapeau, puis faites ce que vous faites actuellement, y compris en appelant DbgHelp, puis effacez le drapeau. Si votre interception est appelée pendant que l'indicateur est défini, n'appelez que le code HeapAlloc principal sans rien faire d'autre (y compris en appelant DbgHelp qui est la cause de votre récursion infinie).

Quelque chose le long des lignes de (pseudo-code):

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 
+0

Merci pour l'idée, statique ne peut pas m'aider car les appels peuvent provenir de plusieurs threads. Je pense que je peux utiliser TLS à cette fin. – Canopus

+0

En supposant que TLS est la variante Windows de données spécifiques au thread (c'est-à-dire, un «statique» par thread), alors oui, je le pense. Mais HeapAlloc et DbgHelp sont-ils spécifiques au thread ou au processus? Si ce dernier, vous avez vraiment besoin d'un drapeau qui traverse les limites de fil (et est mutex-protégé). – paxdiablo

+0

Merci encore pour l'indice. Je viens de trouver que DbgHelp n'est pas thread-safe. Donc j'ai aussi besoin d'un gardien. – Canopus

0

Vous pouvez utiliser Deviare API Hook et obtenir toute trace de la pile sans utiliser cette API qui a un grand nombre de problèmes.

Questions connexes