Aufrufen der DbgHelp-Bibliothek

Obwohl DbgHelp.dll in allen Versionen von Windows enthalten ist, sollten Aufrufer die Verwendung einer der neueren Versionen dieser DLL in Betracht ziehen, wie sie im Paket Debugtools für Windows zu finden sind. Ausführliche Informationen zur Verteilung von DbgHelp finden Sie unter DbgHelp-Versionen.

Bei Verwendung von DbgHelp besteht die beste Strategie darin, eine Kopie der Bibliothek aus dem Paket Debugtools für Windows im Anwendungsverzeichnis logisch neben der Software zu installieren, die sie aufruft. Wenn auch Symbolserver und Quellserver benötigt werden, müssen sowohl SymSrv.dll als auch SrcSrv.dll im selben Verzeichnis wie DbgHelp.dll installiert werden, da DbgHelp diese DLLs nur aufruft, wenn sie dasselbe Verzeichnis für sie verwenden. (Beachten Sie, dass DbgHelp diese beiden DLLs nicht aus dem Standardsuchpfad aufruft.) Dies trägt dazu bei, die Verwendung nicht übereinstimmender DLLs zu verhindern. ebenso verbessert es die Sicherheit insgesamt.

Der folgende Code wird aus der DbgHelp-Quelle extrahiert. Es zeigt, wie DbgHelp nur Versionen von SymSrv.dll und SrcSrv.dll aus demselben Verzeichnis lädt, in dem sich DbgHelp.dll befindet.

HINSTANCE ghinst;

// For calculating the size of arrays for safe string functions.

#ifndef cch
 #define ccht(Array, EltType) (sizeof(Array) / sizeof(EltType))
 #define cch(Array) ccht(Array, (Array)[0])
#endif

//
// LoadLibrary() a DLL, using the same directory as dbghelp.dll.
//

HMODULE 
LoadDLL(
    __in PCWSTR filename
    )
{
    WCHAR drive[10] = L"";
    WCHAR dir[MAX_PATH + 1] = L"";
    WCHAR file[MAX_PATH + 1] = L"";
    WCHAR ext[MAX_PATH + 1] = L"";
    WCHAR path[MAX_PATH + 1] = L"";
    HMODULE hm;
    
    // Chop up 'filename' into its elements.
    
    _wsplitpath_s(filename, drive, cch(drive), dir, cch(dir), file, cch(file), ext, cch(ext));

    // If 'filename' contains no path information, then get the path to our module and 
    // use it to create a fully qualified path to the module we are loading.  Then load it.
    
    if (!*drive && !*dir) 
    {
        // ghinst is the HINSTANCE of this module, initialized in DllMain or WinMain
         
        if (GetModuleFileNameW(ghinst, path, MAX_PATH)) 
        {
            _wsplitpath_s(path, drive, cch(drive), dir, cch(dir), NULL, 0, NULL, 0);
            if (*drive || *dir) 
            {
                swprintf_s(path, cch(path), L"%s%s%s%s", drive, dir, file, ext);
                hm = LoadLibrary(path);
                if (hm)
                    return hm;
            }
        }
    }
    else
    {
        // If we wanted to, we could have LoadDLL also support directories being specified
        // in 'filename'.  We could pass the path here.  The result is if no path is specified,
        // the module path is used as above, otherwise the path in 'filename' is specified.
        // But the standard search logic of LoadLibrary is still avoided.
        
        /*
        hm = LoadLibrary(path);
        if (hm)
            return hm;
        */
    }
    
    return 0;
}

Nach dem Laden dieser beiden DLLs ruft DbgHelp GetProcAddress auf, um die benötigten Funktionen von ihnen abzurufen.

Normalerweise stellt Code, der DbgHelp.dll aufruft, sicher, dass die richtige Version geladen wird, indem DbgHelp.dll im selben Verzeichnis installiert wird wie die Anwendung, die den aktuellen Prozess initiiert hat. Wenn sich der aufrufende Code in einer DLL befindet und keinen Zugriff auf den Speicherort des anfänglichen Prozesses hat, muss DbgHelp.dll zusammen mit der aufrufenden DLL installiert werden, und Code, der dem LoadDLL von DbgHelp ähnelt, sollte verwendet werden.

DbgHelp-Versionen

LoadLibrary

GetProcAddress

GetModuleFileName