根据进程名 获取该进程的启动参数

hedengxiang 2012-02-28 11:02:39
如果一个进程已经启动,而且我们知道这个进程名,我们能否知道这个进程的启动参数呢?

例如:
程序A使用 ShellExecuteEx启动程序B,并传递一个启动参数(如“-check”),已知程序B的进程名是B.exe

这时程序C该如何获取到程序B的启动参数(“-check”)?
...全文
743 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
dbdoing 2014-04-17
  • 打赏
  • 举报
回复
引用 11 楼 zwfgdlc 的回复:
可以直接在远程进程执行GetCommandLine()就行了. 我试了下可以.

int WINAPI GetProcessCommandLine(DWORD dwPID, LPTSTR lpszCommandLine, DWORD dwByteOfSize)
{
	HANDLE hProcess = ::OpenProcess(PROCESS_CREATE_THREAD|PROCESS_VM_OPERATION|PROCESS_VM_WRITE|PROCESS_VM_READ, FALSE, dwPID);
	
	if (!hProcess)
	{
		return 0;
	}

	DWORD dwThreadId = 0;
	DWORD dwExitCode = 0;
	DWORD dwReaded = 0;
	HANDLE hThread  = ::CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)GetCommandLine, NULL, 0, &dwThreadId);

	if (hThread)
	{
		::WaitForSingleObject(hThread, INFINITE);
		::GetExitCodeThread(hThread, &dwExitCode);
		::ReadProcessMemory(hProcess, (LPCVOID)dwExitCode, lpszCommandLine, dwByteOfSize, &dwReaded);
	}

	return dwReaded;
}

int _tmain(int argc, _TCHAR* argv[])
{
	TCHAR szBuffer[256] = {0};
	GetProcessCommandLine(628, szBuffer, sizeof(szBuffer)); //628改成你要获取的进程PID,
	return 0;
}
牛啊,给力,也解决了我的问题。十分感谢!
饿半肚 2013-06-19
  • 打赏
  • 举报
回复
引用 11 楼 zwfgdlc 的回复:
可以直接在远程进程执行GetCommandLine()就行了. 我试了下可以.

int WINAPI GetProcessCommandLine(DWORD dwPID, LPTSTR lpszCommandLine, DWORD dwByteOfSize)
{
	HANDLE hProcess = ::OpenProcess(PROCESS_CREATE_THREAD|PROCESS_VM_OPERATION|PROCESS_VM_WRITE|PROCESS_VM_READ, FALSE, dwPID);
	
	if (!hProcess)
	{
		return 0;
	}

	DWORD dwThreadId = 0;
	DWORD dwExitCode = 0;
	DWORD dwReaded = 0;
	HANDLE hThread  = ::CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)GetCommandLine, NULL, 0, &dwThreadId);

	if (hThread)
	{
		::WaitForSingleObject(hThread, INFINITE);
		::GetExitCodeThread(hThread, &dwExitCode);
		::ReadProcessMemory(hProcess, (LPCVOID)dwExitCode, lpszCommandLine, dwByteOfSize, &dwReaded);
	}

	return dwReaded;
}

int _tmain(int argc, _TCHAR* argv[])
{
	TCHAR szBuffer[256] = {0};
	GetProcessCommandLine(628, szBuffer, sizeof(szBuffer)); //628改成你要获取的进程PID,
	return 0;
}
好代码!帮了我大忙啊!多谢!
  • 打赏
  • 举报
回复
看过不少列宁回答的帖子,觉得列宁同志对windows很厉害
这个我倒是做过,但是根本不记得了,回头去看了下程序,里面当初是这么做的
就像列宁说的那样,应该是可以的

DWORD dwRet = -1;
DWORD dwAddr = *(DWORD*)((DWORD)GetCommandLine + 1); // The 2nd DWORD is the address I need
DWORD dwRead = 0;
if(ReadProcessMemory(hProc, (LPVOID)dwAddr, &dwAddr, sizeof(DWORD), &dwRead) && ReadProcessMemory(hProc, (LPVOID)dwAddr, szParam, 250, &dwRead))
bGetName = TRUE;
CloseHandle(hProc);

知道B的进程名,就先遍历进程,找到那个进程呗,我上面的进程句柄就是hProc
Lactoferrin 2012-02-28
  • 打赏
  • 举报
回复
用CreateToolHelp32Snapshot列举进程,然后比较
hedengxiang 2012-02-28
  • 打赏
  • 举报
回复
谢谢各位
有可能A B程序都不是自己写的
而我们仅仅知道B的进程名,这时该如何获取呢?
Lactoferrin 2012-02-28
  • 打赏
  • 举报
回复
先读(char*)GetCommandLine+1
再读这个地方的
结果就是字符串的地址
于是再读一次
gameslq 2012-02-28
  • 打赏
  • 举报
回复
[Quote=引用楼主 hedengxiang2011 的回复:]
如果一个进程已经启动,而且我们知道这个进程名,我们能否知道这个进程的启动参数呢?

例如:
程序A使用 ShellExecuteEx启动程序B,并传递一个启动参数(如“-check”),已知程序B的进程名是B.exe

这时程序C该如何获取到程序B的启动参数(“-check”)?
[/Quote]
按照你的想法,程序c可以直接和程序a通信,从程序a哪里获得程序b的启动参数
1楼说的也可以
oldm4n 2012-02-28
  • 打赏
  • 举报
