elf

package
v1.2.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 19, 2025 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Parses an ELF binary providing additional details vs. debug/elf

Errors:

All errors returned will be of the type ErrElf.

Usage:

Construct a new Elf struct with elf.New

bin, err := elf.New(path)

bin is an Elf with the following structure:
{
	Name: base filename
	Path: absolute path
	Class: 32-bit or 64-bit?
	Type: EXE, BIN, PIE, ...
	Interpreter: path to requested interpeter
	Dependencies: slice of paths to dependencies as identified and found by the interpreter
}

Note:

Only accepts static binaries or dynamic binaries which use ld-linux*.so as the interpreter

Index

Constants

View Source
const (
	ELFNONE = debug_elf.ELFCLASSNONE // 0
	ELF32   = debug_elf.ELFCLASS32   // 1
	ELF64   = debug_elf.ELFCLASS64   // 2
)
  • Values for [EI_CLASS]

Values for [EI_CLASS]

View Source
const (
	UNDEF = 0 // Undefined
	EXEC  = 1 // Executable: Use Elf.IsExe() to catch _any_ type of executable (including PIE)
	DYN   = 2 // Dynamic: Use Elf.IsDyn() to catch _any_ type of dynamically linked binary (including ET_EXEC with Dyn table)
)
  • Bitmask values for [Type]

Bitmask values for [Type]

Think carefully before directly comparing to bitmask (2^n) values. See value descriptions for individual hints.

View Source
const (
	DYNEXE = 3 // EXEC + DYN (PIE or ET_EXEC with Dynamic table)
)

Meaningful combination values for [Type]

Variables

View Source
var (
	// Error returned when the provided file is not a valid Elf.
	ErrInvalidElf = errors.New("invalid ELF file")
	// Error wrapping a failure when calling `ld-linux*.so` (like `ldd`) to identify dependencies
	ErrLdd = errors.New("ldd failed to execute")
)
  • Primary Errors

Primary Errors

View Source
var (
	// Error returned if dynamic ELF has a bad entry for the interpreter
	ErrBadInterpreter = fmt.Errorf("%w: bad interpreter", ErrInvalidElf)
	// Error returned if the ELF is not a type we support (currently only ET_EXEC & ET_DYN)
	ErrUnsupportedElfType = fmt.Errorf("%w: %w (unsupported ELF Type)", ErrInvalidElf, errors.ErrUnsupported)
	// Error returned if the interpreter is not `ld-linux*.so`
	ErrUnsupportedInterpreter = fmt.Errorf("%w: %w (unsupported interpreter)", ErrInvalidElf, errors.ErrUnsupported)
)
  • Specific errors which wrap [ErrInvalidElf]

Specific errors which wrap [ErrInvalidElf]

Functions

This section is empty.

Types

type Elf

type Elf struct {
	// The filename
	Name string
	// Absolute, fully resolved path to the file
	Path string
	// 32 or 64 bit?
	//  - See https://man7.org/linux/man-pages/man5/elf.5.html#:~:text=.%20%20(3%3A%20%27F%27)-,EI_CLASS,-The%20fifth%20byte
	Class EI_CLASS
	// Simplified based on ET_DYN & DynFlag1
	Type Type
	// Absolute path to the interpreter (if executable), "" if not executable.
	//  - See https://gist.github.com/x0nu11byt3/bcb35c3de461e5fb66173071a2379779 for much more background
	Interpreter string
	// All requested libraries
	Dependencies []string
}

A parsed Elf binary

func New

func New(path string) (Elf, error)

Construct a new Elf for the file located at path, any error will be an ErrElf

  • Returns a best-effort result on error
  • Returns early if errors are encountered in resolving the Path or in initial parsing by debug_elf.Open, in this case Name & Path will be filled, although Path may not be fully resolved
  • If errors are encountered in parsing these will be collected in the returned ErrElf and the result will contain as much valid information as possible

func (Elf) Diff

func (e Elf) Diff(o Elf) []string

Deeply check for diffs between two `Elf`s. Ignores differences in the Path, as long as:

  1. Both `Path`s are absolute
  2. Both `Path`s end in the same filename

func (*Elf) IsDyn

func (e *Elf) IsDyn() bool

Is this ELF dynamically linked?

func (*Elf) IsExe

func (e *Elf) IsExe() bool

Is this ELF **primarily** an executable.

  • This will return `false` in cases such as `/lib64/ld-linux-x86-64.so.2` which has an entry point and _may_ be `exec()`'ed but is primarily designed as a library and therefore not `ET_EXEC` or `PIE`

func (*Elf) IsLib

func (e *Elf) IsLib() bool

Is this ELF **primarily** a library?

  • If it's not **primarily** an executable, then it's a library (Slightly simplified but good enough for our case)

type ErrElf

type ErrElf struct {
	// contains filtered or unexported fields
}

All errors returned will be of the type ErrElf.

  • ErrElf can store multiple errors for a single Elf struct. Use .Join() to add an error.
  • Will not == nil, even if empty. Use .IsEmpty() to check and then manually return (something, nil)

To extract the path use errors.As followed by .Path()

var errelf *ErrElf
if errors.As(err, &errelf) {
     errelf.Path()
}

.

func (*ErrElf) Error

func (e *ErrElf) Error() string

func (*ErrElf) IsError

func (e *ErrElf) IsError() bool

Does this ErrElf contain any errors?

func (*ErrElf) Join

func (e *ErrElf) Join(err error)

Add an error to the ErrElf

func (*ErrElf) Path

func (e *ErrElf) Path() string

The path of the Elf which this ErrElf describes

func (*ErrElf) Unwrap

func (e *ErrElf) Unwrap() []error

type Type

type Type byte

Binary type

Think carefully before directly comparing to bitmask (2^n) values. See value descriptions for individual hints.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL