Wie finde ich heraus, welche Symbole aus einem gemeinsam genutzten Objekt exportiert werden?

131

Ich habe ein gemeinsames Objekt (DLL). Wie finde ich heraus, welche Symbole daraus exportiert werden?

Chappar
quelle
1
Alle Symbole im Objekt werden exportiert - auch die "internen" Funktionen. Sie müssen sie nur beim Compiler deklarieren, damit sie für den Linker bereit sind. Dies geschieht normalerweise mit einer Header-Datei, wie Ryan Fox unten sagte.
Chris Lutz
6
Chris Lutz irrt sich: Nicht alle Symbole werden aus verschiebbaren Objektdateien exportiert, geschweige denn aus gemeinsam genutzten Bibliotheken.
Angestellt Russisch

Antworten:

218

Haben Sie ein "freigegebenes Objekt" (normalerweise eine gemeinsam genutzte Bibliothek unter AIX), eine gemeinsam genutzte UNIX-Bibliothek oder eine Windows-DLL? Dies sind alles verschiedene Dinge, und Ihre Frage bringt sie alle zusammen :-(

  • Verwenden Sie für ein freigegebenes AIX-Objekt dump -Tv /path/to/foo.o.
  • Verwenden readelf -Ws /path/to/libfoo.soSie für eine gemeinsam genutzte ELF-Bibliothek oder (wenn Sie GNU nm haben) nm -D /path/to/libfoo.so.
  • Geben Sie für eine gemeinsam genutzte Nicht-ELF-UNIX-Bibliothek an, an welchem UNIX Sie interessiert sind.
  • Verwenden Sie für eine Windows-DLL dumpbin /EXPORTS foo.dll.
Angestellt Russisch
quelle
7
In GNU / Linux gibt es kein solches Dienstprogramm «dumpbin». Und die Frage ist als Linux markiert.
Hi-Angel
3
Sehr hilfreich, gut, einen solchen Überblick zu haben. nmfunktioniert auch unter MacOSX, mit Ausnahme der -DOption. Oder brew install binutilsund verwenden Sie die GNU-Version über gnm. Für GNU nm, --demangleist ebenfalls nützlich. Auch gobjdump.
Albert
Tatsächlich können Sie mit gemeinsam genutzten Bibliotheken, DLLs und Objektfüllungen von einem einzigen Dienstprogramm aus problemlos arbeiten. Siehe diese Antwort .
Hi-Angel
Die Frage ist mit Tags versehen, linuxdaher kann man mit Sicherheit sagen, dass @chappar über eine gemeinsam genutzte Linux-Bibliothek verfügt.
JWW
Ich nehme an, es gibt keine API, um dies zur Laufzeit zu tun, oder? Ich habe festgestellt, dass Sie unter Windows GetProcAddress () haben, aber Sie können es nicht verwenden, ohne die Bibliothek tatsächlich auszuführen (was sehr gefährlich ist, wenn die übergeordnete App zu viele Zugriffsrechte hat).
Pablo Ariel
23

objdump ist ein weiteres gutes unter Linux.

smcameron
quelle
Auch verfügbar auf AIX
Pitseeker
17

Wenn es sich um eine Windows-DLL-Datei handelt und Ihr Betriebssystem Linux ist, verwenden Sie winedump :

$ winedump -j export pcre.dll

Contents of pcre.dll: 229888 bytes

Exports table:

  Name:            pcre.dll
  Characteristics: 00000000
  TimeDateStamp:   53BBA519 Tue Jul  8 10:00:25 2014
  Version:         0.00
  Ordinal base:    1
  # of functions:  31
  # of Names:      31
Addresses of functions: 000375C8
Addresses of name ordinals: 000376C0
Addresses of names: 00037644

  Entry Pt  Ordn  Name
  0001FDA0     1 pcre_assign_jit_stack
  000380B8     2 pcre_callout
  00009030     3 pcre_compile
...
Björn Lindqvist
quelle
12

On * nix check nm. Verwenden Sie unter Windows das Programm Dependency Walker

AllDayCpp
quelle
2
Insbesondere nm --defined-only -g something.sowerden die Symbole gedruckt, die sowohl in der Bibliothek als auch in externen Symbolen definiert sind. Dies ist wahrscheinlich das, was das OP wünscht.
David Grayson
8

siehe Mann nm

GNU nm listet die Symbole aus Objektdateien auf, objfile .... Wenn keine Objektdateien als Argumente aufgeführt sind, nimmt nm die Datei a.out an.
VolkerK
quelle
8
Übrigens: Für gemeinsam genutzte Objekte benötigen Sie die dynamische Option -D / -. zB nm -D libmagic.so
VolkerK
8

Verwenden: nm --demangle <libname>.so

Codebin
quelle
2
nm: /usr/lib/i386-linux-gnu/libtemplates_parser.so.11.6: no symbols. readelfoder -DFlagge funktioniert.
Janus Troelsen
5

Der plattformübergreifende Weg (nicht nur plattformübergreifend selbst, sondern zumindest auch mit beiden *.sound *.dll) funktioniert mit dem Reverse-Engineering-Framework radare2 . Z.B:

$ rabin2 -s glew32.dll | head -n 5 
[Symbols]
vaddr=0x62afda8d paddr=0x0005ba8d ord=000 fwd=NONE sz=0 bind=GLOBAL type=FUNC name=glew32.dll___GLEW_3DFX_multisample
vaddr=0x62afda8e paddr=0x0005ba8e ord=001 fwd=NONE sz=0 bind=GLOBAL type=FUNC name=glew32.dll___GLEW_3DFX_tbuffer
vaddr=0x62afda8f paddr=0x0005ba8f ord=002 fwd=NONE sz=0 bind=GLOBAL type=FUNC name=glew32.dll___GLEW_3DFX_texture_compression_FXT1
vaddr=0x62afdab8 paddr=0x0005bab8 ord=003 fwd=NONE sz=0 bind=GLOBAL type=FUNC name=glew32.dll___GLEW_AMD_blend_minmax_factor

Erkennt als Bonus beispielsweise rabin2C ++ - Namensmangel (und auch mit .soDatei) :

$ rabin2 -s /usr/lib/libabw-0.1.so.1.0.1 | head -n 5
[Symbols]
vaddr=0x00027590 paddr=0x00027590 ord=124 fwd=NONE sz=430 bind=GLOBAL type=FUNC name=libabw::AbiDocument::isFileFormatSupported
vaddr=0x0000a730 paddr=0x0000a730 ord=125 fwd=NONE sz=58 bind=UNKNOWN type=FUNC name=boost::exception::~exception
vaddr=0x00232680 paddr=0x00032680 ord=126 fwd=NONE sz=16 bind=UNKNOWN type=OBJECT name=typeinfoforboost::exception_detail::clone_base
vaddr=0x00027740 paddr=0x00027740 ord=127 fwd=NONE sz=235 bind=GLOBAL type=FUNC name=libabw::AbiDocument::parse

Funktioniert auch mit Objektdateien:

$ g++ test.cpp -c -o a.o
$ rabin2 -s a.o | head -n 5
Warning: Cannot initialize program headers
Warning: Cannot initialize dynamic strings
Warning: Cannot initialize dynamic section
[Symbols]
vaddr=0x08000149 paddr=0x00000149 ord=006 fwd=NONE sz=1 bind=LOCAL type=OBJECT name=std::piecewise_construct
vaddr=0x08000149 paddr=0x00000149 ord=007 fwd=NONE sz=1 bind=LOCAL type=OBJECT name=std::__ioinit
vaddr=0x080000eb paddr=0x000000eb ord=017 fwd=NONE sz=73 bind=LOCAL type=FUNC name=__static_initialization_and_destruction_0
vaddr=0x08000134 paddr=0x00000134 ord=018 fwd=NONE sz=21 bind=LOCAL type=FUNC name=_GLOBAL__sub_I__Z4funcP6Animal
Hallo Engel
quelle
1

Sie können gnu objdump verwenden. objdump -p your.dll. Schwenken Sie dann zum .edataAbschnittinhalt und Sie finden die exportierten Funktionen unter [Ordinal/Name Pointer] Table.

Don F.
quelle
0

Normalerweise haben Sie auch eine Header-Datei, die Sie in Ihren Code aufnehmen, um auf die Symbole zuzugreifen.

Ryan Fox
quelle