เคล็ดลับ LD_PRELOAD คืออะไร


342

ฉันเจอการอ้างอิงถึงมันเมื่อเร็ว ๆ นี้ในproggitและ (ณ ตอนนี้) มันไม่ได้อธิบาย

ฉันสงสัยว่ามันอาจเป็นไปได้ แต่ฉันไม่รู้แน่นอน


1
ไม่ใช่คำตอบจริงๆดังนั้นฉันจะไม่โพสต์เป็นหนึ่งเดียว แต่ ... Stephen Kell กำลังใช้ LD_PRELOAD สำหรับไลบรารี liballocs ของเขาในวิดีโอนี้และถ้าคุณดูบิตก่อนหน้านี้คุณอาจเข้าใจได้ดีขึ้นว่าทำไม ดูเหมือนว่าจะใช้ liballocs เพื่อให้ภาษาไดนามิกอื่น ๆ สามารถพูดคุยกันได้ คำบรรยายนี้มีคำอธิบายลึก ๆ ในเรื่องนี้ youtu.be/LwicN2u6Dro?t=24m10s
Elijah Lynn

คำตอบ:


415

หากคุณตั้งค่าLD_PRELOADเป็นพา ธ ของวัตถุที่ใช้ร่วมกันไฟล์นั้นจะถูกโหลดก่อนไลบรารีอื่น ๆ (รวมถึง C runtime libc.so) ดังนั้นในการรันlsด้วยmalloc()การติดตั้งแบบพิเศษให้ทำดังนี้

$ LD_PRELOAD=/path/to/my/malloc.so /bin/ls

12
ฉันไม่รู้ว่ามันมีอยู่จริง ... ดูเหมือนว่ามันจะเป็นเวคเตอร์ที่สำคัญสำหรับการโจมตีด้านความปลอดภัย ความคิดใด ๆ ว่ามันปลอดภัยหรือไม่?
rmeador

141
มันปลอดภัยจากความจริงแล้วตัวโหลดจะไม่สนใจ LD_PRELOAD ถ้า ruid! = euid - Joshua
Joshua

18
@ โจชัว: อะไรคือซากปรักหักพังและ euid?
heinrich5991

20
@ heinrich5991 รหัสผู้ใช้จริงและมีประสิทธิภาพ: lst.de/~okir/blackhats/node23.html
gsingh2011

59
สิ่งหนึ่งที่สำคัญที่จะเก็บไว้ในใจ: คุณมักจะต้องการระบุแน่นอนLD_PRELOADเส้นทางไปยัง เหตุผลก็คือมันเป็นตัวแปรสภาพแวดล้อม แต่สืบทอดโดยกระบวนการลูก - ซึ่งอาจมีไดเรกทอรีทำงานแตกต่างจากกระบวนการหลัก ดังนั้นเส้นทางสัมพัทธ์ใด ๆ จะล้มเหลวในการค้นหาไลบรารีเพื่อโหลดล่วงหน้า
Frerich Raabe

49

LD_PRELOADคุณสามารถแทนที่สัญลักษณ์หุ้นในห้องสมุดโดยการสร้างห้องสมุดที่มีสัญลักษณ์เดียวกันและระบุห้องสมุดใน

บางคนใช้เพื่อระบุไลบรารีในตำแหน่งที่ตั้งที่ไม่เป็นมาตรฐาน แต่LD_LIBRARY_PATHดีกว่าสำหรับจุดประสงค์นั้น


17
"บางคนใช้เพื่อระบุห้องสมุดในสถานที่ที่ไม่ได้มาตรฐาน" ... จริงเหรอ? ดูเหมือนว่า "บางคนใช้ผิด"!
Tom

6
LD_PRELOAD สามารถโดยการสั่งตัดโหลดเส้นทางฮาร์ดโค้ดที่ระบุแอปพลิเคชัน
Joshua

1
มันจะเป็นการผิดที่จะโหลดรุ่นที่แตกต่างกันของห้องสมุด - สมมติว่าพวกเขาเข้ากันได้?
z0r

2
ฉันเคยเห็นมันเคยโหลด debug หรือชุดเครื่องมือหรือโหลดไลบรารีที่ทำสิ่งที่แตกต่างอย่างสิ้นเชิงอย่างสิ้นเชิงจากไลบรารีฐานราวกับว่าเลียนแบบระบบอื่น
Joshua

