Як дізнатися, які всі символи експортуються із спільного об'єкта?


131

У мене є спільний об'єкт (dll). Як я можу дізнатися, які всі символи експортуються з цього?



1
Всі символи в об'єкті експортуються - навіть "внутрішні" функції. Вам просто потрібно оголосити їх компілятору, щоб вони були готові до посилання. Зазвичай це робиться з файлом заголовка, як сказано нижче Райан Фокс.
Кріс Лутц

6
Кріс Лутз помиляється: не всі символи експортуються з об'єктів, що переміщуються, а тим більше з спільних бібліотек.
працевлаштований росіянин

Відповіді:


218

Чи є у вас "спільний об'єкт" (як правило, спільна бібліотека на AIX), спільна бібліотека UNIX або DLL для Windows? Це все різні речі, і ваше запитання зводить їх у відповідь :-(

  • Для спільного об'єкта AIX використовуйте dump -Tv /path/to/foo.o.
  • Для спільної бібліотеки ELF використовуйте readelf -Ws /path/to/libfoo.soабо (якщо у вас є GNU nm) nm -D /path/to/libfoo.so.
  • Для спільної бібліотеки, яка не є ELF UNIX, вкажіть, який UNIX вас цікавить.
  • Для Windows DLL використовуйте dumpbin /EXPORTS foo.dll.

7
У GNU / Linux немає такої утиліти «dumpbin». І питання позначено як Linux.
Привіт-Ангел

3
Дуже корисно, добре мати такий огляд. nmтакож працює на MacOSX, крім -Dопції. Або brew install binutilsскористайтеся версією GNU через gnm. Для GNU nm, --demangleтакож корисно. Також gobjdump.
Альберт

Насправді ви можете добре працювати як із спільними бібліотеками, dll, так і з об’єктними файлами з однієї утиліти, дивіться цю відповідь .
Привіт-Ангел

Питання позначено тегами, linuxтому я думаю, що можна сказати, що @chappar має спільну бібліотеку Linux.
jww

Я припускаю, що немає API, щоб це зробити під час виконання, чи не так? Я виявив, що у Windows у вас є GetProcAddress (), але ви не можете його використовувати без фактичного виконання бібліотеки (що дуже небезпечно, якщо батьківська програма має занадто багато прав доступу).
Пабло Аріель


17

Якщо це файл DLL для Windows, а ваша ОС Linux, тоді використовуйте 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
...

12

On * nix check nm. У Windows використовують програму Dependency Walker


2
Зокрема, nm --defined-only -g something.soбуде надруковано символи, визначені як у бібліотеці, так і зовнішні символи, що, мабуть, те, чого хоче ОП.
Девід Грейсон

8

бачити людину нм

GNU nm перераховує символи з об’єктних файлів objfile .... Якщо жодні об'єктні файли не вказані як аргументи, nm передбачає файл a.out.

8
btw: для спільних об'єктів вам потрібна динамічна опція -D / -. наприклад, nm -D libmagic.so
VolkerK


5

Крос-платформенний спосіб (не тільки сама крос-платформа, але також, щонайменше, працює і з обома, *.soі з *.dll) використовує систему зворотної інженерії radare2 . Наприклад:

$ 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

Як бонус, rabin2визнає керування іменем C ++, наприклад (а також з .soфайлом) :

$ 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

Працює і з об’єктними файлами:

$ 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

1

Ви можете використовувати gnu objdump. objdump -p your.dll. Потім перейдіть до .edataвмісту розділу, і ви знайдете експортовані функції під [Ordinal/Name Pointer] Table.


0

Зазвичай у вас також буде файл заголовка, який ви включаєте у свій код для доступу до символів.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.