Почему Windows запрещает доступ к именам некоторых процессов? - PullRequest
0 голосов
/ 13 октября 2018

Я хотел попытаться создать небольшую программу, которая может считывать память других программ и выгружать ее в текстовый файл (если он, очевидно, имеет доступ).Но доступ кажется проблемой прямо передо мной.Сначала я немного попробовал и хотел напечатать список всех процессов, запущенных в настоящее время, но, очевидно, у меня даже нет доступа, чтобы открыть некоторые процессы.Однако, если я открою список в программе, такой как Cheat Engine, он покажет все имена процессов (системный процесс, например, в основном PID 4, если я видел правильно).Теперь я только испортил желаемый уровень доступа при открытии процесса, или Cheat Engine просто использует некоторые трюки или читает имена откуда-то еще?Я пробовал и QueryFullProcessImageName, и GetBaseModuleName, где последний требует PROCESS_VM_READ доступа, поэтому я использовал QueryFullProcessImageName, потому что я пытался минимизировать свой уровень доступа.

main.cpp

#include <cstring>
#include <iostream>
#include <iomanip>
#ifdef _WIN32_WINNT
#undef _WIN32_WINNT
#endif
#define _WIN32_WINNT 0x0600 /* Define so QueryFullProcessImageName can be used */
#include <windows.h>
#include <psapi.h>


using namespace std;


WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR cmdLine, int cmdShow) {
    DWORD processIds[256];  /* Buffer for the process IDs */
    DWORD cbNeeded; /* Space needed from EnumProcesses() to store all IDs */
    /* 
     * I will not check if the space was sufficient or not because this is just a local experiment 
     * and i can insure it is enough space
     */
    if (EnumProcesses(processIds, sizeof(processIds), &cbNeeded) == 0) {
        cout << "Error while enumerating processes(" << GetLastError() << ")" << endl;
        return 0;
    }
    for (unsigned int i = 0; i < cbNeeded / sizeof(DWORD); i++) {
        DWORD nameBufferSize = 128;
        LPSTR processBaseName = new CHAR[128];
        /* Open the process; here is where i get access denied */
        HANDLE openProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, processIds[i]);
        if (openProcess == NULL) {
            if(GetLastError() == 5) strcpy(processBaseName, "<denied>");
            else strcpy(processBaseName, "<unknown>");
        } else if (QueryFullProcessImageName(openProcess, NULL, processBaseName, nameBufferSize) == 0) {
            if(GetLastError() == 5) strcpy(processBaseName, "<denied>");
            else strcpy(processBaseName, "<unknown>");
        }
        cout << "PID: " << setw(6) << left << processIds[i] << "\t" << processBaseName << endl;
        delete processBaseName;
        CloseHandle(openProcess);
    }
    return 0;
}

Ответы [ 2 ]

0 голосов
/ 15 октября 2018

Здесь, где комментируется много полезной информации, чтобы я мог ответить на вопрос сам.Как было сказано, проблема заключалась в том, что у меня никогда не будет достаточных разрешений для открытия защищенных системных процессов.Решение состоит в том, чтобы собрать информацию по-другому.Как прокомментировано, это может быть сделано намного проще с CreateToolhelp32Snapshot, чтобы получить снимок всех текущих запущенных процессов.Затем я могу перебрать их через Process32First, а затем все последующие с Process32Next, а затем просто прочитать PROCESSENTRY32::szExeFile структуры, чтобы получить имя процесса.

Код, который я сейчас использую:

HANDLE processSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (processSnapshot == INVALID_HANDLE_VALUE) {
      std::cout << "Error while taking process snapshot(" << GetLastError() << ")" << std::endl;
      return 0
}
PROCESSENTRY32 process;
process.dwSize = sizeof(PROCESSENTRY32); /* This is neccessary as the Process32First/Next function expects the size of the class in this member before the first call */
if ( ! Process32First(processSnapshot, &process) ) {
      std::cout << "Error while accessing first entry of snapshot(" << GetLastError() << ")" << std::endl;
      return 0;
}
do {
      std::cout << "PID: " << process.th32ProcessID << "\t" << process.szExeFile << std::endl;
} while( Process32Next(processSnapshot, &process) );
if (GetLastError() != ERROR_NO_MORE_FILES) { /*  The Process32Next function throws the ERROR_NO_MORE_FILES error code when there is no more entry to read. If this is not the last error message something went wrong. */
        std::cout << "Error while enumerating processes(" << GetLastError() << ")" << std::endl;
}

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

0 голосов
/ 15 октября 2018

Защищенный процесс - ваша главная причина.Например, вы не можете открыть дескрипторы для csrss.exe, smss.exe или System.Во-вторых, попробуйте включить привилегию отладки SeDebugPriviledge.Затем также запустите от имени администратора, чтобы увидеть, если вы получаете больше процессов.Но вы не можете получить доступ к защищенным процессам, даже с привилегиями отладки.Для этого вам нужен драйвер режима ядра, который использует SeLocateProcessImageFileName или PsGetProcessFileName.

...