Tech News
← Back to articles

ELF Crimes: Program Interpreter Fun

read original related products more articles

ELF Crimes: Program Interpreter Fun

December 21, 2025

For reasons I don't even remember, I was reading about the details of the ELF executable format, and stumbled across the program interpreter functionality used for dynamic linking. Immediately I was struck by one of the more cursed and yet simultaneously pedestrian ideas I've had, but we'll get back to that.

For those unacquainted (because who is?), the ELF standard specifies a PT_INTERP type of program segment, which is what makes dynamic linking work. The PT_INTERP segment contains a single string that specifies a hardcoded path to the dynamic linker/loader (the interpreter ), typically /lib64/ld-linux-x86-64.so or such. When present, it tells the OS loader that the program can't be executed as-is. It first needs to run the dynamic linker found at that path, which will go load all the dynamic libraries into memory and then update the addresses referenced by the executable to the libraries' locations in memory. Then it can run the original executable like would've normally been done by the OS loader.

But wait, we're getting ahead of ourselves. The above is a description of what the dynamic linker does holistically. The ELF interpreter functionality in particular is much much simpler: after the to-be-interpreted executable is loaded into memory, the OS then loads the interpreter executable into the same process address space, and executes the interpreter's code. That's literally it; the OS doesn't invoke the interpreter specially, it doesn't expect the interpreter to have any specific behavior or functionality, it doesn't even expect the to-be-interpreted executable to ever be run. It just loads both executables and expects the interpreter to do everything else that needs to be done.

This opens up some… interesting possibilities. For instance, imagine using ELFs as a data storage format, where you can directly run them to open them in the program, no need for any of that gosh dang xdg-open or MIME types based off of file extension or any of that nonsense! Or now your programming language's bytecode is on equal footing with natively compiled languages! Clearly it's such a good idea, I can't see why seemingly no one has ever done this before (and written about it)!

Now, the ELF designers did seem to envision some other uses since they used the generic term interpreter rather than something specific to linking; but I assume they were imagining something, you know, sensible XD. Even bytecode is a step too far I think, since it'd still be solely cross-platform data needlessly put in a native executable shell.

But of course I would be a Fool to let anything like being sensible stop my grand plans!

Trying It

After conceiving of this idea, for some reason my first thought was not to use a linker script, or even to write a program to generate an ELF from scratch. Instead, I decided to write an ELF by hand in a hex editor! Genius!

... continue reading