Windows find executable location

How Can I Find The Current Windows Defender Executable Location? And Why Are There Many?

Microsoft has multiple versions of the Defender executable (MpCmdRun.exe) installed on my computer. There is an obvious one in «C:\Program Files\Windows Defender\MpCmdRun.exe» but then two others in «C:\ProgramData\Microsoft\Windows Defender\Platform\4.18.2010.7-0\MpCmdRun.exe» and «C:\ProgramData\Microsoft\Windows Defender\Platform\4.18.2011.6-0\MpCmdRun.exe». The folders all have different versions of MpCmdRun.exe.

Per Microsoft, the latest version is the 4.18.2011.6-0 version, but how would I know this if I hadn’t researched? And if I encode some dependency on this location (see below), how would I know when it’s been superceded?

My goal is to create a custom scheduled task for Defender that runs full scans rather than quick scans. I tried whacking on the existing Windows Defender task definitions (in Task Scheduler -> Task Scheduler Library -> Microsoft -> Windows -> Windows Defender), but the tasks periodically modify themselves (after updates, etc.) and my changes are lost. I can readily create my own custom task, but I have to know the location of MpCmdRun.exe which, as I pointed out above, seems to move around.

Does anyone know of a reliable way to determine what the location of the latest Defender executable is, preferably easy enough to use in a command line?

Also, anyone have any clues about why Microsoft did it this way? Why not just keep the latest version in «C:\Program Files\Windows Defender»? And why leave old version laying around?

How do I find the location of the executable in C? [duplicate]

Is there a way in C/C++ to find the location (full path) of the current executed program?

(The problem with argv[0] is that it does not give the full path.)

9 Answers 9

On Unixes with /proc really straight and realiable way is to:

readlink(«/proc/self/exe», buf, bufsize) (Linux)

readlink(«/proc/curproc/file», buf, bufsize) (FreeBSD)

readlink(«/proc/self/path/a.out», buf, bufsize) (Solaris)

On Unixes without /proc (i.e. if above fails):

If argv[0] starts with «/» (absolute path) this is the path.

Otherwise if argv[0] contains «/» (relative path) append it to cwd (assuming it hasn’t been changed yet).

Otherwise search directories in $PATH for executable argv[0] .

Afterwards it may be reasonable to check whether the executable isn’t actually a symlink. If it is resolve it relative to the symlink directory.

This step is not necessary in /proc method (at least for Linux). There the proc symlink points directly to executable.

Note that it is up to the calling process to set argv[0] correctly. It is right most of the times however there are occasions when the calling process cannot be trusted (ex. setuid executable).

On Windows: use GetModuleFileName(NULL, buf, bufsize)

Use GetModuleFileName() function if you are using Windows.

Please note that the following comments are unix-only.

The pedantic answer to this question is that there is no general way to answer this question correctly in all cases. As you’ve discovered, argv[0] can be set to anything at all by the parent process, and so need have no relation whatsoever to the actual name of the program or its location in the file system.

However, the following heuristic often works:

  1. If argv[0] is an absolute path, assume this is the full path to the executable.
  2. If argv[0] is a relative path, ie, it contains a / , determine the current working directory with getcwd() and then append argv[0] to it.
  3. If argv[0] is a plain word, search $PATH looking for argv[0], and append argv[0] to whatever directory you find it in.
Читайте также:  Как устанавливать приложения mac os

Note that all of these can be circumvented by the process which invoked the program in question. Finally, you can use linux-specific techniques, such as mentioned by emg-2. There are probably equivalent techniques on other operating systems.

Even supposing that the steps above give you a valid path name, you still might not have the path name you actually want (since I suspect that what you actually want to do is find a configuration file somewhere). The presence of hard links means that you can have the following situation:

Now, the approach above (including, I suspect, /proc/$pid/exe) will give /some/where/else/foo as the real path to the program. And, in fact, it is a real path to the program, just not the one you wanted. Note that this problem doesn’t occur with symbolic links which are much more common in practice than hard links.

In spite of the fact that this approach is in principle unreliable, it works well enough in practice for most purposes.

How do I find the location of an executable in Windows?

I remembered that I used a tool called as where to find locations for any executable programs like this in a console:

