다음을 통해 공유


DbgHelp 라이브러리 호출

DbgHelp.dll은 모든 버전의 Windows와 함께 제공되지만 호출자는 Windows용 디버깅 도구 패키지에 있는 이 DLL의 최신 버전 중 하나를 사용하는 것을 고려해야 합니다. DbgHelp 배포에 대한 자세한 내용은 DbgHelp 버전을 참조하세요.

DbgHelp를 사용할 때 가장 좋은 전략은 Windows용 디버깅 도구 패키지의 라이브러리 복사본을 이를 호출하는 소프트웨어에 논리적으로 인접한 애플리케이션 디렉터리에 설치하는 것입니다. 기호 서버와 원본 서버도 필요한 경우 SymSrv.dll 및 SrcSrv.dll은 모두 DbgHelp.dll과 동일한 디렉터리에 설치해야 합니다. DbgHelp는 동일한 디렉터리를 공유하는 경우에만 이러한 DLL을 호출하기 때문입니다. (DbgHelp는 표준 검색 경로에서 이 두 DLL을 호출하지 않습니다.) 이는 일치하지 않는 DLL의 사용을 방지하는 데 도움이 됩니다. 마찬가지로 전반적인 보안도 개선됩니다.

다음 코드는 DbgHelp 원본에서 추출됩니다. DbgHelp가 DbgHelp.dll이 상주하는 동일한 디렉터리에서 SymSrv.dll 및 SrcSrv.dll 버전만 로드하는 방법을 보여 줍니다.

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;
}

이 두 DLL을 로드한 후 DbgHelp는 GetProcAddress를 호출하여 필요한 함수를 가져옵니다.

일반적으로 DbgHelp.dll을 호출하는 코드는 현재 프로세스를 시작한 애플리케이션과 동일한 디렉터리에 DbgHelp.dll을 설치하여 올바른 버전이 로드되도록 합니다. 호출 코드가 DLL에 있고 초기 프로세스의 위치에 대한 액세스 권한이나 지식이 없는 경우 DbgHelp.dll을 호출 DLL과 함께 설치해야 하며 DbgHelp의 LoadDLL과 유사한 코드를 사용해야 합니다.

DbgHelp 버전

LoadLibrary

GetProcAddress

GetModuleFileName