Executables vs Shared Object


13

ฉันสังเกตเห็นบางสิ่งขณะทำfind /bin -exec file {} \;:

fileคำสั่งรายงานบางรายการใน/binเป็น ขณะที่คนอื่นเป็นshared objects executablesตัวอย่างเช่น

/ bin / ntfsck:
เอลฟ์ 64 บิต LSB ที่ใช้ร่วมกันวัตถุ , x86-64, รุ่นที่ 1 (SYSV)
เชื่อมโยงแบบไดนามิก (ใช้ libs ใช้ร่วมกัน) สำหรับ GNU / Linux 2.6.24, BuildID [sha1] = 312d93fd0d8653e7236a61db2e67b93c63225a00 ปล้น

รายงานเดียวกันสำหรับ gawk

/ usr / bin / gawk: วัตถุที่ใช้ร่วมกันของ
ELB 64- บิต LSB , x86-64, รุ่น 1 (SYSV), เชื่อมโยงแบบไดนามิก (ใช้ libs ที่ใช้ร่วมกัน), สำหรับ GNU / Linux 2.6.24, BuildID [sha1] = 76bb13aac7e212164bd6e0d7b8a5d92db92

ในทางตรงกันข้ามfileสำหรับ /bin/echoคือ:

/ bin / echo:
ELF 64 บิตแบบปฏิบัติการ LSB , x86-64, เวอร์ชัน 1 (SYSV),
ลิงก์แบบไดนามิก (ใช้ libs ที่ใช้ร่วมกัน), สำหรับ GNU / Linux 2.6.24,
BuildID [sha1] = 193e75fc13e9c4599e772b8d79125a5934cf601c

โดยพื้นฐานแล้วฉันต้องการทราบว่าอะไรคือความแตกต่างระหว่างexecutableไฟล์และshared objectไฟล์


คำตอบ:


14

tl; DR

ไม่มีความแตกต่างนอกเหนือจากความจริงที่ว่าปฏิบัติการที่คอมไพล์แล้วอาจเชื่อมโยงกับวัตถุที่ใช้ร่วมกัน แต่ไม่ใช่กับไฟล์ปฏิบัติการ


โดยทั่วไปมีสองวิธีในการคอมไพล์1ไฟล์ที่ประมวลผลได้:

  • การใช้การลิงก์แบบสแตติก: ไลบรารีภายนอกที่รวมอยู่ในซอร์สโค้ดจะถูกคอมไพล์และไลบรารีที่คอมไพล์แล้ว (หรือวัตถุในมุมมองของลิงเกอร์) จะถูกเพิ่มเข้าไปในตัวปฏิบัติการ
  • การใช้การเชื่อมโยงแบบไดนามิก: ไลบรารีภายนอกที่รวมอยู่ในซอร์สโค้ดจะถูกรวบรวม แต่มีการเพิ่มลิงก์ไปยังไลบรารีที่รวบรวม (หรือวัตถุในมุมมองของ linker) เพื่อเพิ่มการปฏิบัติการ (และไลบรารี / วัตถุที่คอมไพล์จะถูกโหลดโดย linker จำเป็น);

มีข้อดี / ข้อเสียในการใช้แต่ละวิธีเหล่านี้ แต่นั่นไม่ใช่ประเด็นของคำถาม;

  • /bin/ntfsckและ/usr/bin/gawkเป็นออบเจ็กต์ที่ใช้ร่วมกัน: นี่หมายความว่าไฟล์ที่ประมวลผลได้อาจถูกรวบรวมและเชื่อมโยงกับพวกมันเพื่อใช้ฟังก์ชันการทำงานของมัน
  • /bin/echoเป็นไฟล์ที่ปฏิบัติการได้: นี่หมายความว่าไฟล์ที่เรียกใช้งานอาจไม่ได้รับการคอมไพล์แล้วเชื่อมโยงกับไฟล์นั้นเพื่อใช้ฟังก์ชันการทำงาน

ดังนั้น/bin/ntfsckและ/usr/bin/gawkเป็นไลบรารีที่รวบรวมทางเทคนิค (หรือวัตถุในมุมมองของ linker) แต่เนื่องจากอาจมีการละทิ้งไม่มีสิ่งใดที่ป้องกันไม่ให้วัตถุที่ใช้ร่วมกันถูกเรียกใช้เป็นปฏิบัติการ

ในหมายเหตุด้านให้สังเกตด้วยว่าfileรายงาน (สำหรับแต่ละรายการ):

เชื่อมโยงแบบไดนามิก (ใช้ libs ที่ใช้ร่วมกัน)

ซึ่งหมายความว่าแต่ละรายการจะเชื่อมโยงกับวัตถุที่แชร์อื่น ๆ (และมีแนวโน้มที่จะใช้) เช่นกัน


1. "คอมไพล์" ที่มีจุดประสงค์ในการยอมรับที่กว้างขึ้นซึ่งรวมถึงการประมวลผลล่วงหน้าการรวบรวมและการลิงก์


1
เชื่อมโยงแบบไดนามิกกับวัตถุที่ใช้ร่วมกันอื่น ๆ ใน OS? หรือห้องสมุดสาธารณะในตัวเอง!
Dr.jacky

@ Mr.Hyde ในระบบปฏิบัติการโดยเฉพาะอย่างยิ่งในสถานที่ที่จะต้องกำหนดค่าล่วงหน้าในตัวเชื่อมโยงเพื่อให้ตัวเชื่อมโยงสามารถโหลดได้ในเวลาทำงานหากจำเป็น ดูที่นี่บทที่ 3.2
kos

หนึ่งสามารถเชื่อมโยงกับปฏิบัติการจริงโดยใช้ dlopen: ตัวอย่าง
Adam Zahran

6

ความแตกต่างอีกประการหนึ่งคือไฟล์ที่เรียกทำงานได้จะมีออฟเซ็ตที่อยู่จุดเข้าใช้งานที่กำหนดไว้เช่น 0x08048000 สำหรับ i386, 0x00400000 สำหรับ x86 และ 0x00010000 สำหรับแขน

ไฟล์อ็อบเจ็กต์ที่แบ่งใช้สามารถเป็นไลบรารี แต่ยังสามารถเรียกทำงานได้ เมื่อเป็นไฟล์ปฏิบัติการไม่มีออฟเซ็ตดังกล่าว ปฏิบัติการวัตถุที่ใช้ร่วมกันเพื่อที่จะบอกว่าเป็นตำแหน่งที่ปฏิบัติการอิสระ (PIE) โดยใช้รูปแบบการสุ่มพื้นที่ที่อยู่ (ASLR) ดังนั้นเมื่อดูที่ไฟล์ / proc / pid / maps คุณจะสังเกตเห็นว่าตำแหน่งของเซ็กเมนต์ที่โหลดแตกต่างกันไปในแต่ละการประมวลผลตรงกันข้ามกับไฟล์มาตรฐาน

แนวคิดที่อยู่เบื้องหลังคุณลักษณะนี้คือการเพิ่มความปลอดภัยให้กับโปรแกรมเรียกใช้งานโดยขัดขวางผู้โจมตีจากการโจมตีโปรแกรมที่มุ่งเน้นการส่งคืน ผู้ดูแลหลายคนตัดสินใจที่จะสร้างแพ็คเกจด้วยการเปิดใช้งาน PIE เป็นค่าเริ่มต้นเช่นตั้งแต่ Fedora 23 หรือกับ Ubuntu 17.10


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