Làm thế nào để tôi tìm ra những gì tất cả các biểu tượng được xuất từ ​​một đối tượng chia sẻ?


131

Tôi có một đối tượng chia sẻ (dll). Làm thế nào để tôi tìm ra những gì tất cả các biểu tượng được xuất khẩu từ đó?



1
Tất cả các biểu tượng trong đối tượng được xuất - ngay cả các hàm "bên trong". Bạn chỉ cần khai báo chúng với trình biên dịch để chúng sẵn sàng cho trình liên kết. Điều này thường được thực hiện với một tệp tiêu đề, như Ryan Fox đã nói dưới đây.
Chris Lutz

6
Chris Lutz bị nhầm lẫn: không phải tất cả các biểu tượng được xuất từ ​​các tệp đối tượng có thể định vị lại, ít hơn nhiều từ các thư viện chia sẻ.
Sử dụng tiếng Nga

Câu trả lời:


218

Bạn có "đối tượng chia sẻ" (thường là thư viện dùng chung trên AIX), thư viện dùng chung UNIX hoặc Windows DLL không? Đây là tất cả những điều khác nhau, và câu hỏi của bạn đưa ra tất cả :-(

  • Đối với một đối tượng chia sẻ AIX, sử dụng dump -Tv /path/to/foo.o.
  • Đối với thư viện dùng chung ELF, hãy sử dụng readelf -Ws /path/to/libfoo.sohoặc (nếu bạn có GNU nm) nm -D /path/to/libfoo.so.
  • Đối với thư viện chia sẻ UNIX không phải ELF, vui lòng cho biết UNIX nào bạn quan tâm.
  • Đối với một DLL Windows, sử dụng dumpbin /EXPORTS foo.dll.

7
Trong GNU / Linux không có tiện ích «dumpbin» như vậy. Và câu hỏi được gắn thẻ là linux.
Hi-Angel

3
Rất hữu ích, tốt để có cái nhìn tổng quan như vậy. nmcũng hoạt động trên MacOSX, ngoại trừ -Dtùy chọn. Hoặc brew install binutilsvà sử dụng phiên bản GNU thông qua gnm. Đối với GNU nm, --demanglecũng hữu ích. Ngoài ra gobjdump.
Albert

Trên thực tế, bạn có thể làm việc cả với các thư viện dùng chung, dll và đối tượng điền từ một tiện ích duy nhất, xem câu trả lời này .
Hi-Angel

Câu hỏi được gắn thẻ linuxvì vậy tôi nghĩ an toàn khi nói @chappar có thư viện chia sẻ Linux.
jww

Tôi cho rằng không có API để làm điều này trong thời gian chạy, phải không? Tôi đã thấy rằng trên các cửa sổ bạn có GetProcAddress () nhưng bạn không thể sử dụng nó mà không thực sự thực thi thư viện (điều này rất nguy hiểm nếu ứng dụng mẹ có quá nhiều quyền truy cập).
Pablo Ariel


17

Nếu đó là tệp Windows DLL và HĐH của bạn là Linux thì hãy sử dụng 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

Trên * nix kiểm tra bước sóng. Trên cửa sổ sử dụng chương trình Dependency Walker


2
Cụ thể, nm --defined-only -g something.sosẽ in các ký hiệu được xác định cả trong thư viện và ký hiệu bên ngoài, đây có thể là những gì OP muốn.
David Grayson

8

xem người đàn ông

GNU nm liệt kê các ký hiệu từ các tệp đối tượng objfile .... Nếu không có tệp đối tượng nào được liệt kê dưới dạng đối số, thì nm giả định tệp a.out.

8
btw: đối với các đối tượng được chia sẻ, bạn cần tùy chọn -D / - động. ví dụ: nm -D libmagic.so
VolkerK


5

Cách đa nền tảng (không chỉ bản thân đa nền tảng, mà còn hoạt động, ít nhất là với cả hai *.so*.dll) đang sử dụng khung kỹ thuật đảo ngược radare2 . Ví dụ:

$ 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

Như một phần thưởng, rabin2ví dụ nhận dạng tên C ++, ví dụ (và cả với .sotệp) :

$ 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

Hoạt động với các tệp đối tượng quá:

$ 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

Bạn có thể sử dụng gnu objdump. objdump -p your.dll. Sau đó xoay đến .edatanội dung của phần và bạn sẽ tìm thấy các hàm được xuất bên dưới[Ordinal/Name Pointer] Table .


0

Thông thường, bạn cũng sẽ có một tệp tiêu đề mà bạn đưa vào mã của mình để truy cập các ký hiệu.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.