Thủ thuật LD_PRELOAD là gì?


341

Gần đây tôi đã bắt gặp một tài liệu tham khảo về nó trên proggit và (hiện tại) nó không được giải thích.

Tôi nghi ngờ đây có thể là nó, nhưng tôi không biết chắc chắn.


1
Không thực sự là một câu trả lời vì vậy tôi sẽ không đăng nó dưới dạng một nhưng ... Stephen Kell đang sử dụng LD_PRELOAD cho thư viện liballocs của anh ấy trong video này và nếu bạn xem các bit trước đó, bạn có thể hiểu rõ hơn về cách thức / lý do. liballocs dường như đang được sử dụng để các ngôn ngữ động khác có thể nói chuyện với nhau. Cuộc nói chuyện này có một số nội bộ sâu sắc được giải thích trong đó. youtu.be/LwicN2u6Dro?t=24m10s
Elijah Lynn

Câu trả lời:


415

Nếu bạn đặt thành LD_PRELOADđường dẫn của một đối tượng chia sẻ, tệp đó sẽ được tải trước bất kỳ thư viện nào khác (bao gồm cả thời gian chạy C libc.so). Vì vậy, để chạy lsvới malloc()triển khai đặc biệt của bạn , hãy làm điều này:

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

12
Tôi không biết điều này tồn tại ... có vẻ như nó sẽ là một véc tơ chính cho các cuộc tấn công bảo mật. Bất kỳ ý tưởng làm thế nào nó được bảo mật?
rmeador

141
Nó được bảo mật bởi thực tế trình tải sẽ bỏ qua LD_PRELOAD nếu bị hủy hoại! = Euid - Joshua
Joshua

18
@Joshua: ruid và euid là gì?
heinrich5991

20
@ heinrich5991 Id người dùng thực sự và hiệu quả: lst.de/~okir/blackhats/node23.html
gsingh2011

59
Một điều quan trọng cần ghi nhớ: bạn thường muốn chỉ định một đường dẫn tuyệt đốiLD_PRELOAD . Lý do là nó là một biến môi trường, nó được thừa hưởng bởi các tiến trình con - có thể có một thư mục làm việc khác với tiến trình cha. Vì vậy, bất kỳ đường dẫn tương đối sẽ không tìm thấy thư viện để tải trước.
Frerich Raabe

49

Bạn có thể ghi đè các biểu tượng trong thư viện chứng khoán bằng cách tạo thư viện có cùng ký hiệu và chỉ định thư viện trong đó LD_PRELOAD.

Một số người sử dụng nó để chỉ định các thư viện ở các vị trí không chuẩn, nhưng LD_LIBRARY_PATHtốt hơn cho mục đích đó.


17
"Một số người sử dụng nó để chỉ định các thư viện ở các vị trí không chuẩn" ... Thật sao? Âm thanh như "Một số người sử dụng sai"!
Tom

6
LD_PRELOAD có thể nhờ vào các đường dẫn được mã hóa theo thứ tự tải ứng dụng.
Joshua

1
Nó có phải là một lạm dụng để tải trước một phiên bản khác của thư viện - giả sử chúng tương thích?
z0r

2
Tôi đã thấy nó được sử dụng để tải một biến thể gỡ lỗi hoặc thiết bị, hoặc để tải một thư viện làm một cái gì đó hoàn toàn khác với thư viện cơ sở như thể mô phỏng một số hệ thống khác.
Joshua

