Frage

Ein Modul kann entladen werden. Wie kann ich also sicher erkennen, ob es noch im Speicher ist? Ich habe einen Griff, der von getModuleHandle erhalten wurde. Als ich versuchte, GethandLeinformation aufzurufen, sehe ich Fehler 0xc00008 - "Ein ungültiges Handle wurde angegeben." Dies geschah, bevor es entladen werden konnte.

War es hilfreich?

Lösung

Der Begriff "Handle" ist hier etwas überladen - viele verschiedene Klassen von Objekten in der Win32 -API werden als "Handles" bezeichnet.

Die GethandLein -Formation wird für Griffe zu Kernelobjekten verwendet - Dateien, Registrierungsschlüssel, Mutexes usw.

Das von getModuleHandle zurückgegebene Hmodule wird vom Lader verwendet und ist kein tatsächliches Kernel -Objekt, daher schlägt die GethandLeinformation fehl. Keines der Flaggen, die Sie in GethandLeinformation erhalten, ist für Hmodule jedoch sinnvoll.

Wenn Sie überprüfen möchten, ob das Hmodule weiterhin in Speicher geladen ist, können Sie einfach GetModuleHandle anrufen. Diese API sollte schnell genug sein, um viele Male anzurufen. Das Ergebnis von getModuleHandle kann jedoch in dem Moment, in dem er zurückgibt, ungültig sein - ein anderer Thread hätte als Freelibrary bezeichnet können. Es ist besser sicherzustellen, dass die DLL geladen bleibt. Sie können dies tun, indem Sie Lastlibrary selbst aufrufen oder GetModuleHandleex aufrufen, was die Referenzzahl der DLL erhöht.

Andere Tipps

Zwei Lösungen:

1

Rufen Sie GetModulFileName () auf dem Hmodule an. Wenn das Modul geladen ist, erhalten Sie einen gültigen Dateinamen. Wenn es nicht geladen ist, erhalten Sie keinen gültigen Dateinamen. Stellen Sie sicher, dass Sie entweder das erste Byte des zurückgegebenen Dateiname -Arrays auf ' 0' festlegen, bevor Sie GetModuleFileName () aufrufen, oder um den Rückgabewert zu überprüfen. Wenn Sie das erste Byte vor dem Aufruf einstellen, können Sie den Rückgabewert effektiv ignorieren und die String von Nulllängen als "nicht geladenes" Signal behandeln.

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

Rufen Sie VirtualQuery () an, die die Hmodule als Adresse an die Abfrage übergeben. Tun Sie dies als Experiment in einer geladenen Bibliothek und in einer Bibliothek, von der Sie wissen, dass sie befreit werden. Sie werden feststellen, dass sie sehr unterschiedliche Ergebnisse für die zurückgegebene Memory_Basic_information haben. Ich überlasse es Ihnen, einen geeigneten Algorithmus auszuarbeiten, um den Unterschied zwischen den beiden zu bestimmen.

Vorbehalt

Natürlich kann der Vorbehalt, dass ein anderer Thread die Bibliothek entladen kann, während Sie die Eiher dieser Tests ausführen. Nach meiner Erfahrung ist es sehr unwahrscheinlich, dass dies passiert, aber das hängt sehr davon ab, was Sie tun, warum Sie es tun und wenn Sie dies tun, der Ausführungspfad des Programms. Mit Sorgfalt verwenden.

Es ist eine sehr einfache API.

PIMAGE_NT_HEADERS (NTAPI* _RtlImageNtHeader)

Beispielprogramm:

(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
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top