Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/128.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何为它查询正在运行的进程';s参数列表?(windows,C+;+;)_C++_Winapi - Fatal编程技术网

C++ 如何为它查询正在运行的进程';s参数列表?(windows,C+;+;)

C++ 如何为它查询正在运行的进程';s参数列表?(windows,C+;+;),c++,winapi,C++,Winapi,对于给定的windows进程,我想知道它是用什么命令行参数启动的。例如,windows任务管理器可以显示这一点 提前谢谢你 您可以进入外部进程地址空间,然后调用。假设您知道进程ID,使用获取句柄(这需要提升权限,如文档中所述)。然后使用获取详细的流程信息。使用ProcessBasicInformation选项获取进程的属性-它包含另一个结构指针,通过它可以设置命令行。您无法可靠地获取该信息。有各种各样的技巧来尝试和检索它,但不能保证目标进程没有损坏该部分内存。Raymond Chen不久前讨论过

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


提前谢谢你

您可以进入外部进程地址空间,然后调用。

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

您无法可靠地获取该信息。有各种各样的技巧来尝试和检索它,但不能保证目标进程没有损坏该部分内存。Raymond Chen不久前讨论过这个问题。

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

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;
}
#包括
#包括
#包括“Winternl.h”
typedef NTSTATUS(NTAPI*\u NtQueryInformationProcess)(
句柄进程句柄,
德沃德级,
PVOID进程信息,
德沃德长度,
PDWORD返回长度
);
PVOID GetPebadAddress(句柄进程句柄)
{
_NtQueryInformationProcess NtQueryInformationProcess=
(\n查询信息处理)GetProcAddress(
GetModuleHandleA(“ntdll.dll”),“NtQueryInformationProcess”);
处理基本信息pbi;
NtQueryInformationProcess(ProcessHandle,0,&pbi,sizeof(pbi),NULL);
返回pbi.PebBaseAddress;
}
int wmain(int argc,WCHAR*argv[])
{
int-pid;
句柄进程句柄;
pvoidpebaddress;
PVOID-rtluserproc-paramsadress;
UNICODE_字符串命令行;
WCHAR*命令行内容;
如果(argc<2)
{
printf(“用法:getprocesscommandline[pid]\n”);
返回1;
}
pid=_wtoi(argv[1]);
如果((processHandle=OpenProcess(
NtQueryInformationProcess所需的PROCESS_QUERY_信息|/**/
PROCESS\u VM\u READ,/*是ReadProcessMemory所必需的*/
FALSE,pid))==0)
{
printf(“无法打开进程!\n”);
返回GetLastError();
}
pebAddress=GetPebAddress(processHandle);
/*获取ProcessParameters的地址*/
如果(!ReadProcessMemory(processHandle,
&(((_PEB*)pebAddress)->工艺参数,
&rtlUserProcParamsAddress,
sizeof(PVOID,NULL))
{
printf(“无法读取ProcessParameters的地址!\n”);
返回GetLastError();
}
/*读取命令行UNICODE_字符串结构*/
如果(!ReadProcessMemory(processHandle,
&((((_RTL_USER_PROCESS_PARAMETERS*)rtlUserProcParamsAddress)->命令行),
&命令行,sizeof(命令行,NULL))
{
printf(“无法读取命令行!\n”);
返回GetLastError();
}
/*分配内存以保存命令行*/
commandLineContents=(WCHAR*)malloc(commandLine.Length);
/*阅读命令行*/
如果(!ReadProcessMemory(processHandle,commandLine.Buffer,
commandLineContents,commandLine.Length,NULL)
{
printf(“无法读取命令行字符串!\n”);
返回GetLastError();
}
/*打印出来*/
/*长度说明符以字符为单位,但命令行。长度以字节为单位*/
/*一个WCHAR是2个字节*/
printf(“%.*S\n”,commandLine.Length/2,commandLineContents);
关闭手柄(processHandle);
免费(commandLineContents);
返回0;
}
有关更多详细信息,请查看

编辑(其他信息): 第一作者说:

CreateRemoteThread
仅适用于与相同会话ID的进程 调用方–在Windows Vista中,服务和其他系统进程运行 在会话0中,而用户程序在更高的会话中运行。最好和最安全的方法是读取每个Windows进程中存在的结构

与此相同,如果您是由用户(甚至是管理员)运行程序,则无法打开作为服务或由系统、本地服务或网络服务打开的进程的进程

如果您的程序是服务,它可能已经由本地系统帐户运行,所以没有问题。 但如果不是这样,解决方案是通过以下方式启动:

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

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

    似乎正是我要寻找的。谢谢。“这些API和数据结构可能会在不同的Windows版本之间发生变化。为了保持应用程序的兼容性,请避免使用这些API和数据结构。”嗯,不像我希望的那么简单。是的,但是这些文档已经存在多年了,我