Parsia's Den

Because no one wants to be the other guy from Wham!

Oct 23, 2017 - 5 minute read - Comments - Windows

Run Line vs. cmd vs. PowerShell

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

  1. Start API Monitor and procmon and open a command prompt.
  2. In procmon set this filter
    • Process Name is cmd.exe
  3. In API Monitor clear the filter and only monitor
    • Data Access and Storage > Local File System > File Management > Kernel32.dll
  4. Type iexplore and see the results.

cmd is looking in the current directory (C:\) first and then in PATH.

cmd calls in API Monitor cmd calls in API Monitor cmd calls in procmon cmd calls in procmon

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 calls in API Monitor PowerShell calls in API Monitor PowerShell calls in procmon PowerShell calls in procmon

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.

Process Start for iexplore Process Start for iexplore

A bit further up we will see the registry key in the tl;dr section.

App Paths in procmon App Paths in procmon

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.

App Paths in registry App Paths in registry

Each application has a separate key. Inside we can see the default key and a path key for Chrome.

Chrome app paths Chrome app paths

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
Run Line searching for java.exe Run Line searching for java.exe

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.