回复
用 CreateRemoteThread 在目标进程地址空间加载自己写的dll,在dll里用GetCommandLine API 获取,然后再送出来
hedengxiang 2012-02-28
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 year2002 的回复:]

HANDLE hProc = OpenProcess (PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, FALSE, pe.th32ProcessID);

if(!ReadProcessMemory(hProc, (LPVOID)dwAddr, &dwAddr, sizeof(DWORD), &dwRead))
{
dwRet =……
[/Quote]

试了一下,还是不行,不过也非常感谢你的热心回答,谢谢!
hedengxiang 2012-02-28
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 zwfgdlc 的回复:]

可以直接在远程进程执行GetCommandLine()就行了.
我试了下可以.

C/C++ code

int WINAPI GetProcessCommandLine(DWORD dwPID, LPTSTR lpszCommandLine, DWORD dwByteOfSize)
{
HANDLE hProcess = ::OpenProcess(PROCESS_CREATE……
[/Quote]

嗯,这个可以。谢谢!
hedengxiang 2012-02-28
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 zwfgdlc 的回复:]

可以直接在远程进程执行GetCommandLine()就行了.
我试了下可以.

C/C++ code

int WINAPI GetProcessCommandLine(DWORD dwPID, LPTSTR lpszCommandLine, DWORD dwByteOfSize)
{
HANDLE hProcess = ::OpenProcess(PROCESS_CREATE……
[/Quote]

嗯,这个可以。谢谢!
zwfgdlc 2012-02-28
  • 打赏
  • 举报
回复
可以直接在远程进程执行GetCommandLine()就行了.
我试了下可以.


int WINAPI GetProcessCommandLine(DWORD dwPID, LPTSTR lpszCommandLine, DWORD dwByteOfSize)
{
HANDLE hProcess = ::OpenProcess(PROCESS_CREATE_THREAD|PROCESS_VM_OPERATION|PROCESS_VM_WRITE|PROCESS_VM_READ, FALSE, dwPID);

if (!hProcess)
{
return 0;
}

DWORD dwThreadId = 0;
DWORD dwExitCode = 0;
DWORD dwReaded = 0;
HANDLE hThread = ::CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)GetCommandLine, NULL, 0, &dwThreadId);

if (hThread)
{
::WaitForSingleObject(hThread, INFINITE);
::GetExitCodeThread(hThread, &dwExitCode);
::ReadProcessMemory(hProcess, (LPCVOID)dwExitCode, lpszCommandLine, dwByteOfSize, &dwReaded);
}

return dwReaded;
}

int _tmain(int argc, _TCHAR* argv[])
{
TCHAR szBuffer[256] = {0};
GetProcessCommandLine(628, szBuffer, sizeof(szBuffer)); //628改成你要获取的进程PID,
return 0;
}

  • 打赏
  • 举报
回复
HANDLE hProc = OpenProcess (PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, FALSE, pe.th32ProcessID);

if(!ReadProcessMemory(hProc, (LPVOID)dwAddr, &dwAddr, sizeof(DWORD), &dwRead))
{
dwRet = GetLastError();//返回ERROR_NOACCESS 998L
return "";
}
if(!ReadProcessMemory(hProc, (LPVOID)dwAddr, szParam, 250, &dwRead))
{
dwRet = GetLastError();
return "";
}
试试看
hedengxiang 2012-02-28
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 year2002 的回复:]

是不是应该从进程快照里面取到进程ID再用OpenProcess指定访问权限来获取实际进程句柄
[/Quote]
能麻烦你帮我改下代码吗?我是个新手。。。谢谢!
  • 打赏
  • 举报
回复
是不是应该从进程快照里面取到进程ID再用OpenProcess指定访问权限来获取实际进程句柄
hedengxiang 2012-02-28
  • 打赏
  • 举报
回复
谢谢,我这段代码又问题吗?
大伙帮我看看撒~~


CString GetCmdLineByProcessName(CString csProcessName)
{
CString strCmdLine;
PROCESSENTRY32 pe;
HANDLE hSnapshot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
pe.dwSize=sizeof(PROCESSENTRY32);
if(!Process32First(hSnapshot,&pe))
return strCmdLine;
while(1)
{
pe.dwSize=sizeof(PROCESSENTRY32);
if(Process32Next(hSnapshot,&pe)==FALSE)
break;
if(csProcessName.CompareNoCase(pe.szExeFile) ==0 )
{
DWORD dwRet = -1;
DWORD dwAddr = *(DWORD*)((DWORD)GetCommandLine + 1); // The 2nd DWORD is the address I need
DWORD dwRead = 0;
char szParam[250];
if(!ReadProcessMemory(hSnapshot, (LPVOID)dwAddr, &dwAddr, sizeof(DWORD), &dwRead))
{
dwRet = GetLastError();//返回ERROR_NOACCESS 998L
return "";
}
if(!ReadProcessMemory(hSnapshot, (LPVOID)dwAddr, szParam, 250, &dwRead))
{
dwRet = GetLastError();
return "";
}
strCmdLine = szParam;
CloseHandle(hSnapshot);
return strCmdLine;
}
}
CloseHandle(hSnapshot);
return strCmdLine;
}


第一次调用ReadProcessMemory的时候就失败了,错误代码是:ERROR_NOACCESS 998L

15,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