ฉันจะทราบได้อย่างไรว่าสัญลักษณ์ทั้งหมดจะถูกส่งออกจากวัตถุที่ใช้ร่วมกัน


131

ฉันมีวัตถุที่ใช้ร่วมกัน (dll) ฉันจะรู้ได้อย่างไรว่าสัญลักษณ์ทั้งหมดจะถูกส่งออกจากที่ใด



1
สัญลักษณ์ทั้งหมดในวัตถุจะถูกส่งออก - แม้แต่ฟังก์ชัน "ภายใน" คุณเพียงแค่ต้องประกาศให้คอมไพเลอร์ทราบเพื่อที่พวกเขาจะพร้อมสำหรับลิงเกอร์ สิ่งนี้มักจะทำกับไฟล์ส่วนหัวเช่นไรอันฟ็อกซ์กล่าวไว้ด้านล่าง
คริสลัทซ์

6
Chris Lutz เข้าใจผิด: ไม่ได้มีสัญลักษณ์ทั้งหมดที่ส่งออกจากไฟล์วัตถุที่เปลี่ยนตำแหน่งได้ซึ่งน้อยกว่ามากจากไลบรารีที่แชร์
ลูกจ้างชาวรัสเซีย

คำตอบ:


218

คุณมี "shared object" (โดยปกติคือ shared library บน AIX), UNIX shared library หรือ Windows DLL หรือไม่? สิ่งเหล่านี้ล้วนเป็นสิ่งที่แตกต่างกันและคำถามของคุณจะทำให้พวกเขาทั้งหมด :-(

  • สำหรับวัตถุ AIX dump -Tv /path/to/foo.oที่ใช้ร่วมกันใช้
  • สำหรับเอลฟ์ที่ใช้ร่วมกันห้องสมุดใช้readelf -Ws /path/to/libfoo.soหรือ (ถ้าคุณมี GNU nm -D /path/to/libfoo.soนาโนเมตร)
  • สำหรับที่ไม่ใช่เอลฟ์ UNIX ที่ใช้ร่วมกันห้องสมุดโปรดรัฐซึ่ง UNIX คุณอยู่ในความสนใจ
  • สำหรับ DLL Windows dumpbin /EXPORTS foo.dllใช้

7
ใน GNU / Linux ไม่มีโปรแกรมอรรถประโยชน์« dumpbin » และคำถามถูกแท็กเป็น linux
Hi-Angel

3
มีประโยชน์มากดีที่จะมีภาพรวมดังกล่าว nmใช้ได้กับ MacOSX ยกเว้น-Dตัวเลือก หรือbrew install binutilsและใช้รุ่น GNU gnmผ่าน สำหรับ GNU nm, --demangleยังเป็นประโยชน์ gobjdumpด้วย
อัลเบิร์ต

ที่จริงแล้วคุณสามารถทำงานได้ทั้งกับ shared library, dlls และ object filles จากยูทิลิตี้เดียวได้ดีดูคำตอบนี้
Hi-Angel

คำถามถูกติดแท็กlinuxดังนั้นฉันคิดว่ามันปลอดภัยที่จะพูดว่า @chappar มีไลบรารี่ที่แชร์กับ Linux
jww

ฉันคิดว่าไม่มี API ให้ทำในขณะทำงานใช่ไหม ฉันพบว่าบน windows คุณมี GetProcAddress () แต่คุณไม่สามารถใช้งานได้หากไม่ใช้งานไลบรารี่จริง (ซึ่งอันตรายมากถ้าแอพแม่มีสิทธิ์เข้าถึงมากเกินไป)
Pablo Ariel


17

หากเป็นไฟล์ Windows DLL และระบบปฏิบัติการของคุณเป็น 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

บน * ระวังตรวจสอบ nm บน windows ให้ใช้Dependency Walkerของโปรแกรม


2
โดยเฉพาะnm --defined-only -g something.soจะพิมพ์สัญลักษณ์ที่กำหนดไว้ทั้งในไลบรารีและสัญลักษณ์ extern ซึ่งอาจเป็นสิ่งที่ OP ต้องการ
David Grayson

8

ดูผู้ชาย nm

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 ++ mangling เช่น(และ.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

โดยปกติแล้วคุณจะมีไฟล์ส่วนหัวที่คุณรวมไว้ในรหัสของคุณเพื่อเข้าถึงสัญลักษณ์

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.