-jailshell: d-linux-x86-64.so.2: bad ELF interpreter: No such file or directory
I'm trying to install an executable but it gives me the error
This executable is corrupt.
It is trying to use d-linux-x86-64.so.2
as an interpreter, and such a file doesn't exist (nor should it exist) on your machine.
Chances are this executable was transferred over FTP in ASCII
mode, or corrupted in some other way.
I have already checked if I have the glib 32-bit version
That is irrelevant: the binary you are trying to build is a 64-bit binary.
Also, there is a difference between glib and glibc.
Why is ld.so a shared object?
Can a dynamic linker be a simple ELF executable (ET_EXEC) ?
Yes, it can.
However, an ET_EXEC
must be loaded at the address it was linked at, and that address may conflict with the address at which a.out
itself is linked. If such conflict happens, the kernel will either kill the process before it even starts, or it will mmap
a.out
"on top of" ld.so
, and the resulting binary will crash.
You can move ld.so
out of the way of usual a.out
link address, but someone can always link a.out
at un-usual address.
If instead you link ld.so
as ET_DYN
, with load address of zero, then none of the above problems could happen.
patchelf set interpreter to a path relative to executable
You need to specify the path relative to the current working directory (the one you use to execute the program) and not relative to the directory that contains the binary file.
echo 'int main() { return 0; }' > main.c
gcc -Wl,--dynamic-linker=./lib/ld-linux-x86-64.so.2 -o main main.c
mkdir bin
mkdir lib
cp /lib64/ld-linux-x86-64.so.2 lib/
cp main bin/
bin/main # this should run without problems
cd bin; ./main # this throws a "No such file or directory" error
Can `dlopen` be used to load and mmap a static ELF executable (not library)?
If file anexe is static compiled, no symbols, no exports, ELF, can dlopen("anexe", RTLD_LAZY) be used to map it into memory?
No (but see below).
My goal isn't to be able to reference symbols -- there are no symbols. Rather, my goal is to be able to call its functions given their addresses (which are fixed, not PIC), and to read its data given address.
Note that a non-PIE executable can only be loaded at the address it was linked at. You can find which address that is by examining its program headers (programmatically, or with readelf -Wl
).
Once you know which address it should be loaded at (and assuming that address is not already occupied by your own executable), then you can perform a series of mmap
calls to "load" that executable into memory, and after that you can call its functions and read its data.
One complication is that the executable's initializers will not have run (you didn't call its _start
, nor would you want to), and so functions in it may not run correctly, may crash, etc.
For example, given this binary:
$ echo "int main() { return 0; }" | gcc -xc - -static -no-pie -o a.out
$ readelf -Wl a.out | egrep 'Type|LOAD'
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x000000 0x0000000000400000 0x0000000000400000 0x000518 0x000518 R 0x1000
LOAD 0x001000 0x0000000000401000 0x0000000000401000 0x07fd01 0x07fd01 R E 0x1000
LOAD 0x081000 0x0000000000481000 0x0000000000481000 0x026660 0x026660 R 0x1000
LOAD 0x0a7928 0x00000000004a8928 0x00000000004a8928 0x0059c8 0x007298 RW 0x1000
you would need to perform 4 mmap
calls (one for each LOAD
segment), with MAP_FIXED
. The address, file offset, size and protection arguments for mmap
are obvious.
The mmap
arguments for the last segment may not be: you would need to round address and offset down to Align
, and extend the size by 0x928
to account for that rounding.
Using $ORIGIN to specify the interpreter in ELF binaries isn't working
If I specify an absolute path instead of using $ORIGIN then it seems to work fine.
This is working as intended.
It is the dynamic linker that interprets (expands) $ORIGIN
and other special tokens.
The Linux kernel doesn't.
And it is the kernel that reads PT_INTERP
segment of the main executable and (if present) loads and invokes the interpreter (the dynamic linker). When you set interpreter to non-existant path (such as $ORIGIN/lib/ld-linux-x86-64.so.2
), you get ENOENT
from the kernel execve
system call.
There is no way to make interpreter itself be anything other than valid path.
Depending on what you are actually trying to achieve, rtldi may be the answer.
Where is segment %fs for static elf images setup?
You need to call arch_prctl
with an ARCH_SET_FS
argument before you can use the %fs
segment prefix. You will have to allocate the backing store somewhere (brk
, mmap
, or an otherwise unused part of the stack).
glibc does this in __libc_setup_tls
in csu/libc-tls.c
for statically linked binaries, hidden behind the TLS_INIT_TP
macro.
Multiple glibc libraries on a single host
It is very possible to have multiple versions of glibc on the same system (we do that every day).
However, you need to know that glibc consists of many pieces (200+ shared libraries) which all must match. One of the pieces is ld-linux.so.2, and it must match libc.so.6, or you'll see the errors you are seeing.
The absolute path to ld-linux.so.2 is hard-coded into the executable at link time, and can not be easily changed after the link is done (Update: can be done with patchelf; see this answer below).
To build an executable that will work with the new glibc, do this:
g++ main.o -o myapp ... \
-Wl,--rpath=/path/to/newglibc \
-Wl,--dynamic-linker=/path/to/newglibc/ld-linux.so.2
The -rpath
linker option will make the runtime loader search for libraries in /path/to/newglibc
(so you wouldn't have to set LD_LIBRARY_PATH
before running it), and the -dynamic-linker
option will "bake" path to correct ld-linux.so.2
into the application.
If you can't relink the myapp
application (e.g. because it is a third-party binary), not all is lost, but it gets trickier. One solution is to set a proper chroot
environment for it. Another possibility is to use rtldi and a binary editor. Update: or you can use patchelf.
Related Topics
Apache Cgi in User Directory "End of Script Output Before Headers"
Command to Measure Tlb Misses on Linux
Is There an Equivalent to Dbus on Osx
Set Environment Variables in an Aws Instance
Matlab - Run File Without Opening Gui, Then Quit
Gnu Linker: Alternative to -Version-Script to List Exported Symbols at The Command Line
How to Check Character Encoding of a File in Linux
Do I Need to "Enable" a Pcie Memory Region in a Linux 3.12 Driver
Opening Default Text Editor in Bash
How to View Svn Diff in Vimdiff Style in Svn
Executing Exe or Bat File on Remote Windows Machine from *Nix
What's The Purpose of Mmap Memory Protection Prot_None
Surprise! The Shell Suggests Command Line Switches
Openssl/Rsa - Using a Public Key to Decrypt
How to Set Control Register 0 (Cr0) Bits in X86-64 Using Gcc Assembly on Linux
Get Unique Serial Number of Usb Device Mounted to /Dev Folder