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


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.