Note about the differences between search paths when running stuff via the Windows Run Line (win+r
), command line and PowerShell.
We can type iexplore
in Run Line to open up Internet Explorer but doing the same in a cmd or PowerShell is not successful.
tl;dr\ Run Line looks in the following registry location then PATH. Credit Vic Laurie at commandwindows.com.
HKLM\Software\Microsoft\Windows\CurrentVersion\App Paths
Search order
- cmd searches first in local directory and then in PATH.
- PowerShell searches first in PATH and then in local directory.
- Run Line searches in
App Paths
first.
Usual blabbering and needless digging follows.
Question
When running something via the command line (a.k.a. cmd) or PowerShell (ps), Windows will search for the executable in PATH. Type notepad
or calc
and they will be executed because both are in %WINDIR%\System32
which is usually in PATH. Same thing can be done in Run Line.
Now try iexplore
or chrome
in Run Line. It works. Do the same in cmd/ps and they cannot find the executable. Something is different. We know both of these search in PATH but Run Line is looking in other places.
What is PATH?
In short it's "a bunch of places Windows will search for things."
View it in cmd:
C:\>echo %PATH%
C:\ProgramData\Oracle\Java\javapath;C:\Python27\;C:\Python27\Scripts;C:\Windows\
system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShe
ll\v1.0\
Or in ps:
PS C:\> ls Env:path | Format-List
Name : Path
Value : %SystemRoot%\system32\WindowsPowerShell\v1.0\;C:\ProgramData\Oracle\Java\javapath;
C:\Python27\;C:\Python27\Scripts;C:\Windows\system32;
C:\Windows;C:\Windows\System32\Wbem;
C:\Windows\System32\WindowsPowerShell\v1.0\
# Make sure to pipe the output to Format-List otherwise it will be truncated
PS C:\> ls Env:path
Name Value
---- -----
Path %SystemRoot%\system32\WindowsPowerShell\v1.0\;
C:\ProgramData\Oracle\Java\javapath;C:\...
Although these are for disposable VMs, I am quite sure I am giving away free intel. But let's move on.
Executing in cmd/ps vs. Run Line
A search does not bring any relevant info. I could only find one relevant result from commandwindows.com
which had the answer.
As an exercise we are going to analyze how these work and where they search.
Setup and Tools
Usual setup is a Windows 7 32-bit VM.
Tools are:
- Procmon
- API Monitor
cmd
- Start API Monitor and procmon and open a command prompt.
- In procmon set this filter
Process Name is cmd.exe
- In API Monitor clear the filter and only monitor
Data Access and Storage > Local File System > File Management > Kernel32.dll
- Type
iexplore
and see the results.
cmd is looking in the current directory (C:\)
first and then in PATH.
We can see that it searches in current directory first and then in PATH.
Note about javapath
C:\ProgramData\Oracle\Java\javapath
is actually a junction or soft link to C:\ProgramData\Oracle\Java\javapath_target_36229975
. It's like an NTFS symlink but not exactly (NTFS junction can only point to local volume while NTFS symlink can point to remote shares). See more at MSDN Hard Links and Junctions. As far as I was able to understand, hard links are for files (local and remote) while junctions are for local directories.
This is different from a shortcut (or lnk). It's an alias. We can cd to javapath
and Windows will think such a directory exists while we are actually in javapath_target_36229975
.
C:\ProgramData\Oracle\Java>dir
Directory of C:\ProgramData\Oracle\Java
10/06/2017 11:16 PM <DIR> .
10/06/2017 11:16 PM <DIR> ..
10/06/2017 11:16 PM <DIR> .oracle_jre_usage
10/06/2017 11:16 PM <DIR> installcache
10/06/2017 11:16 PM <JUNCTION> javapath [C:\ProgramData\Oracle\Java\java
path_target_36229975]
10/06/2017 11:16 PM <DIR> javapath_target_36229975
C:\ProgramData\Oracle\Java>dir javapath
Directory of C:\ProgramData\Oracle\Java\javapath
10/06/2017 11:16 PM <DIR> .
10/06/2017 11:16 PM <DIR> ..
10/06/2017 11:16 PM 191,040 java.exe
10/06/2017 11:16 PM 191,552 javaw.exe
10/06/2017 11:16 PM 270,912 javaws.exe
C:\ProgramData\Oracle\Java>dir javapath_target_36229975
Directory of C:\ProgramData\Oracle\Java\javapath_target_36229975
10/06/2017 11:16 PM <DIR> .
10/06/2017 11:16 PM <DIR> ..
10/06/2017 11:16 PM 191,040 java.exe
10/06/2017 11:16 PM 191,552 javaw.exe
10/06/2017 11:16 PM 270,912 javaws.exe
PowerShell
Do the same for PowerShell but run API Monitor as admin.
PowerShell is using different API calls and also looking for files with specific extensions (ps files and PATHEXT
env variable).
It's also searching first in PATH and then in current directory.
Run Line
For Run Line, we will use a different approach to find stuff in procmon.
After we run iexplore in Run Line, open process tree at Tools > Process Tree (ctrl+t)
in procmon (don't forget to reset the filter). Double clicking on iexplore.exe
which will take us to the Process Start
event.
A bit further up we will see the registry key in the tl;dr section.
Going up in procmon and watching the results in API Monitor does not show anything about searching path. It seems like Run Line first searches in App Paths
and then in PATH.
What is in App Paths?
Let's look at this so-called registry keys.
Each application has a separate key. Inside we can see the default key and a path key for Chrome.
Run Line Search Order
Let's test our search order theory by running java.exe
via Run Line and observing it in procmon.
This time will add a new filter and reduce the noise.
Path contains java
Note that while we have a javaws.exe
key in App Paths, there's none for java.exe
.
See the REPARSE
results? That's the java junction we talked about.
Looks like we were right. Interesting but potentially useless stuff.