SymLoadModule64 и GetCurrentProcess из C#

Я хочу использовать библиотеку dbghelp, чтобы получить некоторую информацию о типе и программе из файла pdb. Теперь, потому что мне нравится C# гораздо больше, чем C++, я сейчас пытаюсь заставить его работать изнутри C#. В настоящее время я застрял при вызове SymLoadModule64. У меня есть рабочий вызов в C++, выглядит так:

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

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

Однако, пытаясь как-то вызвать это из C#, я продолжаю получать ошибки:

    [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);

в результате загружаемый модуль устанавливается в 0, а Marshal.GetLastWin32Error() возвращает 6 (ERROR_INVALID_HANDLE). Теперь я подумал, что, поскольку это кажется проблемой с дескриптором, я мог бы просто использовать встроенную функцию для его извлечения (чтобы избежать каких-либо ловушек из-за несовместимости с дескриптором C# при извлечении материала тому, что ожидает C++ и т. Д.). Однако пока удалось

Process.GetCurrentProcess().Handle;

всегда возвращает что-то более или менее значимое (1008, 1036, ...), вызов

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

всегда возвращает -1.

Итак: Поскольку я был бы признателен за любые идеи по "основному" вопросу (как я могу заставить SymLoadModule64() работать из C#), я, конечно, очень хотел бы знать также, почему происходит сбой вызова GetCurrentProcess(). Заранее спасибо.

2 ответа

Решение

Дескриптор процесса, который вы передаете в качестве первого параметра SymLoadModule64 может быть произвольным значением, на самом деле оно не обязательно должно быть допустимым дескриптором процесса. Однако для каждого дескриптора процесса, который вы хотите использовать, вы должны сначала инициализировать dbghelp для этого значения, вызвав SymInitialize,

Что касается GetCurrentProcess значение -1 является псевдо-дескриптором, ссылающимся на текущий процесс. Он может использоваться с большинством функций Windows, которые ожидают дескриптор. Обратите внимание, что тот факт, что функция возвращает псевдо-дескриптор, очень хорошо задокументирован.

Для рабочего кода для вашего "основного вопроса" о том, как реализовать использование SymLoadModule64 в C# (ответ отображается в конце) см. http://social.msdn.microsoft.com/Forums/en/netfxtoolsdev/thread/d79f7876-6d37-429f-937c-57797462473a

Также посмотрите этот ТАК вопрос и ответ DbgHelp.dll: вызов SymGetModuleInfo64 из C# - у него есть хороший код, который должен помочь вам начать...

Другие вопросы по тегам