# How Fastfetch Identifies Installed Software Through Binary Detection

> Discover how fastfetch detects installed software by analyzing binary executables and their version strings across ELF PE and Mach-O formats. Learn its efficient detection methods.

- Repository: [fastfetch-cli/fastfetch](https://github.com/fastfetch-cli/fastfetch)
- Tags: internals
- Published: 2026-03-30

---

**Fastfetch identifies installed software by locating executables in `$PATH` and extracting version strings directly from binary files using platform-specific parsers for ELF, PE, and Mach-O formats, falling back to executing `--version` only when necessary.**

The fastfetch-cli/fastfetch repository implements a high-performance detection system that determines software versions without spawning subprocesses whenever possible. By parsing binary file formats directly, fastfetch minimizes system overhead while maintaining accurate version identification across Linux, Windows, and macOS platforms.

## The Three-Step Binary Detection Pipeline

Fastfetch employs a standardized three-step pipeline to identify installed software versions. This architecture prioritizes static file analysis over dynamic execution to reduce latency and resource consumption.

### Locate the Executable with `ffFindExecutableInPath()`

The detection process begins in [`src/common/impl/path.c`](https://github.com/fastfetch-cli/fastfetch/blob/main/src/common/impl/path.c) where `ffFindExecutableInPath()` traverses the directories specified in `$PATH`. On Windows, the implementation utilizes `SearchPathA` for native compatibility, while Unix-like systems parse the colon-delimited `PATH` environment variable. This function returns the absolute filesystem path of the target binary, enabling subsequent direct file analysis without relying on shell execution.

### Extract Version Strings Using `ffBinaryExtractStrings()`

The core detection logic resides in [`src/common/binary.h`](https://github.com/fastfetch-cli/fastfetch/blob/main/src/common/binary.h) and its platform-specific implementations. The `ffBinaryExtractStrings()` function maps the binary into memory and scans the read-only data section—`.rodata` on ELF systems, `.rdata` on Windows PE files, and the appropriate segment in Mach-O binaries.

The platform-specific implementations handle their respective file formats:

- **Linux/macOS/BSD**: [`src/common/impl/binary_linux.c`](https://github.com/fastfetch-cli/fastfetch/blob/main/src/common/impl/binary_linux.c) utilizes `libelf` to locate and parse the `.rodata` section
- **Windows**: [`src/common/impl/binary_windows.c`](https://github.com/fastfetch-cli/fastfetch/blob/main/src/common/impl/binary_windows.c) maps PE files and scans the `.rdata` section  
- **Apple universal binaries**: [`src/common/impl/binary_apple.c`](https://github.com/fastfetch-cli/fastfetch/blob/main/src/common/impl/binary_apple.c) handles Mach-O fat binaries and architecture-specific segments

The function accepts a **callback parameter** that examines each string literal. When the callback identifies a matching version pattern, it stores the result and returns `false` to terminate the scan immediately, optimizing performance by avoiding unnecessary iteration through the remaining binary content.

### Fallback to `--version` Execution

When binary string extraction fails to locate a version identifier, modules fall back to executing the binary with standard version flags. The `ffProcessAppendStdOut()` function captures output from commands like `--version`, then applies post-processing to isolate the version number. This hybrid approach ensures compatibility with software that embeds version data only in runtime output or dynamic libraries.

## Platform-Specific Implementation Details

Fastfetch's binary detection abstracts file format complexity through unified interfaces while maintaining platform-native parsing capabilities.

### ELF Binary Parsing on Linux and Unix

The Linux implementation in [`src/common/impl/binary_linux.c`](https://github.com/fastfetch-cli/fastfetch/blob/main/src/common/impl/binary_linux.c) leverages `libelf` to access the `.rodata` section of ELF executables. This section contains string literals compiled into the binary, including version banners and build identifiers. The parser iterates through this section sequentially, passing each candidate string to the module-specific callback function for pattern recognition.

### PE Binary Parsing on Windows

For Windows executables, [`src/common/impl/binary_windows.c`](https://github.com/fastfetch-cli/fastfetch/blob/main/src/common/impl/binary_windows.c) handles Portable Executable (PE) format parsing. The implementation maps the file into memory and specifically targets the `.rdata` section, where Microsoft compilers store read-only initialized data. This approach captures version strings embedded during the build process without requiring process execution or command-line parsing.

### Mach-O Handling for macOS

Apple platforms require special handling due to universal binaries containing multiple architectures. The [`src/common/impl/binary_apple.c`](https://github.com/fastfetch-cli/fastfetch/blob/main/src/common/impl/binary_apple.c) implementation parses Mach-O headers to locate the appropriate segment for string extraction, ensuring accurate version detection across both Intel and Apple Silicon systems without architecture-specific execution.

## Practical Implementation: Detecting Neovim

The editor detection module in [`src/detection/editor/editor.c`](https://github.com/fastfetch-cli/fastfetch/blob/main/src/detection/editor/editor.c) demonstrates the callback-based extraction pattern. When identifying Neovim installations, fastfetch uses the following approach:

```c
/* editor.c – part of the editor detection module */
static bool extractNvimVersionFromBinary(const char *str,
                                         FF_MAYBE_UNUSED uint32_t len,
                                         void *userdata)
{
    if (!ffStrStartsWith(str, "NVIM v")) return true;
    ffStrbufSetS((FFstrbuf *)userdata, str + strlen("NVIM v"));
    return false;            /* stop scanning */
}

/* After locating the binary path … */
ffBinaryExtractStrings(result->path.chars,
                       extractNvimVersionFromBinary,
                       &result->version,
                       (uint32_t)strlen("NVIM v0.0.0"));

```

The callback checks for the "NVIM v" prefix, extracts the trailing version string into the result buffer, and returns `false` to halt further scanning. The **minimum length parameter** `(uint32_t)strlen("NVIM v0.0.0")` filters out shorter strings that cannot contain valid version data, reducing unnecessary callback invocations.

## Extending Detection to New Software

Adding support for additional tools requires implementing three components:

1. **String recognition callback** – A function matching the tool's specific version marker (e.g., "v0.0.0" patterns or branded prefixes)
2. **Minimum length parameter** – Passed to `ffBinaryExtractStrings()` to skip obviously short strings
3. **Fallback handling** – Optional execution of `--version` flags when binary extraction returns empty results

The window manager detection in [`src/detection/wm/wm_linux.c`](https://github.com/fastfetch-cli/fastfetch/blob/main/src/detection/wm/wm_linux.c) illustrates this pattern when identifying Hyprland:

```c
/* wm_linux.c – detecting Hyprland */
ffBinaryExtractStrings(buffer.chars,
                       extractHyprlandVersion,
                       result,
                       (uint32_t)strlen("v0.0.0"));
if (result->length == 0) {
    /* fallback */
    ffProcessAppendStdOut(result,
        (char *const[]){ buffer.chars, "--version", NULL });
}

```

This modular architecture allows contributors to add new software detection by implementing only the recognition logic, while the heavy lifting of file parsing and memory management remains handled by the common binary extraction framework.

## Summary

Fastfetch's binary detection system provides efficient software identification through direct file analysis:

- **Path resolution** via `ffFindExecutableInPath()` locates binaries in `$PATH` without environment assumptions
- **Format abstraction** through `ffBinaryExtractStrings()` handles ELF, PE, and Mach-O transparently
- **Callback architecture** enables early termination upon version discovery, minimizing I/O operations
- **Execution fallback** ensures compatibility when static strings are unavailable
- **Minimal overhead** avoids process spawning until necessary, reducing detection latency across all supported platforms

## Frequently Asked Questions

### How does fastfetch identify installed software without running the programs?

Fastfetch identifies installed software by parsing executable binary files directly rather than executing them. The tool uses `ffBinaryExtractStrings()` to scan read-only data sections (`.rodata` in ELF, `.rdata` in PE) where compilers store version strings, extracting this information through file I/O operations that avoid process creation overhead and shell execution.

### What file formats does fastfetch support for binary version detection?

Fastfetch supports three major executable formats: **ELF** (Linux and BSD systems), **PE** (Windows executables), and **Mach-O** (macOS). Each format has a dedicated implementation—[`binary_linux.c`](https://github.com/fastfetch-cli/fastfetch/blob/main/binary_linux.c), [`binary_windows.c`](https://github.com/fastfetch-cli/fastfetch/blob/main/binary_windows.c), and [`binary_apple.c`](https://github.com/fastfetch-cli/fastfetch/blob/main/binary_apple.c)—that understands the specific section layouts and string storage mechanisms of its respective platform.

### Why does fastfetch fall back to executing `--version` commands?

Fastfetch falls back to `--version` execution when `ffBinaryExtractStrings()` fails to locate recognizable version patterns in the binary's read-only sections. Some applications generate version strings dynamically at runtime or store them in resources that require execution to access. The fallback ensures comprehensive coverage while maintaining performance by attempting static extraction first.

### How can I add detection for a new tool to fastfetch?

To add detection for new software, implement a callback function that recognizes the tool's specific version string pattern (such as "ToolName v1.0.0"), then call `ffBinaryExtractStrings()` with this callback and an appropriate minimum string length. If binary extraction fails, implement a fallback using `ffProcessAppendStdOut()` to execute the binary with `--version`. Reference existing implementations in [`src/detection/editor/editor.c`](https://github.com/fastfetch-cli/fastfetch/blob/main/src/detection/editor/editor.c) or [`src/detection/wm/wm_linux.c`](https://github.com/fastfetch-cli/fastfetch/blob/main/src/detection/wm/wm_linux.c) for structural patterns.