Как запросить запущенный процесс для его списка параметров? (windows, C ++) - PullRequest
5 голосов
/ 29 июня 2011

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

Заранее спасибо!

Ответы [ 4 ]

7 голосов
/ 29 июня 2011

Предполагая, что вы знаете идентификатор процесса, используйте OpenProcess , чтобы получить дескриптор к нему (это требует повышенных привилегий, как указано в документации).Затем используйте NtQueryInformationProcess , чтобы получить подробную информацию о процессе.Используйте параметр ProcessBasicInformation, чтобы получить PEB процесса - он содержит другой указатель структуры, с помощью которого вы можете получить командную строку.

5 голосов
/ 20 февраля 2017

Удаленный впрыск резьбы:

Вы используете удаленное внедрение потока, вызываете GetCommandLine(), затем возвращаете результат IPC. Это может работать в большинстве случаев в Windows XP, но в Windows Vista и более поздних версиях не работает в системных и служебных процессах. Это связано с тем, что CreateRemoteThread работает только с процессами с тем же идентификатором сеанса, что и у вызывающего - в Windows Vista службы и другие системные процессы выполняются в сеансе 0, а пользовательские программы - в сеансах более высокого уровня. Лучший и самый безопасный способ - прочитать структуру, присутствующую в каждом процессе Windows.

Структура PEB:

Блок среды процесса (PEB) обычно хранится в верхних областях памяти процесса, выше 0x7ff00000. Эти регионы также содержат блоки среды потоков (TEB). Адрес PEB различен практически для каждого процесса, поэтому вы не можете просто использовать жестко закодированную константу.

#include <windows.h>
#include <stdio.h>
#include "Winternl.h"

typedef NTSTATUS (NTAPI *_NtQueryInformationProcess)(
    HANDLE ProcessHandle,
    DWORD ProcessInformationClass,
    PVOID ProcessInformation,
    DWORD ProcessInformationLength,
    PDWORD ReturnLength
    );

PVOID GetPebAddress(HANDLE ProcessHandle)
{
    _NtQueryInformationProcess NtQueryInformationProcess =
        (_NtQueryInformationProcess)GetProcAddress(
        GetModuleHandleA("ntdll.dll"), "NtQueryInformationProcess");
    PROCESS_BASIC_INFORMATION pbi;

    NtQueryInformationProcess(ProcessHandle, 0, &pbi, sizeof(pbi), NULL);

    return pbi.PebBaseAddress;
}

int wmain(int argc, WCHAR *argv[])
{
    int pid;
    HANDLE processHandle;
    PVOID pebAddress;
    PVOID rtlUserProcParamsAddress;
    UNICODE_STRING commandLine;
    WCHAR *commandLineContents;

    if (argc < 2)
    {
        printf("Usage: getprocesscommandline [pid]\n");
        return 1;
    }

    pid = _wtoi(argv[1]);

    if ((processHandle = OpenProcess(
        PROCESS_QUERY_INFORMATION | /* required for NtQueryInformationProcess */
        PROCESS_VM_READ, /* required for ReadProcessMemory */
        FALSE, pid)) == 0)
    {
        printf("Could not open process!\n");
        return GetLastError();
    }

    pebAddress = GetPebAddress(processHandle);

    /* get the address of ProcessParameters */
    if (!ReadProcessMemory(processHandle,
            &(((_PEB*) pebAddress)->ProcessParameters),
            &rtlUserProcParamsAddress,
            sizeof(PVOID), NULL))
    {
        printf("Could not read the address of ProcessParameters!\n");
        return GetLastError();
    }

    /* read the CommandLine UNICODE_STRING structure */
    if (!ReadProcessMemory(processHandle,
        &(((_RTL_USER_PROCESS_PARAMETERS*) rtlUserProcParamsAddress)->CommandLine),
        &commandLine, sizeof(commandLine), NULL))
    {
        printf("Could not read CommandLine!\n");
        return GetLastError();
    }

    /* allocate memory to hold the command line */
    commandLineContents = (WCHAR *)malloc(commandLine.Length);

    /* read the command line */
    if (!ReadProcessMemory(processHandle, commandLine.Buffer,
        commandLineContents, commandLine.Length, NULL))
    {
        printf("Could not read the command line string!\n");
        return GetLastError();
    }

    /* print it */
    /* the length specifier is in characters, but commandLine.Length is in bytes */
    /* a WCHAR is 2 bytes */
    printf("%.*S\n", commandLine.Length / 2, commandLineContents);
    CloseHandle(processHandle);
    free(commandLineContents);

    return 0;
}

Для более подробной информации, пожалуйста, посмотрите Получить командную строку процесса

РЕДАКТИРОВАТЬ (Дополнительная информация):

Первый автор сказал:

CreateRemoteThread работает только для процессов с тем же идентификатором сеанса, что и вызывающая сторона - в Windows Vista запускаются сервисы и другие системные процессы в сеансе 0, в то время как пользовательские программы работают в старших сеансах. Самый лучший и безопасный способ - прочитать структуру, присутствующую в каждом процессе Windows.

То же самое с OpenProcess , вы не можете открыть процесс, который является службой или процесс, открытый SYSTEM или LOCAL SERVICE NETWORK SERVICE , если ваша программа запускается пользователем (даже администратором).

Если ваша программа является службой, она, вероятно, уже запущена локальной системной учетной записью , так что никаких проблем. Но если нет, решение состоит в том, чтобы запустить его с psexec :

  1. Загрузите PSEXEC и разархивируйте в какую-нибудь папку.
  2. Откройте привилегированное приглашение CMD от имени администратора.
  3. Перейдите в папку, в которую вы распаковали PSEXEC.EXE
  4. Прогон: PSEXEC -i -s -d CMD
  5. Откроется новая подсказка CMD.
  6. Введите следующее в новом приглашении CMD, чтобы доказать, кто вы: WHOAMI

Вы должны увидеть, что вы SYSTEM , теперь вы можете запустить свою программу и просмотреть командную строку для всех процессов.

2 голосов
/ 29 июня 2011

Вы не можете достоверно получить эту информацию. Существуют различные приемы, чтобы попытаться получить его, но нет никакой гарантии, что целевой процесс еще не исказил этот раздел памяти. Рэймонд Чен некоторое время назад обсуждал это на Старом Новом .

2 голосов
/ 29 июня 2011

Ну, вы могли бы внедрить dll в адресное пространство внешнего процесса и затем вызвать GetCommandLine .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...