Toon posts:

[Linux/LD/C++/libtool] Undefined symbols bij maken library

Pagina: 1
Acties:

Verwijderd

Topicstarter
Hallo,

Voor een project waar ik mee bezig ben wil ik een library maken die alle calls naar de Berkeley Socket Interface (sys/socket.h) opvangt, de nodige administratie vastlegt en uiteindelijk alsnog doorstuurt naar de Socket Interface.

Het programma proxychains maakt ook van deze truc gebruik om een verbinding door een proxyserver op te bouwen door alleen de 'connect' op te vangen. Proxychains geeft de definitie van de connect en zorgt dmv van LD_PRELOAD dat zijn eigen .so wordt gebruikt bij het opstarten van een programma. In deze 'connect' wordt dan uiteindelijk de 'echte' connect aangeroepen dmv __libc_connect.

Ik wil nu hetzelfde bereiken, maar dan met alle functies van deze interface. Ik compileer m'n gehele library met:
libtool --mode=compile g++ -g -Wall -c test.cpp
libtool --mode=link g++ -g -Wall -s -o libTEST.la *.lo -rpath /usr/lib -luuid -lc
en installeer de bestanden & symlinks in de .libs directory naar /usr/lib (libTEST.so.0.0.0, libTEST.so.0, libTEST.so en libTEST.a)

Als ik nu met ldd kijk in libISL.so krijg ik de volgende meldingen:
$ ldd -r /usr/lib/libTEST.so
libuuid.so.1 => /lib/libuuid.so.1 (0x40032000)
libstdc++.so.5 => /usr/lib/libstdc++.so.5 (0x40035000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x400f0000)
libm.so.6 => /lib/tls/i686/cmov/libm.so.6 (0x400f9000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x4011c000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x80000000)
undefined symbol: __listen (/usr/lib/libTEST.so)
undefined symbol: __bind (/usr/lib/libTEST.so)
undefined symbol: __socket (/usr/lib/libTEST.so)
undefined symbol: __setsockopt (/usr/lib/libTEST.so)

Deze 4 functies zijn precies dezelfde als waarvan er geen __libc_FUNCTIE aanwezig is in libc maar wel een __FUNCTIE alternatief (voor zover ik kan zien). Bij de andere functies wordt de __libc_FUNCTIE aangeroepen, en daar zijn dus ook geen problemen mee, alleen met deze 4. Weet iemand welke library ik misschien ben vergeten mee te linken? Of doe ik iets anders fout?

Verwijderd

Topicstarter
Zo, dat met de __ symbolen was blijkbaar geen goed plan aangezien het om interne symbolen gaat die dus kunnen veranderen bij nieuwe versies van de C library (libc). Dus ik heb het nu op een andere manier opgelost: met dlopen (http://www.dwheeler.com/p...y-HOWTO/dl-libraries.html).

Dus van alle functies van de berkeley socket interface function pointers gemaakt:

#include <dlfcn.h>

void *handle;
handle = dlopen ("/lib/libc.so.6", RTLD_LAZY);

int (*libcsocket)(int domain, int type, int protocol);
(void*)libcsocket = dlsym(handle, "socket");

int r = -1;
r = (*libcsocket)(domain, type, protocol);

dlclose(handle);

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
Dat doet niet wat je denkt dat het doet, en volgens mij is het een error. Het probleem is dat (void*)libsocket een temporary rvalue is, verkregen door een ongeintialiseerde functionpointer te casten. Die overschrijf je dan, maar het origineel zou daardoor niet moeten wijzigen. Nu is dit undefined behavior, dus als ze die cast gewoon negeren is het strikt genomen ook nog wel legaal - alles is legaal na UB.

Anders gezegd, je code is moreel equivalent aan (void*)(2+2) = dlsym(...); , waar dat resultaat naar toe gaat is een gok.

De correcte syntax is om de rhs te casten, het resultaat van dlsym is toch een temporary.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein