Question

Un module peut être déchargé, alors comment puis-je savoir à coup sûr si elle est encore en mémoire? J'ai une poignée à lui, obtenu à partir GetModuleHandle. Quand j'ai essayé d'appeler GetHandleInformation à ce que je vois erreur 0xc0000008 - « Une poignée non valide a été spécifiée. » Cela est arrivé avant qu'il aurait pu être déchargé.

Était-ce utile?

La solution

Le terme « poignée » est un peu surchargé ici -. Beaucoup de différentes classes d'objets dans l'API Win32 sont appelés « poignées »

GetHandleInformation est utilisé pour les poignées d'objets noyau -. Fichiers, clés de registre, mutex, etc

Le HMODULE retourné par GetModuleHandle est utilisé par le chargeur et n'est pas un objet réel du noyau, donc ne GetHandleInformation. Aucun des drapeaux que vous obtenez dans GetHandleInformation est logique pour HMODULE bien.

Si vous voulez vérifier si le HMODULE est toujours chargé en mémoire, vous pouvez simplement appeler GetModuleHandle - cette API devrait être assez rapide pour appeler plusieurs fois. Cependant, le résultat de GetModuleHandle peut être invalide le moment, il retourne - un autre thread aurait pu appeler FreeLibrary. Il est préférable de faire en sorte que la DLL ne reste chargé. Vous pouvez le faire en appelant LoadLibrary vous, ou en appelant GetModuleHandleEx qui incrémente le compteur de référence de la DLL.

Autres conseils

Deux solutions:

1

Appel GetModuleFileName () sur le HMODULE. Si le module est chargé, vous obtiendrez un nom de fichier valide. Si ce n'est pas chargé, vous ne serez pas obtenir un nom de fichier valide. Assurez-vous de définir soit le premier octet du tableau de nom de fichier renvoyé à « \ 0 » avant d'appeler GetModuleFileName () ou de vérifier la valeur de retour. Si vous définissez le premier octet avant l'appel, vous pouvez ignorer efficacement la valeur de retour et juste traiter la chaîne de longueur zéro comme un signal « non chargé ».

TCHAR szModName[MAX_PATH + 1];

szModName[0] = _T('\0');
GetModuleFileName(hMod, szModName, MAX_PATH);

// zero length string if not loaded, valid DLL name if still loaded

2

Appel VirtualQuery () faire passer la HMODULE comme l'adresse à interroger. A titre d'expérience faire sur une bibliothèque chargée et une bibliothèque que vous savez être libéré. Vous trouverez qu'ils ont des résultats très differentl pour le MEMORY_BASIC_INFORMATION retourné. Je vous laisse travailler un algorithme approprié pour déterminer la différence entre les deux.

caveat

Bien sûr, la mise en garde qu'un autre thread peut décharger la bibliothèque pendant que vous exécutez eiher de ces tests s'applique. Dans mon expérience, cela est très peu probable, mais cela dépend beaucoup de ce que vous faites, pourquoi vous le faites, et quand vous le faites le chemin d'exécution du programme. Utiliser avec soin.

Il est très simple API.

PIMAGE_NT_HEADERS (NTAPI* _RtlImageNtHeader)

Exemple de programme:

(PVOID)typedef PIMAGE_NT_HEADERS (NTAPI *RTLIMAGENTHEADER)(PVOID);
RTLIMAGENTHEADER RtlImageNtHeader;
HMODULE hDll = GetModuleHandle("ntdll.dll");
HMODULE hDllTmp = LoadLibrary("ws2_32.dll");
RtlImageNtHeader = (RTLIMAGENTHEADER)GetProcAddress(hDll,"RtlImageNtHeader");

struct _IMAGE_NT_HEADERS *r,*r2;
r= RtlImageNtHeader(hDllTmp); 
FreeLibrary(hDllTmp);
r2= RtlImageNtHeader(hDllTmp);

//r = NULL
//r2 = return ws2_32 PE Header address
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top