Search code examples
c#c++dbghelp

SymLoadModule64 and GetCurrentProcess from C#


I want to use the dbghelp library to get some type and program information from a pdb file. Now, because I like C# much more than C++, I'm currently trying to get it working from within C#. I'm currently stuck at a call to SymLoadModule64. I've got a working call in C++, looking like this:

const TCHAR* pModName = argv[1]; 
HANDLE currentProcHandle = GetCurrentProcess();

DWORD64 ModBase = ::SymLoadModule64 ( 
            currentProcHandle,
            NULL,
            pModName,
            NULL,
            0, 
            0);

However, when trying to somehow call that from C#, I keep getting errors:

    [DllImport("dbghelp.dll", SetLastError = true)]
    public static extern ulong SymLoadModule64(IntPtr hProcess, IntPtr hFile,
    string ImageName, string ModuleName,
    ulong BaseOfDll, uint SizeOfDll);

[...]

            var loadedModule = SymLoadModule64(
                currentProcHandle,
                System.IntPtr.Zero,
                "C:\\Path\\To\\Executable.exe",
                string.Empty,
                0,
                0);

results in loadedModule being set to 0 and Marshal.GetLastWin32Error() returning 6 (ERROR_INVALID_HANDLE). Now, I thought that as it seems to be a problem with the handle, I could just use the native function for retrieving it (to avoid any pitfalls due to incompatibilities from c# handle retrieving stuff to what c++ expects etc.). However, while the managed

Process.GetCurrentProcess().Handle;

always returns something more or less meaningful (1008, 1036, ...), a call to

[DllImport("kernel32.dll")]
static extern IntPtr GetCurrentProcess();
GetCurrentProcess();

always returns -1.

So: As I'd appreciate any ideas on the "major" question (how can I get the SymLoadModule64() working from C#), I'd of course really like to know as well why the call to the GetCurrentProcess() fails. Thanks in advance.


Solution

  • The process handle that you pass as the first parameter to SymLoadModule64 can be an arbitrary value, it does not actually have to be a valid handle to a process. However, for every process handle you want to use, you must first initialize dbghelp for that value by calling SymInitialize.

    As for GetCurrentProcess, the value -1 is a pseudo-handle referring to the current process. It can be used with most Windows functions that expect a handle. Note that the fact that the function returns the pseudo-handle is very well documented.