# vmlinux-to-elf: Recovering analyzable ELF files from Linux kernels

> vmlinux-to-elf converts raw or stripped Linux kernel images into ELF files with recovered symbols for IDA Pro and Ghidra analysis. It is aimed at embedded Linux reverse engineers, although symbol recovery remains heuristic and dependent on compatible kallsyms data.

**marin-m/vmlinux-to-elf** — A tool to recover a fully analyzable .ELF from a raw kernel, through extracting the kernel symbol table (kallsyms)

- Repository: https://github.com/marin-m/vmlinux-to-elf
- Website: https://fossplant.re/wiki/Main_page
- Stars: 1,835 · Forks: 187
- Language: Python
- License: GPL-3.0
- Published: 2026-10-16 · Updated: 2026-10-16 · Language: en
- Canonical page: https://hysenlabs.com/projects/marin-m-vmlinux-to-elf

## Why vmlinux-to-elf exists for embedded kernel analysis

A Linux kernel image often arrives as a raw binary, vmlinux, vmlinuz, bzImage, or zImage. It may be stripped, compressed, or packaged in a format that makes it inconvenient to load directly into a disassembler. Even when some symbols remain, strings that existed in an earlier, uncompressed kernel image can be absent from the supplied file.

vmlinux-to-elf addresses that gap by scanning a kernel image for kallsyms, the kernel symbol table used in Linux kernel oops messages. According to the README, the table contains symbol names, addresses, and symbol types represented in a style similar to nm. Its compact serialization is compressed, so recovering it can restore names that are not visible in the original input.

The intended users are reverse engineers working with embedded Linux systems, firmware images, and kernel binaries. The resulting ELF is intended for IDA Pro and Ghidra, where recovered function and variable symbols can make navigation and static analysis easier. This is a conversion and recovery tool, not a general Linux boot loader, exploit framework, or runtime tracing system.

## The kallsyms recovery path inside vmlinux-to-elf

The central mechanism is heuristic detection of the serialized kallsyms structures. The repository documentation describes separate areas for symbol addresses, symbol counts, compressed names, markers, and newer name-sequence data. Their offsets are detected in vmlinux_to_elf/core/kallsyms.py rather than supplied by a fixed image layout.

Modern kernels may store either kallsyms_addresses or a combination of kallsyms_offsets and kallsyms_relative_base. The symbol count, kallsyms_num_syms, is useful for checking alignment and endianness while decoding. Names in kallsyms_names are stored as length-separated, compressed tokens. Each token byte references an index in kallsyms_token_index, which points to a character or string fragment in kallsyms_token_table. The tool therefore has to locate and decode several related tables before it can produce useful symbol records.

The process also includes architecture detection. The README says the tool infers instruction set, endianness, and bit size using common function prologue signatures and other clues. It then infers an entry point from symbols in kallsyms. Basic kernel-base inference uses the first TEXT symbol whose lower address bits are clear. That last point is a heuristic, not a general-purpose relocation engine. The generated ELF is consequently most dependable when the source image follows the structures and conventions the scanner recognizes.

## Kernel containers and compression supported by the project

The tool accepts both raw kernel blobs and preexisting but stripped ELF files. It automatically detects and unpacks main Linux kernel compression formats, and its feature list also includes support for certain Android boot images that begin with ANDROID! or UNCOMPRESSED_IMG. This makes it more useful than a script that expects an already decompressed vmlinux.

The README exposes two smaller command-line workflows. kallsyms-finder lists symbol addresses from an input image, while vmlinuz-decompressor writes a decompressed kernel binary. The main vmlinux-to-elf command combines the relevant conversion path and emits an ELF file. This separation is useful when debugging a difficult image: first determine whether the image can be decompressed, then inspect whether a symbol table can be found before opening the output in another tool.

The input format boundary is still important. The documentation says certain Android boot images are supported, not every container format. Likewise, automatic compression handling is described in general terms without a complete format matrix in the excerpt. A container may need to be extracted with another tool before vmlinux-to-elf can see the kernel image it expects.

## Installing the CLI and producing the first ELF file

On Ubuntu, the README recommends the Snap package for the command-line and graphical interfaces. The command requires administrative access and installs the published package:

```bash
sudo snap install vmlinux-to-elf
```

After installation, pass an input kernel image and an output ELF path to the main command. The output path is supplied by the user, so the following example follows the syntax documented in the README:

```bash
vmlinux-to-elf <input_kernel.bin> <output_kernel.elf>
```

Replace both placeholders with real paths. A successful invocation should create the ELF file at the selected output path. The README also documents a symbol-address-only command, which is a faster first check when the goal is to determine whether kallsyms can be found:

```bash
kallsyms-finder <input_kernel.bin>
```

The Snap package names this command vmlinux-to-elf.kallsyms-finder. If that command reports no usable symbols, inspect the input container or compression format before treating the generated ELF as a reliable analysis artifact. The README does not document a separate rollback or undo command.

## uv, Flatpak, and local GUI setup for vmlinux-to-elf

Users who prefer uv can install the command-line package. On Fedora, the README gives the following dependency and installation sequence. The first command installs uv and native build dependencies, while the second installs the Python package as a tool:

```bash
sudo dnf install -y uv flatpak @development-tools
uv tool install vmlinux-to-elf
```

That installation path omits the GUI optional dependency. The documented Flatpak installation then adds the graphical interface:

```bash
flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
flatpak install re.fossplant.vmlinux-to-elf
```

The GUI can also be launched through Flatpak with the documented command:

```bash
flatpak run re.fossplant.vmlinux-to-elf
```

For a source checkout, the README describes installing development hooks, GUI dependencies, synchronizing the project, and installing it in editable tool mode. The project is Python-based and declares Python 3.9 or newer, with optional GUI support through pygobject. The documented `uv sync --extra gui` and `uv tool install -e .[gui]` commands are intended for a development environment rather than a minimal command-line deployment.

## Output quality, limitations, and maintenance boundaries

The strongest feature is the conversion boundary: vmlinux-to-elf takes an image that is difficult for a disassembler to interpret and produces an ELF with recovered symbols. It also exposes intermediate operations, so a user does not have to assume that a failed ELF result means the kernel could not be decompressed.

The largest limitation is inherent in the heuristic design. Base-address inference is based on a selected TEXT symbol, and the README describes this as something that currently seems to work well enough. That wording signals an assumption, not a guarantee. Architecture inference, endianness detection, entry-point selection, and container support can also fail when an image is unusual, modified, packed differently, or built with structures that do not match the scanner's expectations. A generated ELF can look usable while still containing an incorrect analysis base, so reviewers should check those values against known firmware metadata.

The project is not archived, and the last push was on 2026-10-16. Releases 1.3.4, 1.3.5, and 1.3.6 were published in May 2026, including an ARM64 unpacking fix and subsequent fixes. The repository provides multiple installation channels, but the README excerpt does not document a compatibility matrix for every kernel family or a formal upgrade procedure. License information is GPL-3.0-or-later, which has implications for distributing modified versions, but this article does not provide legal advice.

## Conclusion

Adopt vmlinux-to-elf when analyzing Linux kernel images that still contain a recoverable kallsyms table, especially embedded firmware that must be inspected in IDA Pro or Ghidra. Do not assume that ELF recovery or base-address inference is exact for every image. Verify the detected architecture, entry point, base address, recovered symbol names, and original kernel load address before relying on the generated ELF for deeper analysis.

## FAQ

### Can vmlinux-to-elf analyze bzImage and raw kernel files?

Yes. The README lists vmlinux/vmlinuz/bzImage/zImage images, raw binary blobs, and stripped ELF files as accepted inputs. The tool also documents automatic unpacking for the main Linux kernel compression formats.

### What output does vmlinux-to-elf produce?

It produces an ELF file with recovered function and variable symbols. The README identifies IDA Pro and Ghidra as intended analysis tools, including for embedded systems reverse engineering.

### How can I check whether symbols are present before creating an ELF?

Use kallsyms-finder with the input kernel image. The README describes this command as listing symbol addresses only, which makes it a direct first check for kallsyms recovery.

### Does vmlinux-to-elf install a graphical interface?

The uv installation can include the GUI through the `[gui]` extra, while the README also documents Flatpak and Snap installation paths. The command-line package can be installed separately when the GUI is not needed.

### Are the inferred architecture and kernel base guaranteed to be correct?

No. The README describes architecture detection and entry-point inference from symbols, and says base-address inference is based on a selected TEXT symbol. These are heuristics, so the generated ELF should be checked against known image metadata.

## Sources

- [License: GPL-3.0](https://github.com/marin-m/vmlinux-to-elf/blob/master/LICENSE)
- [marin-m/vmlinux-to-elf on GitHub](https://github.com/marin-m/vmlinux-to-elf)
- [Project website](https://fossplant.re/wiki/Main_page)
- [README](https://github.com/marin-m/vmlinux-to-elf/blob/master/README.md)
- [Releases](https://github.com/marin-m/vmlinux-to-elf/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/marin-m-vmlinux-to-elf