1
Trong trường hợp các thư viện không được biên dịch chính xác (được sử dụng để chạy với điều này với mysql mọi lúc, nơi nó có khớp nối lỏng lẻo với libmysql_client chung, ghi đè lên một liên kết tượng trưng của phiên bản cũ hơn - tùy thuộc vào phiên bản perl nào bạn đã sử dụng / buộc nó với LD_PRELOAD .. Bí quyết hữu ích Nếu tôi nhớ không lầm thì valgrind sử dụng kỹ thuật này để cung cấp khả năng gỡ lỗi để mã nhị phân mà không cần phải biên dịch lại .. nó khá hữu ích..
synthesizerpatel

37

Với LD_PRELOADbạn có thể cung cấp cho các thư viện ưu tiên.

Ví dụ, bạn có thể viết một thư viện thực hiện mallocfree. Và bằng cách tải chúng với LD_PRELOADbạn mallocfreesẽ được thực hiện chứ không phải là những tiêu chuẩn.


Nhưng nếu chương trình sử dụng callocthì sao? điều đó có làm xáo trộn mọi thứ không?
Janus Troelsen

7
@JanusTroelsen nếu thư viện bạn viết không triển khai một phần nhất định, phần đó sẽ được tải từ thư viện gốc.
Woodrow Barlow

@JanusTroelsen, Nói cách khác, LD_PRELOAD cho phép bạn chỉ định triển khai biểu tượng cụ thể nào sẽ được sử dụng. Nếu thư viện tải sẵn không xuất biểu tượng, nó sẽ được tìm thấy ở nơi khác.
sherrellbc

1
@JanusTroelsen: Hóa ra mallocvà miễn phí được thiết kế đặc biệt trong glibc để cho phép điều này và cổ phiếu callocquản lý để gọi cho hàng nhập khẩu của bạn malloc. Đừng thử điều này với bất kỳ chức năng nào khác. Nó sẽ không hoạt động tốt như vậy.
Joshua

30

Như nhiều người đã đề cập, sử dụng LD_PRELOADđể tải trước thư viện. BTW, bạn có thể KIỂM TRA nếu cài đặt có sẵn bằng lddlệnh.

Ví dụ: giả sử bạn cần tải trước của riêng bạn 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)

Do đó, hãy thiết lập môi trường tải trước của bạn:

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

Kiểm tra thư viện của bạn một lần nữa:

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

9

LD_PRELOADliệt kê các thư viện chia sẻ với các chức năng ghi đè lên bộ tiêu chuẩn, cũng như /etc/ld.so.preloadvậy. Chúng được thực hiện bởi bộ nạp /lib/ld-linux.so. Nếu bạn muốn ghi đè chỉ một vài chức năng đã chọn, bạn có thể thực hiện việc này bằng cách tạo tệp và cài đặt đối tượng ghi đè LD_PRELOAD; các hàm trong tệp đối tượng này sẽ ghi đè chỉ các hàm đó để lại các hàm khác.

Để biết thêm thông tin về các thư viện được chia sẻ, hãy truy cập http://tldp.org/HOWTO/Program-L Library- HOWTO / Shared-lologists.html


3

Đây là một bài viết blog chi tiết về tải trước:

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


13
Cảm ơn đã gửi câu trả lời của bạn! Xin lưu ý rằng bạn nên đăng các phần thiết yếu của câu trả lời tại đây, trên trang web này hoặc rủi ro bài đăng của bạn bị xóa Xem Câu hỏi thường gặp trong đó đề cập đến câu trả lời 'hầu như không nhiều hơn một liên kết'. Bạn vẫn có thể bao gồm liên kết nếu bạn muốn, nhưng chỉ là một 'tài liệu tham khảo'. Câu trả lời nên tự đứng mà không cần liên kết.
Taryn

3

thật dễ dàng để xuất mylib.sosang env:

$ export LD_PRELOAD=/path/mylib.so
$ ./mybin

để vô hiệu hóa:

$ export LD_PRELOAD=

7
hoặcunset LD_PRELOAD
Morten

2

Khi LD_PRELOAD được sử dụng, tập tin đó sẽ được tải trước khi bất kỳ $export LD_PRELOAD=/path/liblib nào khác được tải trước, thậm chí điều này cũng có thể được sử dụng trong các chương trình


1

Sử dụng LD_PRELOADđường dẫn, bạn có thể buộc trình tải ứng dụng tải đối tượng dùng chung được cung cấp, theo mặc định được cung cấp.

Các nhà phát triển sử dụng điều này để gỡ lỗi các ứng dụng của họ bằng cách cung cấp các phiên bản khác nhau của các đối tượng được chia sẻ.

Chúng tôi đã sử dụng nó để hack một số ứng dụng nhất định, bằng cách ghi đè các chức năng hiện có bằng cách sử dụng các đối tượng chia sẻ đã chuẩn bị.

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.