Note that there are some explanatory texts on larger screens.

plurals
  1. POLoading ELF shared library and custom binfmt executable into same Linux address space
    primarykey
    data
    text
    <p>I am working on a project to load and run a custom binary format executable (PE, in my case) on a Linux platform. I've done this pretty successfully so far by first loading the executable and then loading a small ELF shared library that calls the start address of the executable and then exits safely.</p> <p>I would really like not doing the ELF loading myself for a few reasons, though. First, the shared library I use is written in assembly (I can't use anything else because I'm not linking to <code>libc</code>, etc.), which will be very platform-specific, and I'd like to move away from that and use C so I can compile for any platform. Also, it will be easier and safer to use Linux's native ELF loader instead of my own simplified version.</p> <p>I'm wondering if there is a way to use my binfmt handler, an installed kernel module, to load my executable and <em>then</em> ask Linux to load my shared library (and its dependencies) into the same address space without overwriting my executable code. I first thought that the <code>uselib</code> syscall might be useful, but the description on the man page is unclear about whether or not this will serve my purposes:</p> <blockquote> <p>From libc 4.4.4 on only the library "/lib/ld.so" is loaded, so that this dynamic library can load the remaining libraries needed (again using this call). This is also the state of affairs in libc5.</p> <p>glibc2 does not use this call.</p> </blockquote> <p>I've also never seen an example of its use, and I'm always wary of using syscalls that I don't understand.</p> <p>Is there a good way to achieve what I've described? Can I use Linux's existing capabilities to load a shared library (written in C) into an address space already containing executable code, and, if so, how can I use that library without knowing where it has been loaded?</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. COWell, you could flip the problem around entirely. Instead of adding PE support to the kernel, instead provide a PE loader (that is an ELF executable) that runs in user-space. You might get some problems with page protections faults (trying to write to an executable page), but in that case, you can make a kernel module that allows your application to create a new executable page in you application. Basically, create a kernel mod that can load a PE executable like a PE shared lib.
      singulars
    2. CO@Linuxios I tried that at first, but I ran into problems with the PE code having a fixed address, which happened to be the default Linux load address; if I forced the `mmap`, then the whole thing would crash because I was overwriting executing code in memory. I switched to using a kernel module for loading when userspace didn't seem like an option anymore; it's basically an analog for the ELF loader, and the ELF code I want to run (from the shared library) is the analog of the ELF interpreter.
      singulars
    3. COI see. Now, here's a thought: Still load an elf binary, but tell GCC to create position independent code. Then, there has to be some sort of header to tell Linux at what address to load your elf code, leaving the PE address free.
      singulars
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload