
ELF Statifier, self-contained dynamically linked executables - turrini
http://statifier.sourceforge.net/
======
glandium
_" 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).

~~~
josephcsible
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.

~~~
monocasa
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...

------
JoshTriplett
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.

~~~
app4soft
For modern systems there is AppImage.

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

------
usr1106
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?

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

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

------
peterwwillis
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.

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

~~~
peterwwillis
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.

~~~
swiley
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.

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

~~~
qalmakka
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.

~~~
enriquto
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.

~~~
eqvinox
> 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](https://savannah.gnu.org/patch/?9687)

~~~
enriquto
> 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).

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

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

~~~
fao_
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.