Now I cannot find this tool. Not sure if Windows has a build-in tool to do that search?

14 Answers 14

According to the StackOverflow answer at Is there an equivalent of ‘which’ on windows?, where.exe does this on Windows 7 and Windows Server 2003 and later:

Example

Output:

In powershell use where.exe , Get-Command (or its abbreviation gcm ), as where is the default alias for Where-Object .

EDIT: I should have added, if you can’t use the WHERE command from the command prompt, check your PATH variable. (Just use the «path» command.) Make sure C:\Windows\System32 is in your path. That’s where «where.exe» is located.

WHERE is the command you’re looking for! WHERE is like a cross between the UNIX shell built-in «which» and the «locate» command, in that it works for both command executables and regular files.

It’s also somewhat more complex than either of those two, although, in general a simple

It’s different from the «locate» command in that it’s not looking through the entire filesystem. Instead, the default behavior is to look for files in two locations:

  • The current directory.
  • All of the directories in the PATH variable.

So, any command that you can run directly from a command prompt without specifying the directory, will be found by the WHERE command. (Because any command like that is already in the PATH variable list.)

If you want to search only in the command path variable, you can use:

If, on the other hand, you want to find all copies of a file in a directory tree, you can use:

Finally, WHERE will find commands and any files with an extension from the PATHEXT variable without including the extension. All other files have to be specified either exactly or with wildcards.

Take for example the files «dxdiag.exe» and «dxdiagn.dll». Note the following command and its output:

It succeeds in returning all versions of «dxdiag.exe» because «.exe» is one of the extensions in the PATHEXT variable. (Note: «WHERE dxdiag» would have worked as well, because C:\Windows\System32 is in the PATH variable.)

on the other hand, fails to return any result, because «.dll» is not in PATHEXT.

In this case, look at the result that adding a wildcard gives us:

It successfully returns all versions of dxdiagn.dll.

For more information, use «WHERE /?». Hope this helps!

Search for executable files using find command

What type of parameter/flag can I use with the Unix find command so that I search executables?

Читайте также:  Asus код активации windows

10 Answers 10

On GNU versions of find you can use -executable :

For BSD versions of find, you can use -perm with + and an octal mask:

In this context «+» means «any of these bits are set» and 111 is the execute bits.

Note that this is not identical to the -executable predicate in GNU find. In particular, -executable tests that the file can be executed by the current user, while -perm +111 just tests if any execute permissions are set.

Older versions of GNU find also support the -perm +111 syntax, but as of 4.5.12 this syntax is no longer supported. Instead, you can use -perm /111 to get this behavior.

Tip of the hat to @gniourf_gniourf for clearing up a fundamental misconception.

This answer attempts to provide an overview of the existing answers and to discuss their subtleties and relative merits as well as to provide background information, especially with respect to portability.

Finding files that are executable can refer to two distinct use cases:

  • user-centric: find files that are executable by the current user.
  • file-centric: find files that have (one or more) executable permission bits set.

Note that in either scenario it may make sense to use find -L . instead of just find . in order to also find symlinks to executables.

Note that the simplest file-centric case — looking for executables with the executable permissions bit set for ALL three security principals (user, group, other) — will typically, but not necessarily yield the same results as the user-centric scenario — and it’s important to understand the difference.

User-centric ( -executable )

The accepted answer commendably recommends -executable , IF GNU find is available.

  • GNU find comes with most Linux distros
    • By contrast, BSD-based platforms, including macOS, come with BSD find, which is less powerful.
  • As the scenario demands, -executable matches only files the current user can execute (there are edge cases. [1] ).

The BSD find alternative offered by the accepted answer ( -perm +111 ) answers a different, file-centric question (as the answer itself states).

    Using just -perm to answer the user-centric question is impossible, because what is needed is to relate the file’s user and group identity to the current user’s, whereas -perm can only test the file’s permissions.
    Using only POSIX find features, the question cannot be answered without involving external utilities.

Thus, the best -perm can do (by itself) is an approximation of -executable . Perhaps a closer approximation than -perm +111 is -perm -111 , so as to find files that have the executable bit set for ALL security principals (user, group, other) — this strikes me as the typical real-world scenario. As a bonus, it also happens to be POSIX-compliant (use find -L to include symlinks, see farther below for an explanation):