1
ในกรณีที่ห้องสมุดไม่ได้รวบรวมอย่างถูกต้อง (ใช้ในการทำงานกับ mysql ตลอดเวลาที่มีการเชื่อมต่อหลวม ๆ กับ libmysql_client ทั่วไปซึ่งเขียนทับ symlink เวอร์ชันเก่า - ขึ้นอยู่กับเวอร์ชันของ perl ที่คุณใช้คุณต้องระบุ / บังคับด้วย LD_PRELOAD .. เคล็ดลับที่มีประโยชน์ถ้าฉันจำอย่างถูกต้อง valgrind ใช้เทคนิคนี้เพื่อให้ความสามารถในการดีบักกับไบนารีโดยไม่จำเป็นต้องคอมไพล์ซ้ำ .. มันมีประโยชน์มาก
synthesizerpatel

37

ด้วยLD_PRELOADคุณสามารถให้ความสำคัญกับห้องสมุด

ตัวอย่างเช่นคุณสามารถเขียนห้องสมุดที่ใช้และmalloc freeและโดยการโหลดสิ่งเหล่านี้กับLD_PRELOADคุณmallocและfreeจะถูกประหารชีวิตแทนที่จะเป็นแบบมาตรฐาน


แต่ถ้าโปรแกรมใช้calloc? มันจะไม่เลอะทุกอย่างเหรอ?
Janus Troelsen

7
@JanusTroelsen หากไลบรารีที่คุณเขียนไม่ได้ใช้งานบางส่วนส่วนนั้นจะถูกโหลดจากไลบรารีดั้งเดิม
Woodrow Barlow

@JanusTroelsen กล่าวอีกนัยหนึ่ง LD_PRELOAD ช่วยให้คุณระบุการใช้งานสัญลักษณ์เฉพาะที่จะใช้ หากไลบรารีที่โหลดไว้ล่วงหน้าไม่ส่งออกสัญลักษณ์จะพบว่าไม่มีอะไรอีกแล้ว
sherrellbc

1
@JanusTroelsen: ปรากฎว่าmallocและฟรีได้รับการออกแบบมาโดยเฉพาะใน glibc ที่จะอนุญาตให้นี้และสต็อกพอที่จะเรียกที่นำเข้าcalloc mallocอย่าลองด้วยฟังก์ชั่นอื่น ๆ มันทำงานได้ไม่ดีนัก
Joshua

30

ดังที่หลายคนพูดถึงการใช้LD_PRELOADโหลดไลบรารีล่วงหน้า BTW คุณสามารถตรวจสอบหากการตั้งค่าสามารถใช้ได้โดยlddคำสั่ง

ตัวอย่าง: libselinux.so.1สมมติว่าคุณจำเป็นต้องโหลดของคุณเอง

> ldd /bin/ls
    ...
    libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007f3927b1d000)
    libacl.so.1 => /lib/x86_64-linux-gnu/libacl.so.1 (0x00007f3927914000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f392754f000)
    libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007f3927311000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f392710c000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f3927d65000)
    libattr.so.1 => /lib/x86_64-linux-gnu/libattr.so.1 (0x00007f3926f07000)

ดังนั้นตั้งค่าสภาพแวดล้อมพรีโหลดของคุณ:

  export LD_PRELOAD=/home/patric/libselinux.so.1

ตรวจสอบห้องสมุดของคุณอีกครั้ง:

>ldd /bin/ls
    ...
    libselinux.so.1 =>
    /home/patric/libselinux.so.1 (0x00007fb9245d8000)
    ...

9

LD_PRELOADรายการห้องสมุดสาธารณะที่มีฟังก์ชั่นที่แทนที่ชุดมาตรฐานเช่นเดียวกับที่/etc/ld.so.preloadไม่ /lib/ld-linux.soเหล่านี้จะถูกนำมาใช้โดยโหลด หากคุณต้องการที่จะแทนที่เพียงฟังก์ชั่นที่เลือกไม่กี่คุณสามารถทำเช่นนี้โดยการสร้างไฟล์วัตถุเอาชนะและการตั้งค่าLD_PRELOAD; ฟังก์ชั่นในไฟล์วัตถุนี้จะแทนที่เพียงฟังก์ชั่นเหล่านั้นออกจากคนอื่น ๆ เช่นที่พวกเขา

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับห้องสมุดสาธารณะให้ไปที่ http://tldp.org/HOWTO/Program-Library-HOWTO/shared-library.html


3

นี่คือโพสต์บล็อกโดยละเอียดเกี่ยวกับการโหลดล่วงหน้า:

https://blog.cryptomilk.org/2014/07/21/what-is-preloading/


13
ขอบคุณสำหรับการโพสต์คำตอบของคุณ! โปรดทราบว่าคุณควรโพสต์ส่วนสำคัญของคำตอบที่นี่ในเว็บไซต์นี้หรือความเสี่ยงในการโพสต์ของคุณถูกลบดูคำถามที่พบบ่อยซึ่งระบุถึงคำตอบที่ 'แทบจะไม่มากกว่าลิงก์' คุณยังอาจรวมลิงค์ได้หากต้องการ แต่เป็นเพียง 'ข้อมูลอ้างอิง' คำตอบควรยืนด้วยตัวเองโดยไม่ต้องเชื่อมโยง
Taryn


2

เมื่อ LD_PRELOAD ถูกใช้ไฟล์นั้นจะถูกโหลดก่อนที่$export LD_PRELOAD=/path/liblib อื่น ๆ จะถูกโหลดไว้ล่วงหน้าแม้จะสามารถใช้ในโปรแกรมได้เช่นกัน


1

การใช้LD_PRELOADพา ธ คุณสามารถบังคับให้โหลดเดอร์ของแอปพลิเคชันให้วัตถุที่ใช้ร่วมกันผ่านค่าเริ่มต้นที่ให้ไว้

นักพัฒนาใช้สิ่งนี้เพื่อดีบักแอปพลิเคชันของพวกเขาโดยจัดเตรียมวัตถุที่ใช้ร่วมกันรุ่นต่างๆ

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

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