Remix.run Logo
mdavid626 13 hours ago

You can "package" all .so files you need into one file, there are many tools which do this (like a zip file).

But you can't take .so files and make one "static" binary out of them.

geocar 9 hours ago | parent | next [-]

> But you can't take .so files and make one "static" binary out of them.

Yes you can!

This is more-or-less what unexec does

- https://news.ycombinator.com/item?id=21394916

For some reason nobody seems to like this sorcery, probably because it combines the worst of all worlds.

But there's almost[1] nothing special about what the dynamic linker is doing to get those .so files into memory that it can't arrange them in one big file ahead of time!

[1]: ASLR would be one of those things...

mdavid626 6 hours ago | parent [-]

What if the library you use calls dlopen later? That’ll fail.

There is no universal, working way to do it. Only some hacks which work in some special cases.

geocar 4 hours ago | parent [-]

> What if the library you use calls dlopen later? That’ll fail.

Nonsense. xemacs could absolutely call dlopen.

> There is no universal, working way to do it. Only some hacks which work in some special cases.

So you say, but I remember not too long ago you weren't even aware it was possible, and you clearly didn't check one of the most prominent users of this technique, so maybe you should also explain why I or anyone else should give a fuck about what you think is a "hack"?

fc417fc802 11 hours ago | parent | prev [-]

Well not a static binary in the sense that's commonly meant when speaking about static linking. But you can pack .so files into the executable as binary data and then dlopen the relevant memory ranges.

mdavid626 11 hours ago | parent [-]

Yes, that's true.

But I'm always a bit sceptical about such approaches. They are not universal. You still need glibc/musl to be the same on the target system. Also, if you compile againt new glibc version, but try to run on old glibc version, it might not work.

These are just strange and confusing from the end users' perspective.

toast0 6 hours ago | parent [-]

> But I'm always a bit sceptical about such approaches. They are not universal. You still need glibc/musl to be the same on the target system. Also, if you compile againt new glibc version, but try to run on old glibc version, it might not work.

Why would you include most of your dynamic libraries but not your libc?

You could still run into problems if you (or your libraries) want to use syscalls that weren't available on older kernels or whatever.

mdavid626 6 hours ago | parent [-]

You can include it, but

- either you use chroot, proot or similar to make /lib path contain your executable’s loader

- or you hardcode different loader path into your executable

Both are difficult for an end user.

toast0 6 hours ago | parent [-]

This isn't that hard (that's not to say this is easy, it is tricky). Your executable should be a statically linked stub loader with an awful lot of data, the stub loader dynamically links your real executable (and libraries, including libc) from the data and runs it.

fc417fc802 5 hours ago | parent [-]

To add to this, in case of any remaining confusion. You can implement your own execve in userspace. [0] But the kernel's execve is a piece of machinery that invokes the loader so obviously it follows that you're free to make any changes you'd like to the overall process.

Bonus points if you add compression or encryption and manage to trip a virus scanner or three. [1]

[0] https://grugq.github.io/docs/ul_exec.txt

[1] https://blackhat.com/presentations/bh-usa-07/Yason/Whitepape...