How to make static linked ELF file to load LD_PRELOAD .so
How could i create fake dummy dynamic segment to activate dynamic loader and perform LD_PRELOAD command?
You can't.
Even if you could, getting LD_PRELOAD
to preload something would still be useless: usually you want to interpose some symbols in your LD_PRELOAD
ed library, but that requires these symbols to be unresolved in the main binary, or at least exported in its dynamic symbol table. A statically linked executable doesn't have any unresolved symbols, nor a dynamic symbol table by definition.
Convert a statically linked elf binary to dynamically linked
What you are attempting is not possible in any automated way. At the time of static linking, all relocation information identifying calls to libc as calls to libc has been resolved and removed. If debugging symbols exist in the binary, it's possible to identify "this range of bytes in the text segment corresponds to such-and-such libc function", but there is no way to identify references to the function, which will be embedded in the instruction byte stream with no markup to identify them. You could use heuristics based on disassembly, but they would be incomplete and unreliable (possibility of both false negatives and false positives).
As far as shifting offsets, you absolutely cannot change anything about the load addresses for a static linked binary. If you need to insert headers before the load segments, you'd have to insert a whole page, and update the file offsets in the program header table (adding 1 page to them) while leaving the virtual address load offsets the same. However, since what you're trying to do is not possible overall, the offset-shifting issue is the least of your worries.
Perhaps, if the program doesn't require high performance, you could run it under qemu app-level emulation, with qemu going through the sockets emulation/wrapper.
Is it possible to override main method using LD_PRELOAD?
No, you cannot use LD_PRELOAD
to override the main
function of a binary.
LD_PRELOAD
A whitespace-separated list of additional, user-specified, ELF
shared libraries to be loaded before all others. This can be
used to selectively override functions in other shared
libraries. For setuid/setgid ELF binaries, only libraries in
the standard search directories that are also setgid will be
loaded.
What LD_PRELOAD gives you is the ability to inject symbols that are dynamically linked so that when the runtime linker goes to resolve them, it finds your replacement instead of the one it'd normally find. Let's take this example:
main.c:
#include <stdio.h>
int main (void)
{
puts("Hello, world!");
return 0;
}
puts.c
#include <stdio.h>
int puts (const char *s)
{
return printf("Hijacked puts: %s\n", s);
}
If compile main.c, check out its symbols:
$ gcc -o main main.c
$ objdump -t main | grep 'main\|puts'
main: file format elf64-x86-64
0000000000000000 l df *ABS* 0000000000000000 main.c
0000000000000000 F *UND* 0000000000000000 puts@@GLIBC_2.2.5
0000000000000000 F *UND* 0000000000000000 __libc_start_main@@GLIBC_2.2.5
00000000004004f4 g F .text 0000000000000015 main
Notice that the main()
function is listed here with a known address, whereas puts()
, which will be pulled from glibc, is unknown.
Thus, we can force the runtime linker to use our puts instead:
$ gcc -o puts.so -shared -fPIC puts.c
$ LD_PRELOAD=./puts.so ./main
Hijacked puts: Hello, world!
In contrast, if we statically link our original binary:
$ gcc -o main -static main.c
$ objdump -t main | grep 'main\|puts'
main: file format elf64-x86-64
00000000006c27c0 l O .data 0000000000000888 main_arena
0000000000000000 l df *ABS* 0000000000000000 main.c
00000000006c5580 l O .bss 0000000000000008 _nl_loaded_domains
00000000004957d0 g F __libc_freeres_fn 00000000000000d6 _nl_unload_domain
000000000041bcb0 g F .text 000000000000170c _nl_load_domain
00000000006c60e0 g O .bss 0000000000000008 _nl_domain_bindings
0000000000402050 w F .text 0000000000000189 puts
...
$ LD_PRELOAD=./puts.so ./main
Hello, world!
Our override no longer worked because puts()
was statically linked, which caused the symbol to be resolved at (static) link time.
Using LD_PRELOAD mixed 64bit/32bit environment in Linux
By specifying full path to the library, you don't let dynamic linker to adjust it's search path according to binaries architecture. Define only library name and let linker to pick the correct library for you. E.g.:
$ LD_PRELOAD=lib_init.so ./hello32
will search for lib_init.so in /lib, while
$ LD_PRELOAD=lib_init.so ./hello64
will search in /lib64
Related Topics
How to Capitalize First Letter of Each Line in Bash
Jna Link Issue While Starting Cassandra Rhel 6.5
Looping Through Lines in a File in Bash, Without Using Stdin
Write to a File After Piping Output from Tail -F Through to Grep
Shell Command to Update Pom File from a Variable
Dbus_Bus_Request_Name (): Connections Are Not Allowed to Own the Service
Is There an Scp Variant of Mv Command
What Does Grep -Po '...\K...' Do? How Else Can That Effect Be Achieved
Ksh Storing Result of a Command to a Variable
Printing Grep Results to File and Terminal
Shell Script for Process Monitoring
How to Find the Particular Text Stored in the File "Data.Txt" and It Occurs Only Once
.Zshrc Config File Syntax Error
How to Make Static Linked Elf File to Load Ld_Preload .So
Error Marking Master: Timed Out Waiting for the Condition [Kubernetes]