Show HN: ELF Injector
37 dillstead 12 7/29/2025, 3:00:02 PM github.com ↗
The ELF Injector allows you to "inject" arbitrary-sized relocatable code chunks into ELF executables. The code chunks will run before the original entry point of the executable runs.
Included in the project are sample chunks as well as a step-by-step tutorial on how it works.
It's a mix of C and assembly and currently runs on 32-bit ARM though it's easy to port to other architectures.
I also made my code execute before the entry point by specifying it as DT_INIT in the dynamic section. This way you don't have to modify the entry point pointer or call it after your unpacking stub is done decompressing the binary in memory.
Your solution with the the thunk is much better and probably avoids a lot of the complexity I encountered in moving segment headers around! Elf is a tight format unlike PE. Not a single byte goes to waste.
Thanks for sharing your project, I learned something today!
PS one interesting piece of trivia I found was that you could strip the section header entirely from an Elf file and the OS would still load and execute it. All it needs is the segment headers. It looks like the section headers are just there as a courtesy to help tools like strip and objcopy.
I had to make sure that I always inserted a page size multiple of bytes into the executable which can add up to a page of unused padding in addition to the thunk and chunk.
How many different target ELFs have you tried it with, and are there any that don't work?
I was careful to only inject the thunk (the code that loads the actual relocatable code chunk the the user injects) into the available padding at the end of the text segment, injecting anything larger runs the risk of "sliding" the next segment (usually the data segment) over thereby breaking references to static data from code.
Most of the these projects (often intended as packers or similar obfuscation techniques for malware) that I've seen are cool but get flagged aggressively.
I created something similar to your tool: an ELF embedder. It's for arbitrary data rather than native code injection.
I leveraged ELF segments to get the kernel to mmap the data into memory on my behalf, no file I/O needed. The auxvec allows the program to reach its own program header table. From there it's just a matter of finding the right segment.
https://www.matheusmoreira.com/articles/self-contained-lone-...
My programming language's interpreter introspects into its own ELF header, finds the embedded segments and uses them to load data and code from inside itself.
I'm not entirely sure whether this approach is applicable to your case but it might be worth a try. My embedding tool could just as easily map in executable segments.
But even if /proc/self/exe is visible, it might not be possible to open it. For example, you can execute a binary residing in anonymous memory (memfd) using fexecve(2), or the executable file could have been deleted immediately after execution. AFAIU, /proc/self/exec is generated as a symlink rather than exposing the file object directly (cf. BSD /dev/fd), so opening it can fail.
The easy fix is to just simply fail if argv[0] is NULL or empty, but if one is a glutton for punishment and wants to be "robust", /proc/self/exe support could be added as a (preferred) alternative rather than a substitute mechanism.
Thanks for sending your link, I'll take a look.