Проблемы с открытием процесса с флагами DEBUG
Я пытаюсь открыть процесс с помощью моего отладчика, используя CreateProcess
с DEBUG_PROCESS
а также DEBUG_ONLY_THIS_PROCESS
флаги и процесс открывается, но потом, когда я пытаюсь позвонить SymInitialize
с ручкой, которую я получаю, это не удается.
Это мой код:
#include <windows.h>
#include <stdio.h>
#include <dbghelp.h>
#pragma (lib, "dbghelp.lib");
bool EnablePrivilege(LPCTSTR lpszPrivilegeName, BOOL bEnable)
{
HANDLE hToken;
TOKEN_PRIVILEGES tp;
LUID luid;
bool ret;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY | TOKEN_READ, &hToken))
return FALSE;
if (!LookupPrivilegeValue(NULL, lpszPrivilegeName, &luid))
return FALSE;
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = bEnable ? SE_PRIVILEGE_ENABLED : 0;
ret = AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL);
CloseHandle(hToken);
return ret;
}
void main()
{
EnablePrivilege(SE_DEBUG_NAME, TRUE);
STARTUPINFOA startInfo;
PROCESS_INFORMATION processInfo;
ZeroMemory( &startInfo, sizeof(startInfo) );
startInfo.cb = sizeof(startInfo);
ZeroMemory( &processInfo, sizeof(processInfo) );
DWORD creationFlags = DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS | PROCESS_VM_READ | PROCESS_QUERY_INFORMATION;
const char* comLine = "Some process path and name";
// Start the child process.
if( CreateProcessA( NULL, // No module name (use command line)
(LPSTR)comLine, //argv[1], // Command line
NULL, // Process handle not inheritable
NULL, // Thread handle not inheritable
FALSE, // Set handle inheritance to FALSE
creationFlags, // No creation flags
NULL, // Use parent's environment block
NULL, // Use parent's starting directory
&startInfo, // Pointer to STARTUPINFO structure
&processInfo ) // Pointer to PROCESS_INFORMATION structure
== false )
{
printf("FAIL!");
return;
}
SetLastError(0);
bool ok = SymInitialize(processInfo.hProcess, NULL, true);
int err = GetLastError();
}
Если я вызываю CreateProcess без флагов создания, symInitialize преуспевает.
Что я делаю неправильно?
2 ответа
Ваша ошибка является результатом вызова макроса MAKE_HRESULT как
MAKE_HRESULT(ERROR_SEVERITY_ERROR, FACILITY_NULL, ERROR_INVALID_DATA)
Так что ваш код ошибки не мусор. Документация не говорит, какие данные могут быть недействительными в этом контексте. Я постараюсь увидеть, что именно вызывает проблему.
РЕДАКТИРОВАТЬ:
Этот код работает для меня
#include <windows.h>
#include <stdio.h>
#include <dbghelp.h>
#include <WinError.h>
bool EnablePrivilege(LPCTSTR lpszPrivilegeName, BOOL bEnable)
{
HANDLE hToken;
TOKEN_PRIVILEGES tp;
LUID luid;
bool ret;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY | TOKEN_READ, &hToken))
return FALSE;
if (!LookupPrivilegeValue(NULL, lpszPrivilegeName, &luid))
return FALSE;
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = bEnable ? SE_PRIVILEGE_ENABLED : 0;
ret = AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL);
CloseHandle(hToken);
return ret;
}
void main()
{
EnablePrivilege(SE_DEBUG_NAME, TRUE);
STARTUPINFOA startInfo;
PROCESS_INFORMATION processInfo;
ZeroMemory( &startInfo, sizeof(startInfo) );
startInfo.cb = sizeof(startInfo);
ZeroMemory( &processInfo, sizeof(processInfo) );
DWORD creationFlags = DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS | PROCESS_VM_READ | PROCESS_QUERY_INFORMATION;
const char* comLine = "C:\\Windows\\Notepad.exe";
// Start the child process.
if( CreateProcessA( NULL, // No module name (use command line)
(LPSTR)comLine,// argv[1], // Command line
NULL, // Process handle not inheritable
NULL, // Thread handle not inheritable
FALSE, // Set handle inheritance to FALSE
creationFlags, // No creation flags
NULL, // Use parent's environment block
NULL, // Use parent's starting directory
&startInfo, // Pointer to STARTUPINFO structure
&processInfo ) // Pointer to PROCESS_INFORMATION structure
== false )
{
printf("FAIL!");
return;
}
SetLastError(0);
bool ok = SymInitialize(processInfo.hProcess, NULL, true);
HRESULT err = HRESULT_FROM_WIN32(GetLastError());
}
Я не знаю, почему это не для вас - я использую Windows XP, может быть разница. Для меня SymInitialize возвращает true, а GetLastError возвращает 0x800700cb, что означает только то, что он не нашел переменную evirnment, указывающую на каталог с файлами символов.
Это может быть глупый вопрос, но, возможно, вам не хватает отладочных библиотек в вашей системе? Вы пробовали установить, например. Инструменты отладки для Windows? Я бы порекомендовал вариант "Загрузить средства отладки из Windows SDK" - прочтите описание. Я предполагаю, что каждая программирующая среда разработки установит ее для вас или вы установите ее перед отладкой чего-либо, но всегда лучше проверить.
Когда процесс только что создан с флагом DEBUG_PROCESS, символы не загружаются. Требуется дождаться некоторого LOAD_DLL_DEBUG_EVENT и затем вызвать SymInitialize().