Отказано в доступе к EnumProcessModules - C++

Я пытаюсь перечислить все модули для определенного процесса, но получаю сообщение «Отказано в доступе», даже когда я устанавливаю привилегии токена. Вот код:

#include <cstdlib>
#include <iostream>
#include <windows.h>
#include <psapi.h>
#include <Tlhelp32.h>
using namespace std;
#pragma comment(lib, "cmcfg32.lib")

BOOL SetPrivilege(HANDLE hToken, LPCTSTR lpszPrivilege, BOOL bEnablePrivilege) 
{
    TOKEN_PRIVILEGES tp;
    LUID luid;
    if (!LookupPrivilegeValue(NULL, lpszPrivilege, &luid))
    {
        char buf[256];
        FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, 255, NULL);
        cout << "LookupPrivilegeValue error: " << buf;   
        return FALSE; 
    }
    tp.PrivilegeCount = 1;
    tp.Privileges[0].Luid = luid;
    if (bEnablePrivilege) { tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; }
    else { tp.Privileges[0].Attributes = 0; }

    if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES) NULL, (PDWORD)NULL))
    { 
        char buf[256];
        FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, 255, NULL);
        cout << "AdjustTokenPrivileges error: " << buf;   
        return FALSE; 
    } 
    if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
    {
        printf("The token does not have the specified privilege. \n");
        return FALSE;
    } 
    return TRUE;
}

int GetPID(char pname[])
{
    PROCESSENTRY32 pEntry;
    HANDLE hSnapshot = NULL;
    pEntry.dwSize = sizeof(PROCESSENTRY32);
    hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 
    Process32First(hSnapshot,&pEntry);
    do { if(strcmp(pEntry.szExeFile, pname) == 0) { return pEntry.th32ProcessID; } } while(Process32Next(hSnapshot,&pEntry));
    return 0;
}

int main()
{
    HANDLE currentToken;
    OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &currentToken);
    if (!SetPrivilege(currentToken, SE_DEBUG_NAME, TRUE))
    {
        MessageBox(0, "Unable to adjust privileges", "Error", MB_ICONERROR);
    }
    DWORD ID = GetPID("test.exe");
    HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, ID);
    if(!hProcess)
    {
        MessageBox(0, "Process not found", "Error", MB_ICONERROR);
    }
    else
    {
        HMODULE hMods[2048];
        DWORD cbNeeded;
        if(EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded))
        {
            for (unsigned int i = 0; i < (cbNeeded/sizeof(HMODULE)); i++)
            {
                TCHAR szModName[MAX_PATH];
                if (GetModuleFileNameEx(hProcess, hMods[i], szModName, sizeof(szModName)/sizeof(TCHAR)))
                {
                    cout << "DLL: " << szModName << " Handle: " << hMods[i] << endl;
                }
            }
        }
        else
        {
            char buf[256];
            FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, 255, NULL);
            cout << "Error: " << buf;
        }    
        system("pause");
    }
    CloseHandle(hProcess);
    return 0;
}

Обратите внимание, что я могу перечислить модули любого другого процесса, но не могу указать конкретный. Оба процесса выполняются с одинаковыми учетными данными пользователя.

Можете ли вы сказать мне, если я делаю что-то не так?


person Douglas Bissoli    schedule 22.07.2011    source источник
comment
Что это за процесс? Возможно, у него есть компонент драйвера, защищающий его.   -  person Luke    schedule 22.07.2011


Ответы (1)


Используйте Process Explorer, чтобы просмотреть безопасность интересующих вас объектов ядра. целевой процесс установил информацию о своем владельце/DACL таким образом, что он запрещает READ для других процессов. Антивирусные программы, службы, файловая система/драйвер ядра являются такими процессами, которые запрещают такие действия.

И что еще более важно: это зависит от уровня привилегий/администрирования/кольца вашего собственного процесса.

ДОБАВЛЕНО: Привилегии применяются не напрямую к объектам, а к системе в целом. Попробуйте открыть с помощью TOKEN_ALL_ACCESS и посмотрите, получится ли.

person Ajay    schedule 22.07.2011
comment
Я попытался открыть с помощью TOKEN_ALL_ACCESS, но безуспешно. Я также проверил привилегии процессов, и оба процесса с включенным SeDebugPrivilege. Это проблема? РЕДАКТИРОВАТЬ: я отключил SeDebugPrivilege в процессе, к которому я пытаюсь получить доступ, и все еще безуспешно. - person Douglas Bissoli; 22.07.2011
comment
Я уже упоминал, что некоторые объекты ядра могут быть явно защищены, чтобы к ним вообще нельзя было получить доступ. - person Ajay; 22.07.2011