Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Determine if process started from shortcut

Tags:

c

winapi

Is it possible to determine if another process/window was started using a shortcut? The purpose being to then read that shortcut to obtain the startup settings: start-in folder, run as admin, etc. Maybe there is a way to find out the catalyst/caller of the program (User/Application w admin privileges/shortcut)?

I'm aware of using the Windows Driver Kit to determine it. Although this is rather tricky to develop in among other things.

like image 830
sazr Avatar asked Dec 19 '22 15:12

sazr


1 Answers

Is it possible to determine if another process/window was started using a shortcut?

Yes, but not easily.

As mentioned in an answer to a similar question, a process can find out if itself was started by a shortcut by calling GetStartupInfo() and checking for the STARTF_TITLEISLINKNAME flag. This is documented on MSDN:

GetStartupInfo function

Retrieves the contents of the STARTUPINFO structure that was specified when the calling process was created.

STARTUPINFO structure

dwFlags
A bitfield that determines whether certain STARTUPINFO members are used when the process creates a window. This member can be one or more of the following values.

...
STARTF_TITLEISLINKNAME
0x00000800
The lpTitle member contains the path of the shortcut file (.lnk) that the user invoked to start this process. This is typically set by the shell when a .lnk file pointing to the launched application is invoked. Most applications will not need to set this value.

Once you have the path to the .lnk file, you can parse it using the IShellLink interface as needed (see Shell Links for more details).

Now, that being said, you cannot directly retrieve the STARTUPINFO structure of another process. However, you can retrieve it indirectly, by injecting code into the target process (using CreateRemoteThread() or SetWindowsHookEx()), and then have that code call GetStartupInfo() and communicate the desired information back to your process using an IPC mechanism of your choosing (WM_COPYDATA, named pipe, mailslot, socket, COM, RPC, etc).

Or, there is an unofficial way (subject to OS version) to get many of the same STARTUPINFO field values, including the .lnk filename, without injecting any code into the target process. Use NtQueryInformationProcess() to get a pointer to the target process's PEB1 structure, which has a ProcessParameters field that is a pointer to an RTL_USER_PROCESS_PARAMETERS1 structure, which has a WindowTitle field (amongst other fields that contain values from STARTUPINFO). You can use OpenProcess() to get a HANDLE to the target process (you can get the process ID of an HWND using GetWindowThreadProcessId()), and then use ReadProcessMemory() to read the contents of the PEB and RTL_USER_PROCESS_PARAMETERS structures as needed.

1: Most of the content of the PEB and RTL_USER_PROCESS_PARAMETERS structures are not documented by MSDN, but are documented on http://undocumented.ntinternals.net (here and here).

like image 177
Remy Lebeau Avatar answered Jan 05 '23 15:01

Remy Lebeau