Sample Header Ad - 728x90

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