Skip to main content
01.03.2026

Recovering Symbols from a Stripped Linux Kernel

Kernel Symbols Recovery

Quick Reference:

# Install vmlinux-to-elf
pipx install vmlinux-to-elf

# Convert stripped kernel to analyzable ELF
vmlinux-to-elf vmlinuz output.elf

# Extract from compressed kernel
vmlinux-to-elf bzImage output.elf

# Extract from Android boot image
vmlinux-to-elf boot.img output.elf

When debugging kernel panics or analyzing embedded firmware, you often encounter stripped kernel binaries with no debug symbols. Stack traces show hex addresses instead of function names. Traditional tools like nm and objdump report nothing useful.

But there's a hidden treasure inside almost every Linux kernel: kallsyms, a compressed symbol table that survives stripping.

What is kallsyms?

The Linux kernel maintains an internal symbol table called kallsyms (kernel all symbols). It exists primarily for:

  • Printing readable kernel oops/panic messages
  • /proc/kallsyms for debugging and profiling tools
  • Stack trace symbolization

Even when distributors strip debug symbols from the kernel binary, kallsyms remains embedded because it's needed at runtime.

The vmlinux-to-elf Tool

vmlinux-to-elf is a Python tool that extracts kallsyms from any kernel image and produces a proper ELF file with symbols restored.

Installation

# Using pipx (recommended)
pipx install vmlinux-to-elf

# Using uv
uv tool install vmlinux-to-elf

# From source
git clone https://github.com/marin-m/vmlinux-to-elf
cd vmlinux-to-elf
pip install -e .

Basic Usage

Convert a stripped kernel to an analyzable ELF:

# From raw vmlinux
vmlinux-to-elf /boot/vmlinuz-$(uname -r) kernel.elf

# From compressed bzImage
vmlinux-to-elf /boot/bzImage kernel.elf

# From Android boot.img
vmlinux-to-elf boot.img kernel.elf

The output ELF file contains all recovered symbols and can be loaded into:

  • IDA Pro for static analysis
  • Ghidra for free reverse engineering
  • GDB for debugging
  • addr2line for crash analysis

How kallsyms Works

The kallsyms table contains tuples of:

  • Symbol address
  • Symbol type (T for text, D for data, etc.)
  • Symbol name (compressed)

The compression is simple: common substrings in symbol names are replaced with single-byte tokens. A token table maps these bytes back to string fragments.

kallsyms Structure

Array Purpose
kallsyms_addresses Array of symbol addresses
kallsyms_num_syms Total symbol count
kallsyms_names Compressed symbol names
kallsyms_markers Lookup table for fast access
kallsyms_token_table String fragments for decompression
kallsyms_token_index Offsets into token table

vmlinux-to-elf finds these structures through heuristics, handles various kernel versions (including 6.4+ layout changes), and correctly decompresses the symbol names.

Practical Use Cases

Debugging Kernel Panics

When you get a panic with raw addresses:

[  123.456789] BUG: unable to handle kernel NULL pointer dereference
[  123.456790] IP: 0xffffffffa1234567
[  123.456791] Call Trace:
[  123.456792]  0xffffffffa1234890
[  123.456793]  0xffffffffa1234abc

Extract symbols and resolve:

# Extract symbols
vmlinux-to-elf /boot/vmlinuz-$(uname -r) kernel.elf

# Resolve addresses
addr2line -e kernel.elf 0xffffffffa1234567
# Output: do_something+0x47/0x100

# Or use nm to find nearby symbols
nm kernel.elf | grep -i "a123"

Firmware Analysis

Embedded devices ship with stripped kernels. Extract from firmware:

# Extract kernel from firmware image
binwalk -e firmware.bin

# Find the kernel
file _firmware.bin.extracted/*
# Look for: Linux kernel ARM boot executable

# Convert to ELF
vmlinux-to-elf _firmware.bin.extracted/vmlinux kernel.elf

# Analyze in Ghidra
ghidraRun kernel.elf

Security Research

Analyzing kernel exploits requires understanding the kernel's memory layout:

# Get symbol addresses for ROP gadgets
nm kernel.elf | grep prepare_kernel_cred
# ffffffff810a1234 T prepare_kernel_cred

nm kernel.elf | grep commit_creds
# ffffffff810a5678 T commit_creds

Reading /proc/kallsyms Directly

On a running system with root access, you can read symbols directly:

# All kernel symbols
sudo cat /proc/kallsyms

# Find a specific function
sudo cat /proc/kallsyms | grep do_sys_open
# ffffffff812345678 T do_sys_open

# Count symbols by type
sudo cat /proc/kallsyms | awk '{print $2}' | sort | uniq -c

Symbol types follow the nm convention:

Type Meaning
T/t Text (code) section
D/d Data section
B/b BSS (uninitialized data)
R/r Read-only data
A Absolute address

Uppercase means global, lowercase means local.

Kernel Configuration

kallsyms is controlled by kernel config options:

CONFIG_KALLSYMS=y           # Enable kallsyms
CONFIG_KALLSYMS_ALL=y       # Include all symbols (not just functions)
CONFIG_KALLSYMS_ABSOLUTE_PERCPU=y  # Use absolute addresses
CONFIG_KALLSYMS_BASE_RELATIVE=y    # Use relative offsets (saves space)

Most distributions enable CONFIG_KALLSYMS by default. Check your kernel:

zcat /proc/config.gz | grep KALLSYMS
# Or
cat /boot/config-$(uname -r) | grep KALLSYMS

Limitations

kallsyms has some limitations:

  • No type information: Only names and addresses, no function signatures
  • No local variables: Only global symbols
  • May be disabled: Some hardened kernels disable kallsyms
  • Address randomization: KASLR shifts addresses at boot (use /proc/kallsyms for runtime addresses)

For full debug info, you need the original vmlinux with DWARF symbols, typically from kernel debuginfo packages:

# Debian/Ubuntu
apt install linux-image-$(uname -r)-dbgsym

# RHEL/CentOS
debuginfo-install kernel

# Fedora
dnf debuginfo-install kernel

Automating Symbol Resolution

Create a script for batch address resolution:

#!/bin/bash
# resolve-addrs.sh - Resolve kernel addresses from log

KERNEL_ELF=${1:-kernel.elf}
LOG_FILE=${2:-/var/log/kern.log}

grep -oE '0x[0-9a-f]+' "$LOG_FILE" | sort -u | while read addr; do
    symbol=$(addr2line -f -e "$KERNEL_ELF" "$addr" 2>/dev/null | head -1)
    if [ "$symbol" != "??" ]; then
        echo "$addr -> $symbol"
    fi
done
  • crash - Kernel crash dump analyzer
  • drgn - Programmable debugger for kernel analysis
  • bpftrace - Dynamic tracing using eBPF
  • perf - Performance analysis with symbol resolution

Conclusion

kallsyms is a powerful feature that enables kernel debugging even on stripped binaries. Tools like vmlinux-to-elf make it accessible for security researchers, SRE teams, and embedded developers who need to understand kernel behavior without source access.

Next time you face a cryptic kernel panic, remember: the symbols are probably still in there.


Need to automate kernel debugging and incident response? Akmatori AI agents can analyze crash dumps, resolve symbols, and diagnose issues automatically.

Automate incident response and prevent on-call burnout with AI-driven agents!