dlsym, when run from an LD_PRELOAD interposer, does not find any symbols from the main program
0
votes
1
answer
339
views
/* dlsym-main.c */
#include
void doSomething(char const *msg)
{
fprintf(stderr, "Main program is doing %s\n", msg);
}
void (*fnptr)(char const *) = doSomething;
int main() {
fnptr("some printing");
return 0;
}
/* dlsym-lib.c */
#define _GNU_SOURCE 1
#include
#include
void myLibraryFunc(char const *msg)
{
fprintf(stdout, "My library is doing %s\n", msg);
}
void hook(void)
{
// Load the current executable as a shared object
void* handle = dlopen(NULL, RTLD_LAZY);
if (!handle) {
fprintf(stderr, "Error: %s\n", dlerror());
return;
}
typedef void (*fnT)(char const *);
// Dynamically resolve the global non-static variable
fnT* fnPtr = (fnT*) dlsym(handle, "fnptr");
if (!fnPtr)
{
fprintf(stderr, "Error locating fnptr: %s\n", dlerror());
dlclose(handle);
return;
}
*fnPtr = myLibraryFunc;
// Close the handle
dlclose(handle);
}
__attribute__((constructor))
void setup() { hook(); }
## Makefile
linky: dlsym-main.c
gcc -o linky dlsym-main.c
libi.so: dlsym-lib.c
gcc -shared -fPIC -o libi.so dlsym-lib.c -ldl
run: linky libi.so
LD_PRELOAD=$$PWD/libi.so ./linky
Output of make run
:
Error locating fnptr: Symbol not found: fnptr
Main program is doing some printing
Symbol (fnptr) is a global data object:
> objdump -t linky | grep fnptr
0000000000020008 g O .data 0000000000000008 fnptr
Using LD_DEBUG=symbols
(Debian) shows that it's looking in the executable:
318: symbol=fnptr; lookup in file=./linky
318: symbol=fnptr; lookup in file=/CDS/libi.so
318: symbol=fnptr; lookup in file=/usr/lib/aarch64-linux-gnu/libstdc++.so.6
318: symbol=fnptr; lookup in file=/lib/aarch64-linux-gnu/libc.so.6
318: symbol=fnptr; lookup in file=/lib/aarch64-linux-gnu/libdl.so.2
318: symbol=fnptr; lookup in file=/lib/aarch64-linux-gnu/libm.so.6
318: symbol=fnptr; lookup in file=/lib/aarch64-linux-gnu/libgcc_s.so.1
318: symbol=fnptr; lookup in file=/lib/ld-linux-aarch64.so.1
318: /CDS/libi.so: error: symbol lookup error: undefined symbol: fnptr (fatal)
I've tried this on Debian, Alpine (musl libc), and other variants (all GCC) and the same results occur.
I've asked AI bots how to do this and they spit out exactly this code.
The same code on macOS works fine
▶ make run_macOS
DYLD_INSERT_LIBRARIES=$PWD/libi.so ./linky
My library is doing some printing
What am I doing wrong that this doesn't work on GCC?
Asked by user3384486
(1 rep)
Aug 7, 2024, 09:34 PM
Last activity: Aug 8, 2024, 05:22 PM
Last activity: Aug 8, 2024, 05:22 PM