Hacker News new | past | comments | ask | show | jobs | submit login
ELF Statifier, self-contained dynamically linked executables (sourceforge.net)
99 points by turrini on July 12, 2020 | hide | past | favorite | 25 comments



"Statifier take "memory snapshot" of the process, created by loader when loader ALREADY finish relocation and BEFORE loader invoke any INIT function.

What now ? Now this "memory snapshot" should be somehow loaded and run from the point were loader was stopped.

Who will be so kind to do it for us ? Kernel !

Let's save "memory snapshot", i.e. all segments from executable and libraries loaded by loader as ELF file with program's header of type 'LOAD' for each segment, and entry point set to the address, where execution was stopped to take sharpshoot.

In this case, kernel will think, it's a statically linked executable. (Because there is no 'INTERP' segment) As we already know kernel load statically linked executable as following: - load all 'LOAD' segment - jump to the executable's entry point.

That's it !"

So the way it works kills ASLR. But it should be possible to do something similar, keeping all relocations, and that still works with ASLR (but that would need an INTERP).


You can have a statically-linked binary with no INTERP that still uses ASLR, by compiling with "-static-pie". IMO, improvements to statifier should go in that direction, rather than just giving up and using INTERP.


You can theoretically, but there are now segments not covered by a reloc section with the way stratifier is currently working. Unless it builds those too and I'm missing it somehow...


This sounds a lot like emacs' old "undump" system, which ran the program, loaded a pile of elisp code, made itself dump core, then tried to massage the core dump into a runnable program.

Emacs ended up dropping that system because it was wildly incompatible with aspects of modern systems.


Modern Emacs (27 and up I think) has a new so-called "portable dumper"[^1]. I've only played a little bit with it, but it does ridiculously speed speed up some things. Don't really need it, but it's cool anyways.

[^1]: https://dancol.org/pdumperpres.pdf


For modern systems there is AppImage.


Emacs' crazy loader fiddling wasn't really a "packaging strategy."


That's what I was thinking. We've come full circle;-) Besides Emacs there is other software from that era that uses this technique: TeX comes to mind and also at least some Lisps.


The title should probably have a (2016), that's the last release.

Sounds useful if you have to work with some limited/restricted systems where you cannot just install something.

However, the listed limitations sound like a blocker in every somewhat modern distro. No ASLR, no VDSO. ASLR can be disabled temporarily or for selected processes, but disabling VDSO is not easy without reboot I believe (have never tried)

Did not understand whether the limitations apply to source or target system or both.

Maybe there is a reason that this promising tool is not well-known? Or does anybody here use it?


Perhaps un-setting envvar AT_SYSINFO_EHDR would disable VDSO for a selected process without reboot?


That's not a commonly set environment variable. So unsetting it is not an option.


What about the -static compiler option? Why it's not good enough? Is it possible to fix its shortcomings?


The main issue with -static is that glibc is a massive PITA that hates being statically linked due to its reliance on dlopen() for locale and NSS management. It's therefore not recommended linking it anything but dynamically and afaik there is no "pick all static but libc" option in Clang or GCC. The other option is using an Alpine chroot and statically link using musl, but there are lots of compatibility issues with certain programs that massively abuse of GNUisms (i.e see anything ever written by Pöttering) and not every library has a .a available in the package manager, so you must compile them also.


Yep. The glibc tries very hard to avoid static linking (since the infamous times of Ulrich Drepper). It is almost as if they hated static linking for some personal reasons, and then they artificially add the NSS and locale excuses that make it impossible.

Yet you can still compile a static executable that calls the dlopen function. And you can also select (by using some -B and -W magic options) exactly which libraries you want to link statically and dynamically on your executable. It is a bit painful but it works. The only thing that does not work is when you rely on GPU code, where your program needs to be linked directly to specific graphics drivers. I hope in a few years the kernel itself will allow a gpu abstraction for that to work.

Great point about musl. To distribute (your) program as a linux static binary, write it in standard C and compile it using musl.


> It is a bit painful but it works.

That's an understatement... especially if you're using autotools with libtool. Which, coincidentally, seems to be unmaintained. I tried submitting a patch on their GNU Savannah[1], and it's soon celebrating its second birthday... last official release in 2015...

And yet this is the "GNU standard" which a huge part of the packages found on an average Linux install - especially the smaller and more foundational pieces - are built with. It's mindbogglingly sad.

[1] https://savannah.gnu.org/patch/?9687


> especially if you're using autotools with libtool.

Then you had it coming!

I do not understand why, in this day and age, the autotools shitfuckery is still necessary. You can write a portable makefile that will compile your program on all widespread unixes (linux distros, all the BSDs and macOS). Using CI tools you can verify in a few minutes whether it compiles correctly everywhere. The autotools and cmake systems are most often useless cruft (except if you want to compile on windows, in that case cmake is probably inevitable).


statifier works on executable files that have already been compiled. See http://statifier.sourceforge.net/statifier/man/statifier.1.h...


This tool works on an existing binary without needing to rebuild it from source.


An executable zip file would solve 90% of the need for a containerized or static executable. Extract zip (app + dependencies) to /var/cache/exezip/<SHA256>/, do whatever complicated pre-execution-song-and-dance you need to transparently locate files there, and execute. Pile on features as desired.

From a portability standpoint, the above could be done with zero OS-specific dependencies, and you could add features depending on the OS. By default you just run the executable with modified environment variables to try to automatically locate things like libraries and other binaries automatically. Then you add chroot, overlayfs, namespaces, control groups, etc as they are available to improve compatibility.


Personally I wouldn’t like running some downloaded binary without at least some kind of sand box around it.


Why? Every sandbox that has ever existed has been exploited/broken out of, including VMs. Only explicit security controls like RBACs (ex. SELinux) can create a secure runtime environment, if you configure them right.

It's much, much easier to just download a binary and compare its cryptographic hash with the origin's before running it. That's how all Linux distributions ship apps, and Windows has a slightly more modern version of that.


Linux distributions ship artifacts from building open source projects, often they’re even built in a deterministic way so that third parties can verify that they haven’t been tampered with.

Closed binaries tend to come from corporations and are often full of nasty things, wether the hash verifies or not isn’t the problem.


Presumably if the output size is a problem, the binary can be further processed with upx.


How does this compare with the flatpak/snap strategy of mounting a filesystem?


flatpak/snap still rely on libraries. This only relies on filesystem features and kernel functions which are, for all intents and purposes, 'static' (because of the "Never break userspace" policy). As such, the resulting binaries (stripped of GNU_* symbols) can run on a musl system. I've had a lot of trouble getting flatpak programs to run on my musl system.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: