C++ 如何为它查询正在运行的进程';s参数列表?(windows,C+;+;)
对于给定的windows进程,我想知道它是用什么命令行参数启动的。例如,windows任务管理器可以显示这一点C++ 如何为它查询正在运行的进程';s参数列表?(windows,C+;+;),c++,winapi,C++,Winapi,对于给定的windows进程,我想知道它是用什么命令行参数启动的。例如,windows任务管理器可以显示这一点 提前谢谢你 您可以进入外部进程地址空间,然后调用。假设您知道进程ID,使用获取句柄(这需要提升权限,如文档中所述)。然后使用获取详细的流程信息。使用ProcessBasicInformation选项获取进程的属性-它包含另一个结构指针,通过它可以设置命令行。您无法可靠地获取该信息。有各种各样的技巧来尝试和检索它,但不能保证目标进程没有损坏该部分内存。Raymond Chen不久前讨论过
提前谢谢你 您可以进入外部进程地址空间,然后调用。假设您知道进程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进程中存在的结构
与此相同,如果您是由用户(甚至是管理员)运行程序,则无法打开作为服务或由系统、本地服务或网络服务打开的进程的进程
如果您的程序是服务,它可能已经由本地系统帐户运行,所以没有问题。
但如果不是这样,解决方案是通过以下方式启动:
PSEXEC-i-s-d CMD
WHOAMI
您应该看到您是一个系统,现在您可以启动程序并查看所有进程的命令行。似乎正是我要寻找的。谢谢。“这些API和数据结构可能会在不同的Windows版本之间发生变化。为了保持应用程序的兼容性,请避免使用这些API和数据结构。”嗯,不像我希望的那么简单。是的,但是这些文档已经存在多年了,我