gpt4 book ai didi

delphi - 标准用户(XP/Server 2003及以下)如何获取所有正在运行的进程的镜像路径?

转载 作者:行者123 更新时间:2023-12-02 04:31:09 35 4
gpt4 key购买 nike

我正在尝试以标准用户身份获取系统中所有正在运行的进程的完整路径,而无需 Windows XP/Server 2003 上的管理权限。获取所有正在运行的进程的列表及其句柄不是问题(Toolhelp“Process32First”/ native API“NtQuerySystemInformation”/PsApi“EnumProcesses”)。我的问题是这些调用不会返回正确的进程句柄,而是返回某种类型的句柄,我首先必须传递给“OpenProcess”以获得正确的进程句柄,然后我可以使用它来查询完整的图像路径(通过调用“GetProcessImageFileName”或一些低级函数)。但是,对于不是由当前用户启动的进程,如果我不是管理员,“OpenProcess”就会失败。

有人能指出我如何检索此信息的正确方向吗? 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 安全性意味着您的标准用户进程根本无法使用必要的访问权限打开这些进程的句柄。如果您希望获取有关这些进程的信息,您将需要以足够的权限执行代码,例如以管理员身份运行。

我相信,在没有管理员权限的情况下,您能做的最好的事情就是使用 TProcessEntry32szExeFile 成员中返回的信息。

{$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 Hacker and Process Explorer are able to do it, so it should be possible.

但事实并非如此。至少对于我使用的 Process Explorer 来说是这样。以下是 Process Explorer 在以标准用户身份运行时必须为 smss 进程提供的功能:

enter image description here

刚刚尝试过 Process Hacker,我发现即使没有运行提升,它也会产生您想要的信息。因此,如果您希望自己执行此操作,您只需阅读 Process Hacker 并执行其操作即可。

关于delphi - 标准用户(XP/Server 2003及以下)如何获取所有正在运行的进程的镜像路径?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26451804/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com