如何以标准用户(XP/Server 2003及以下版本)获取所有正在运行的进程的映像路径?
我试图获得系统中所有正在运行的进程的完整路径,作为没有Windows XP/Server 2003管理权限的标准用户。获取所有正在运行的进程和句柄的列表并不是问题(Toolhelp“Process32First “/ Native API”NtQuerySystemInformation“/ PsApi”EnumProcesses“)。我的问题是这些调用不会返回正确的进程句柄,而是某种我首先必须传递给“OpenProcess”的句柄才能获得适当的进程句柄,然后我可以使用它来查询完整的映像路径(通过调用“ GetProcessImageFileName“或一些低级别的函数)。但是,对于未由当前用户启动的进程,如果我不是管理员,则“OpenProcess”会失败。如何以标准用户(XP/Server 2003及以下版本)获取所有正在运行的进程的映像路径?
任何人都可以指出我如何检索这些信息的权利方向吗? Process Hacker和Process Explorer能够做到,所以它应该是可能的。我知道Process Hacker的源代码是可用的,但据我了解,它使用某种驱动程序来查询正在运行的进程。
更正:正如David Heffernan在他的回答中指出的那样,Process Explorer和Process Hacker在非管理员用户启动时,不会在Windows XP上显示完整映像路径。
这里的(Delphi编写的)请求的代码:
function GetProcessDetails (const th32ProcessID: THandle) : String;
var
szImageFileName : array [0..MAX_PATH] of Char;
hProcess : THandle;
begin
hProcess := OpenProcess (PROCESS_QUERY_INFORMATION or PROCESS_VM_READ,
false, th32ProcessID);
if (hProcess = 0) then
exit;
if (GetProcessImageFileName (hProcess, @szImageFileName [0],
MAX_PATH) > 0) then
Result := szImageFileName;
CloseHandle (hProcess);
end; { GetProcessDetails }
这里是一个使用 “Process32First/Process32Next” 检索过程信息的功能:
procedure FillProcessListToolHelp;
var
hSnapShot : THandle;
PE : TProcessEntry32;
sImageFileName : String;
begin
hSnapShot := CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0);
PE.dwSize := SizeOf (TProcessEntry32);
if (Process32First (hSnapShot, PE)) then
repeat
if (PE.th32ProcessID <> 0) then
sImageFileName := GetProcessDetails (PE.th32ProcessID);
until (Process32Next (hSnapShot, PE) = false);
CloseHandle (hSnapShot);
end; { FillProcessListToolHelp }
请注意“在调用“FillProcessListToolHelp”之前分配了“SeDebugPrivilege”。此外,现在我只对32位Windows的解决方案感兴趣。
您呈现的代码按预期工作,并且是您可以做的最好的代码。您可以添加多一点的诊断,它更好地看到正在发生的事情:
hProcess := OpenProcess (PROCESS_QUERY_INFORMATION or PROCESS_VM_READ,
false, th32ProcessID);
if (hProcess = 0) then
begin
Writeln(IntToStr(GetLastError));
exit;
end;
什么,那么你将学到的是,当OpenProcess
失败,这是因为GetLastError
将返回5
,又名ERROR_ACCESS_DENIED
。那是因为,正如你自己已经确定的那样,所讨论的过程是由不同的用户拥有的。
Windows安全意味着您的标准用户进程无法打开具有必要访问权限的这些进程的句柄。如果您希望获取有关这些流程的信息,您需要以足够的权限执行您的代码,例如以管理员身份运行。
我相信没有管理员权限就可以做的最好的事情就是使用TProcessEntry32
的szExeFile
成员中返回的信息。
{$APPTYPE CONSOLE}
uses
System.SysUtils, Winapi.Windows, Winapi.TlHelp32;
function GetProcessImageFileName(hProcess: THandle; lpImageFileName: LPTSTR;
nSize: DWORD): DWORD; stdcall;
external 'PSAPI.dll' name 'GetProcessImageFileNameW';
function ImageFileName(const PE: TProcessEntry32): string;
var
szImageFileName: array [0 .. MAX_PATH] of Char;
hProcess: THandle;
begin
Result := PE.szExeFile; // fallback in case the other API calls fail
hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, false,
PE.th32ProcessID);
if (hProcess = 0) then
exit;
if (GetProcessImageFileName(hProcess, @szImageFileName[0], MAX_PATH) > 0) then
Result := szImageFileName;
CloseHandle(hProcess);
end;
procedure FillProcessListToolHelp;
var
hSnapShot: THandle;
PE: TProcessEntry32;
begin
hSnapShot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PE.dwSize := SizeOf(TProcessEntry32);
if (Process32First(hSnapShot, PE)) then
repeat
if (PE.th32ProcessID <> 0) then
Writeln(ImageFileName(PE));
until (Process32Next(hSnapShot, PE) = false);
CloseHandle(hSnapShot);
end;
begin
FillProcessListToolHelp;
Readln;
end.
现在,这个问题你状态:
过程黑客和Process Explorer的是能够做到这一点,所以它应该是可能的。
但事实并非如此。至少对于我使用的Process Explorer来说。下面是进程资源管理器,运行在标准用户时,所提供的短信过程:
刚走试用过程黑客,我可以看到,它会产生你想要的信息,即使不运行提升。所以如果你想自己做这件事,你只需要阅读Process Hacker并做它所做的事情。
我的错误 - 由于某种原因,我错误地认为Process Hacker和Process Explorer能够在非管理员执行时返回Windows XP上的完整映像路径。所以大卫是对的。 – 2014-10-20 13:20:08
On win 7过程黑客可以做到这一点,不知何故 – 2014-10-20 13:24:20
过程黑客的作者有一篇关于它如何适用于Vista的文章: http://wj32.org/wp/2010/03/30/get-the-这些未公开的结构的更全面的概述可以在这里找到: http://www.exploit-solutions/index.html。 monday.com/2013/06/undocumented-ntquerysysteminformation.html – 2014-10-21 07:45:07
您在OpenProcess调用中请求什么权限? – 2014-10-19 22:30:39
OpenProcess可以被标准用户调用。你只需要传递适当的权限。在显示代码之前,我们无法告诉您您做错了什么。描述代码本身并不好。 – 2014-10-20 06:21:33
根据要求,我添加了检索进程句柄以及检索进程映像文件名的源代码。 – 2014-10-20 09:04:35