2016-06-09 11 views
6

Tôi đã quen sử dụng dlopen() để kiểm tra xem thư viện được chia sẻ có quá trình sử dụng cuộc gọi trước đến dlopen() không kích hoạt tải không hiện tại, giống như vậy:Cách kiểm tra xem thư viện được chia sẻ linux đã được tải trước bằng cách sử dụng LD_PRELOAD

void* lib = dlopen(lib_name, RTLD_NOLOAD); 
if (lib != NULL) { 
    ... 
} 

Gần đây tôi đã cố gắng áp dụng cùng một mẫu để xác định xem một trong số ít thư viện được chia sẻ đã được tải vào không gian xử lý bằng LD_PRELOAD hay chưa. Tuy nhiên, trong tất cả các trường hợp, cuộc gọi được đề cập ở trên là dlopen() trả lại NULL.

Vì vậy, về cơ bản, nếu tôi bắt đầu quá trình bằng cách sử dụng dòng lệnh này

LD_PRELOAD=libawesome.so ./mycoolprocess 

và sau đó chạy kiểm tra sau trong mã trong mycoolprocess.c

void* has_awesome = dlopen("libawesome.so", RTLD_NOLOAD); 
if (has_awesome != NULL) { 
    printf("libawesome is available\n"); 
} 

cuộc gọi đến dlopen() luôn trả NULL không có vấn đề nếu thư viện được chia sẻ đã được tải bằng cách sử dụng LD_PRELOAD hay không. Dựa trên bình luận của Andrew Henle bên dưới, tôi cũng đã thử gọi dlopen với đường dẫn tuyệt đối đến một trong các đối tượng được chia sẻ tải lại, nhưng dlopen trong trường hợp này vẫn trả về NULL mặc dù đối tượng được chia sẻ đang được tải trước.

Vì vậy, câu hỏi của tôi có hai phần:

  1. nên mô hình làm việc trên một thư viện đó là được nạp bằng LD_PRELOAD?
  2. Có cách nào khác để có quy trình xác định xem thư viện được chia sẻ cụ thể đã được tải trước chưa?
+0

Là đối tượng được chia sẻ được tải sẵn trong thư mục là một phần của 'DT_RPATH' hoặc 'DT_RUNPATH' của tệp nhị phân, trong thư mục nằm trong biến môi trường' LD_LIBRARY_PATH', trong '/ lib' hoặc'/usr/lib' hoặc thư mục khác được cấu hình thông qua 'ldconfig'? Nếu không, bạn có thể phải cung cấp một đường dẫn tuyệt đối hoặc tương đối đến 'dlopen()'. –

+0

Chương trình có thể kiểm tra sự tồn tại của LD_PRELOAD env var không? – jftuga

+0

@AndrewHenle, các đối tượng được chia sẻ tải sẵn thường nằm trong/usr/lib/x86_64-linux. LD_PRELOAD chỉ chỉ định tên thư viện mà không có đường dẫn tuyệt đối hoặc tương đối. –

Trả lời

1

Không và có, tương ứng.

dlopen() và lừa LD_PRELOAD, mặc dù cả hai đều xử lý thư viện được chia sẻ, hoạt động theo các cách khác nhau về cơ bản.

Biến môi trường LD_PRELOAD được xử lý bởi trình liên kết/trình tải động (ld-linux.so) và ảnh hưởng đến độ phân giải của các bản ghi di dời trong chính tệp nhị phân có thể thực thi. Tóm lại, tại mỗi điểm trong mã của bạn, nơi có một cuộc gọi đến một hàm được định nghĩa trong thư viện động, trình liên kết (tại thời gian xây dựng) sẽ chèn một trình giữ chỗ cho địa chỉ bộ nhớ để nhảy tới. Khi chạy, các trình giữ chỗ đó được thay thế bằng các địa chỉ thực dựa trên các thư viện chia sẻ được nạp vào bộ nhớ, chúng được đặt tên trong tệp thực thi, nhưng có thể bị ghi đè nếu sử dụng LD_PRELOAD. Vì vậy, một khi tệp thực thi được nạp vào bộ nhớ và tất cả các trình giữ chỗ đó đã được điền vào bằng các địa chỉ thực, không có cách nào đơn giản (hoặc di động) để nói những gì đến từ đâu. Tuy nhiên ...

Bạn có thể kiểm tra bản đồ bộ nhớ của quá trình đang chạy. Trên Linux, điều này có nghĩa là phân tích cú pháp thông qua/proc/<pid>/maps. Các nội dung tập tin khá tự giải thích, vì vậy chỉ cần chọn một cách ngẫu nhiên và hãy xem.

Không có ý tưởng làm thế nào bạn muốn làm điều đó trên các hệ thống khác, nhưng tôi tin rằng unixen hiện đại nhất có một/proc hệ thống tập tin của một số loại.

Các vấn đề liên quan