gniourf_gniourf’s answer provides a true, portable equivalent of -executable , using -exec test -x <> \; , albeit at the expense of performance.

Combining -exec test -x <> \; with -perm +111 (i.e., files with at least one executable bit set) may help performance in that exec needn’t be invoked for every file (the following uses the POSIX-compliant equivalent of BSD find -perm +111 / GNU find -perm /111 ; see farther below for an explanation):

File-centric ( -perm )

  • To answer file-centric questions, it issufficient to use the POSIX-compliant -perm primary (known as a test in GNU find terminology).
    • -perm allows you to test for any file permissions, not just executability.
    • Permissions are specified as either octal or symbolic modes. Octal modes are octal numbers (e.g., 111 ), whereas symbolic modes are strings (e.g., a=x ).
    • Symbolic modes identify the security principals as u (user), g (group) and o (other), or a to refer to all three. Permissions are expressed as x for executable, for instance, and assigned to principals using operators = , + and — ; for a full discussion, including of octal modes, see the POSIX spec for the chmod utility.
    • In the context of find :
      • Prefixing a mode with — (e.g., -ug=x ) means: match files that have all the permissions specified (but matching files may have additional permissions).
      • Having NO prefix (e.g. 755 ) means: match files that have this full, exact set of permissions.
      • Caveat: Both GNU find and BSD find implement an additional, nonstandard prefix with are-ANY-of-the-specified-permission-bits-set logic, but do so with incompatible syntax:
        • BSD find: +
        • GNU find: / [2]
      • Therefore, avoid these extensions, if your code must be portable.
  • The examples below demonstrate portable answers to various file-centric questions.
Читайте также:  Альт линукс 7 0 кентавр

File-centric command examples

  • The following examples are POSIX-compliant, meaning they should work in any POSIX-compatible implementation, including GNU find and BSD find; specifically, this requires:
    • NOT using nonstandard mode prefixes + or / .
    • Using the POSIX forms of the logical-operator primaries:
      • ! for NOT (GNU find and BSD find also allow -not ); note that \! is used in the examples so as to protect ! from shell history expansions
      • -a for AND (GNU find and BSD find also allow -and )
      • -o for OR (GNU find and BSD find also allow -or )
  • The examples use symbolic modes, because they’re easier to read and remember.
    • With mode prefix — , the = and + operators can be used interchangeably (e.g., -u=x is equivalent to -u+x — unless you apply -x later, but there’s no point in doing that).
    • Use , to join partial modes; AND logic is implied; e.g., -u=x,g=x means that both the user and the group executable bit must be set.
    • Modes cannot themselves express negative matching in the sense of «match only if this bit is NOT set»; you must use a separate -perm expression with the NOT primary, ! .
  • Note that find’s primaries (such as -print , or -perm ; also known as actions and tests in GNU find) are implicitly joined with -a (logical AND), and that -o and possibly parentheses (escaped as \( and \) for the shell) are needed to implement OR logic.
  • find -L . instead of just find . is used in order to also match symlinks to executables
    • -L instructs find to evaluate the targets of symlinks instead of the symlinks themselves; therefore, without -L , -type f would ignore symlinks altogether.

[1] Description of -executable from man find as of GNU find 4.4.2:

Matches files which are executable and directories which are searchable (in a file name resolution sense). This takes into account access control lists and other permissions artefacts which the -perm test ignores. This test makes use of the access(2) system call, and so can be fooled by NFS servers which do UID mapping (or root-squashing), since many systems implement access(2) in the client’s kernel and so cannot make use of the UID mapping information held on the server. Because this test is based only on the result of the access(2) system call, there is no guarantee that a file for which this test succeeds can actually be executed.

[2] GNU find versions older than 4.5.12 also allowed prefix + , but this was first deprecated and eventually removed, because combining + with symbolic modes yields likely yields unexpected results due to being interpreted as an exact permissions mask. If you (a) run on a version before 4.5.12 and (b) restrict yourself to octal modes only, you could get away with using + with both GNU find and BSD find, but it’s not a good idea.

Оцените статью