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.
Show HN: ELF Injector
github.com
1–10 of 14 posts
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.
Show HN: ELF Injector
github.com
How many different target ELFs have you tried it with, and are there any that don't work?
One of the challenges of ELF injection/infection is that you might break assumptions made by the original ELF regarding its layout, particularly for dynamic ELFs (which often parse .dynamic at runtime, etc.) 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.
ATOM could inject code before or after any basic block in a program: https://dl.acm.org/doi/abs/10.1145/178243.178260 . The general technique, IIRC, was to replace the first instruction of the basic block with a jump to code that contained your new code and then the overwritten instructions, and then jump back into the original 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.
ATOM could inject code before or after any basic block in a program: https://dl.acm.org/doi/abs/10.1145/178243.178260 . The general technique, IIRC, was to replace the first instruction of the basic block with a jump to code that contained your new code and then the overwritten instructions, and then jump back into the original code.
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.
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.
Always cool to see people hacking ELF! I see you're using argv[0] to find the executable file. This is fragile because argument vector contents are arbitrary and controlled entirely by the parent process. In other words, argv[0] could contain anything, even an empty string. If you're targeting Linux specifically, there's a better way: /proc/self/exe. I created something similar to your tool: an ELF embedder. It's for…
Thanks for sending your link, I'll take a look.