繁体   English   中英

如何查询正在运行的进程的参数列表? (Windows,C++)

[英]How to query a running process for it's parameters list? (windows, C++)

对于给定的 windows 进程,我想知道它是用什么命令行参数启动的。 例如,windows 任务管理器能够显示这一点。

先感谢您!

假设您知道进程 ID,请使用OpenProcess获取它的句柄(这需要提升权限,如文档中所述)。 然后使用NtQueryInformationProcess获取详细的进程信息。 使用ProcessBasicInformation选项获取进程的PEB - 它包含另一个结构指针,通过它可以获取命令行。

远程线程注入:

您使用远程线程注入,调用GetCommandLine() ,然后 IPC 返回结果。 这可能在 Windows XP 上大部分时间都有效,但在 Windows Vista 或更高版本上,它不适用于系统和服务进程。 这是因为CreateRemoteThread仅适用于与调用者具有相同 session ID 的进程 - 在 Windows Vista 中,服务和其他系统进程在 session 中运行,而用户程序在更高的会话中运行。 最好和最安全的方法是读取每个 Windows 进程中存在的结构。

PEB结构:

进程环境块(PEB)通常存储在进程 memory 的高区域,高于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仅适用于与调用者在同一 session ID 中的进程 - 在 Windows Vista 中,服务和其他系统进程在 session 0 中运行,而用户程序在更高的会话中运行。 最好和最安全的方法是读取每个 Windows 进程中存在的结构。

这与OpenProcess相同,如果您由用户(甚至管理员)运行程序,则无法打开作为服务的进程或由SYSTEMLOCAL SERVICENETWORK SERVICE打开的进程。

如果您的程序是服务,它可能已经由本地系统帐户运行,所以没问题。 但如果没有,一个解决方案是使用psexec启动它:

  1. 下载PSEXEC并解压缩到某个文件夹。
  2. 以管理员身份打开提升的 CMD 提示符。
  3. 导航到解压 PSEXEC.EXE 的文件夹
  4. 运行: PSEXEC -i -s -d CMD
  5. 您将打开一个新的 CMD 提示符。
  6. 在新的 CMD 提示符中键入以下内容以证明您是谁: WHOAMI

您应该看到您是SYSTEM ,现在您可以启动您的程序并查看所有进程的命令行。

您无法可靠地获取该信息。 有各种技巧可以尝试检索它,但不能保证目标进程尚未破坏 memory 的该部分。 Raymond Chen 不久前在The Old New Thing上讨论过这个问题。

好吧,您可以将 dll注入外部进程地址空间,然后调用GetCommandLine

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM