判断进程是否从快捷方式启动

4

有没有可能确定是否使用快捷方式启动了另一个进程/窗口? 目的是读取该快捷方式以获取启动设置:起始文件夹,以管理员身份运行等。也许有一种方法可以找出程序的催化剂/调用者(用户/带管理权限/快捷方式)?

我知道使用Windows驱动程序工具包来确定它。尽管在其他事情中开发这个工具相当棘手。


有很多方法可以使用提升的权限和自定义命令行启动进程。用户可以使用控制台,服务由SCM执行等等。你链接的方法是最好的,它不需要DDK的使用,你可以自己定义所有本地API函数和结构,而且有很多例子。 - Ari0nhh
或者,您可以直接探测应用程序的环境:当前文件夹将成为启动文件夹,您将拥有管理员安全令牌(或没有)等。 - Chris Becke
1
没有必要检查链接。启动文件夹是程序启动时的当前工作目录。如果您的进程拥有适当的令牌,则可以确定是否以管理员身份运行。我完全看不出需要查找lnk文件的必要性... - xMRi
1个回答

12

有没有可能确定另一个进程/窗口是否使用快捷方式启动?

是的,但不容易。

答案所述类似问题,一个进程可以通过调用GetStartupInfo()并检查STARTF_TITLEISLINKNAME标志来找出自己是否由快捷方式启动。这在MSDN上有记录:

GetStartupInfo函数

检索创建调用进程时指定的STARTUPINFO结构的内容。

STARTUPINFO结构

dwFlags
一位比特控制着进程创建窗口时是否使用某些 STARTUPINFO 成员的位字段。此成员可以是以下一个或多个值。

...
STARTF_TITLEISLINKNAME
0x00000800
lpTitle 成员包含用户调用以启动此进程的快捷方式文件(.lnk)的路径。当调用指向启动应用程序的 .lnk 文件时,这通常由 shell 设置。大多数应用程序不需要设置此值。

一旦您有了 .lnk 文件的路径,您可以根据需要使用 IShellLink 接口对其进行解析(有关更多详细信息,请参阅 Shell Links )。

现在,话虽如此,但是你不能直接检索另一个进程的STARTUPINFO结构。然而,你可以通过向目标进程注入代码(使用CreateRemoteThread()SetWindowsHookEx())来间接地检索它,并且然后让该代码调用GetStartupInfo()并使用你选择的任何IPC机制(如WM_COPYDATA,命名管道、邮槽、套接字、COM、RPC等)将所需信息回传给你的进程。

或者,有一种非官方的方法(取决于操作系统版本),可以获取许多相同的STARTUPINFO字段值,包括.lnk文件名,而不需要将任何代码注入目标进程。使用NtQueryInformationProcess()获取指向目标进程的PEB1结构的指针,该结构具有一个ProcessParameters字段,该字段是指向RTL_USER_PROCESS_PARAMETERS1结构的指针,该结构具有一个WindowTitle字段(以及其他包含STARTUPINFO值的字段)。您可以使用OpenProcess()获取目标进程的HANDLE(您可以使用GetWindowThreadProcessId()获取HWND的进程ID),然后使用ReadProcessMemory()根据需要读取PEBRTL_USER_PROCESS_PARAMETERS结构的内容。

1: 大部分PEBRTL_USER_PROCESS_PARAMETERS结构的内容都没有在MSDN上记录,但已在http://undocumented.ntinternals.net此处此处)记录。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接