Incorrect SymLoadModuleEx image name.

Aleksandr Kazakov 1 Reputation point
2022-04-18T07:58:33.343+00:00

I'm trying to load module for dbghelp.dll in my code with SymSetOptions(SYMOPT_DEBUG):

TCHAR  szImageName[MAX_PATH] = TEXT("C:\\Windows\\SysWOW64\\dbghelp.dll");

            module = SymLoadModuleEx(hProcess,  // our unique id
                NULL,      // no open file handle to image
                szImageName,   // name of image to load
                NULL,      // no module name - dbghelp will get it
                0,         // no base address - dbghelp will get it
                0,         // no module size - dbghelp will get it
                NULL,      // no special MODLOAD_DATA structure
                0);        // flags

And the log information is:

DBGHELP: Symbol Search Path: .
10:52:39 +3 [base] DBGHELP: No header for C.  Searching for image on disk
10:52:39 +3 [base] DBGHELP: <>\C - file not found
10:52:39 +3 [base] DBGHELP: symsrv.dll load failure
10:52:39 +3 [base] DBGHELP: C not found in .
10:52:39 +3 [base] DBGHELP: C - no symbols loaded

Why is it looking for module with name C if I m passing the full path?

C++
C++
A high-level, general-purpose programming language, created as an extension of the C programming language, that has object-oriented, generic, and functional features in addition to facilities for low-level memory manipulation.
3,591 questions
{count} votes

4 answers

Sort by: Most helpful
  1. RLWA32 41,831 Reputation points
    2022-04-18T08:19:33.603+00:00

    The docs indicate "To call the Unicode version of this function, define DBGHELP_TRANSLATE_TCHAR."

    Was this done?


  2. Minxin Yu 10,461 Reputation points Microsoft Vendor
    2022-04-18T08:22:42.117+00:00

    Hi, @Aleksandr Kazakov

    Processes explicitly linking to a DLL call GetProcAddress to obtain the address of an exported function in the DLL. Because you are calling the DLL function through a pointer and there is no compile-time type checking, make sure that the parameters to the function are correct so that you do not overstep the memory allocated on the stack and cause an access violation.

    For your reference: Dynamically load a function from a DLL
    Or implicit link: Walkthrough: Create and use your own Dynamic Link Library (C++)

    Best regards,

    Minxin Yu


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


  3. RLWA32 41,831 Reputation points
    2022-04-19T11:28:15.49+00:00

    The typedefs that you use for dynamically linking functions from dbghelp.dll are incorrect. They omit the __stdcall calling convention.


  4. RLWA32 41,831 Reputation points
    2022-04-19T19:54:34.98+00:00

    Following example uses dynamic linking with dbghelp.dll to invoke SymLoadModuleEx(W) depending on the character set setting.

    #define WIN32_LEAN_AND_MEAN  
    #include <Windows.h>  
      
    #ifdef UNICODE  
    #define DBGHELP_TRANSLATE_TCHAR  
    #endif  
    #include <DbgHelp.h>  
      
    #include <stdio.h>  
    #include <tchar.h>  
      
    typedef decltype(SymInitialize) *SI;  
    typedef decltype(SymGetOptions) *SGO;  
    typedef decltype(SymSetOptions) *SSO;  
    typedef decltype(SymLoadModuleEx) *SLMX;  
      
    int main()  
    {  
        TCHAR szModule[]{ _T("C:\\Windows\\SysWOW64\\dbghelp.dll") };  
      
        // Set DLL search order so that Dbghelp.dll version from Windows SDK is loaded and symsrv.dll can be loaded  
        if (!SetDllDirectory(DBGHELPDLL))  
            _tprintf_s(_T("SetDllDirectory for %s failed with %d\n"), DBGHELPDLL, GetLastError());  
      
        HMODULE hMod = LoadLibrary(_T("dbghelp.dll"));  
        if (hMod)  
        {  
    #ifdef UNICODE		  
            SI siInitialize = reinterpret_cast<SI>(GetProcAddress(hMod, "SymInitializeW"));  
    #else  
            SI siInitialize = reinterpret_cast<SI>(GetProcAddress(hMod, "SymInitialize"));  
    #endif  
            if (!siInitialize)  
                _tprintf_s(_T("GetProcAddress failed with code %d\n"), GetLastError());  
      
            SGO sgoGetOptions = reinterpret_cast<SGO>(GetProcAddress(hMod, "SymGetOptions"));  
            if (!sgoGetOptions)  
                _tprintf_s(_T("GetProcAddress failed with code %d\n"), GetLastError());  
      
            SSO ssoSetOptions = reinterpret_cast<SSO>(GetProcAddress(hMod, "SymSetOptions"));  
            if (!ssoSetOptions)  
                _tprintf_s(_T("GetProcAddress failed with code %d\n"), GetLastError());  
      
    #ifdef UNICODE  
            SLMX slmxLoadModuleEx = reinterpret_cast<SLMX>(GetProcAddress(hMod, "SymLoadModuleExW"));  
    #else  
            SLMX slmxLoadModuleEx = reinterpret_cast<SLMX>(GetProcAddress(hMod, "SymLoadModuleEx"));  
    #endif  
            if (!slmxLoadModuleEx)  
                _tprintf_s(_T("GetProcAddress failed with code %d\n"), GetLastError());  
      
            if (siInitialize && sgoGetOptions && ssoSetOptions && slmxLoadModuleEx)  
            {  
                HANDLE hProcess = GetCurrentProcess();  
                auto ret = siInitialize(hProcess, NULL, FALSE);  
                if (ret)  
                {  
                    auto opts = sgoGetOptions();  
                    opts |= SYMOPT_DEBUG;  
                    ssoSetOptions(opts);  
      
                    auto base = slmxLoadModuleEx(hProcess, nullptr, szModule, nullptr, 0, 0, nullptr, 0);  
                    if (base)  
                        _tprintf_s(_T("%s load address is %#.16llx"), szModule, base);  
                    else  
                    {  
                        auto err = GetLastError();  
                        if (err == ERROR_SUCCESS)  
                            _tprintf_s(_T("%s already loaded\n"), szModule);  
                        else  
                            _tprintf_s(_T("SymLoadModuleEx failed with code %d\n"), err);  
                    }  
                }  
            }  
      
            FreeLibrary(hMod);  
        }  
        return 0;  
    }  
      
    

    The DLL search path for the Windows SDK version of dbghelp.dll was set with a preprocessor macro -

    194368-dbgpreproc.png

    Debug output captured by Sysinternals DebugView utility -

    194453-dbgview32.png

    0 comments No comments