Все, что я смог найти в отношении перехода к соответствующим привилегиям для моих нужд, согласуется с моими нынешними методами, но проблема существует. Я надеюсь, что у кого-то есть опыт работы с внутренними компонентами Windows Vista / Windows 7, который может пролить свет в темноте. Я уверен, что это будет долго, но, пожалуйста, потерпите меня.
Контекст
Я работаю над приложением, которое требует доступа к памяти других процессов на текущем компьютере. Это, очевидно, требует прав администратора. Это также требует SeDebugPrivilege
(нет, это не ошибочное написание SetDebugPrivilege
), которое, как я считаю, я получаю правильно, хотя я сомневаюсь, что дополнительные привилегии не нужны и, следовательно, причина моих проблем. До сих пор код успешно работал во всех версиях Windows XP, а также в моей тестовой 64-битной среде Vista и Windows 7.
Процесс
- Программа будет Всегда запускаться с правами администратора. Это можно предположить на протяжении всего этого поста.
- Эскалация
Access Token
текущего процесса для включения SeDebugPrivilege
прав.
- Использование
EnumProcesses
для создания списка текущих PID в системе
- Открытие ручки с помощью
OpenProcess
с PROCESS_ALL_ACCESS
правами доступа
- Использование
ReadProcessMemory
для чтения памяти другого процесса.
Проблема:
Во время разработки и моего личного тестирования все работало нормально (включая Windows XP 32 и 64, Windows Vista 32 и Windows 7 x64). Однако во время тестового развертывания на компьютерах Windows Vista (32-разрядной) и Windows 7 (64-разрядной) коллеги, похоже, возникла проблема с привилегиями / правами: OpenProcess
завершился с ошибкой общая Access Denied
ошибка. Это происходит как при работе с правами ограниченного пользователя (как и следовало ожидать), так и при явном запуске от имени администратора (щелкните правой кнопкой мыши → Запуск от имени администратора и при запуске из командной строки уровня администратора).
Однако эта проблема не воспроизводилась для меня в моей тестовой среде. Я был свидетелем проблемы из первых рук, поэтому я верю, что проблема существует. Единственное различие, которое я могу различить между фактической средой и моей тестовой средой, заключается в том, что ошибка фактическая возникает при использовании учетной записи администратора домена в приглашении UAC, тогда как мои тесты (которые работают без ошибок) используют учетная запись локального администратора в приглашении UAC.
Похоже, что используемые учетные данные позволяют UAC «работать от имени администратора», процесс все еще не получает правильных прав, чтобы иметь возможность OpenProcess
в другом процессе. Я недостаточно знаком с внутренними компонентами Vista / Windows 7, чтобы знать, что это может быть, и я надеюсь, что кто-то имеет представление о том, что может быть причиной.
Kicker
Лицо, сообщившее об этой ошибке, и окружение которого может регулярно воспроизводить эту ошибку, имеет небольшое приложение с именем RunWithDebugEnabled
, которое представляет собой небольшую программу начальной загрузки, которая, как представляется, повышает свои собственные права и затем запускает исполняемый файл. перешел к нему (таким образом наследуя возросшие привилегии). При запуске с этой программой, используя те же учетные данные Администратора домена в приглашении UAC, программа работает правильно и может успешно вызывать OpenProcess
и работает как задумано.
Так что это определенно проблема с получением правильных привилегий, и известно, что учетная запись администратора домена является учетной записью администратора, которая должна иметь доступ к правильным правам. (Очевидно, что получить этот исходный код было бы здорово, но я бы не был здесь, если бы это было возможно).
Примечания
Как отмечено, ошибки, о которых сообщают неудачные попытки OpenProcess
, равны Access Denied
. Согласно документации MSDN OpenProcess
:
Если вызывающая сторона включила привилегию SeDebugPrivilege, запрошенный доступ предоставляется независимо от содержимого дескриптора безопасности.
Это наводит меня на мысль, что, возможно, существует проблема в этих условиях либо с (1) получением SeDebugPrivileges
, либо (2) требованием других привилегий, которые не были упомянуты в какой-либо документации MSDN, и которые могут различаться в домене Учетная запись администратора и учетная запись локального администратора
Пример кода:
void sample()
{
/////////////////////////////////////////////////////////
// Note: Enabling SeDebugPrivilege adapted from sample
// MSDN @ http://msdn.microsoft.com/en-us/library/aa446619%28VS.85%29.aspx
// Enable SeDebugPrivilege
HANDLE hToken = NULL;
TOKEN_PRIVILEGES tokenPriv;
LUID luidDebug;
if(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken) != FALSE)
{
if(LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luidDebug) != FALSE)
{
tokenPriv.PrivilegeCount = 1;
tokenPriv.Privileges[0].Luid = luidDebug;
tokenPriv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if(AdjustTokenPrivileges(hToken, FALSE, &tokenPriv, 0, NULL, NULL) != FALSE)
{
// Always successful, even in the cases which lead to OpenProcess failure
cout << "SUCCESSFULLY CHANGED TOKEN PRIVILEGES" << endl;
}
else
{
cout << "FAILED TO CHANGE TOKEN PRIVILEGES, CODE: " << GetLastError() << endl;
}
}
}
CloseHandle(hToken);
// Enable SeDebugPrivilege
/////////////////////////////////////////////////////////
vector<DWORD> pidList = getPIDs(); // Method that simply enumerates all current process IDs
/////////////////////////////////////////////////////////
// Attempt to open processes
for(int i = 0; i < pidList.size(); ++i)
{
HANDLE hProcess = NULL;
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pidList[i]);
if(hProcess == NULL)
{
// Error is occurring here under the given conditions
cout << "Error opening process PID(" << pidList[i] << "): " << GetLastError() << endl;
}
CloseHandle(hProcess);
}
// Attempt to open processes
/////////////////////////////////////////////////////////
}
Спасибо!
Если у кого-то есть представление о возможных разрешениях, привилегиях, правах и т. Д., Которые мне могут не хватать для правильного открытия другого процесса (при условии, что исполняемый файл был правильно настроен как «Запуск от имени администратора») в Windows Vista и Windows 7 под Вышеуказанные условия были бы весьма признательны.
Я бы не был здесь, если бы не был в тупике, но я надеюсь, что опыт и знания группы снова будут яркими. Я благодарю вас за то, что вы нашли время прочитать эту стену текста. Мы ценим только добрые намерения, спасибо за то, что вы такой тип людей, который делает переполнение стека таким полезным для всех!