2010-09-07 26 views
28

Giả sử tôi muốn hoàn toàn thực hiện cuộc gọi hệ thống mở(), có thể để bọc syscall thực tế và thực hiện một số ghi nhật ký. One way to do this is to use LD_PRELOAD để tải thư viện đối tượng được chia sẻ (do người dùng tạo) chiếm điểm truy cập mở().Làm cách nào để tôi thực hiện lại (hoặc bọc) một hàm syscall trên Linux?

Cách thức mở() do người dùng tạo sau đó lấy con trỏ đến hàm glibc open() bằng cách dlsym() nhập vào và gọi nó.

Giải pháp được đề xuất ở trên là giải pháp động. Giả sử tôi muốn liên kết tĩnh của riêng mình open() trình bao bọc tĩnh. Tôi sẽ làm như thế nào? Tôi đoán cơ chế là như nhau, nhưng tôi cũng đoán sẽ có một xung đột biểu tượng giữa người dùng định nghĩa open() và libc open().

Vui lòng chia sẻ bất kỳ kỹ thuật nào khác để đạt được cùng một mục tiêu.

+0

Làm thế nào về bạn chỉ cần dính một hàm wrapper/macro trong mã của bạn? –

+0

@Seamus: Tôi không thích sử dụng macro. Tôi không thực sự có một vấn đề. Tôi chỉ yêu cầu nâng cao kiến ​​thức SO và tìm hiểu một số mẹo mới. –

Trả lời

56

Bạn có thể sử dụng tính năng bọc được cung cấp bởi ld. Từ man ld:

--wrap symbol Sử dụng hàm bao bọc cho ký hiệu. Mọi tham chiếu chưa được xác định đến symbol sẽ được giải quyết thành __wrap_symbol.

Mọi tham chiếu chưa được xác định đến __real_symbol sẽ được giải quyết thành symbol.

Vì vậy, bạn chỉ phải sử dụng tiền tố __wrap_ cho hàm wrapper và __real_ khi bạn muốn gọi hàm thực sự. Một ví dụ đơn giản là:

malloc_wrapper.c:

#include <stdio.h> 
void *__real_malloc (size_t); 

/* This function wraps the real malloc */ 
void * __wrap_malloc (size_t size) 
{ 
    void *lptr = __real_malloc(size); 
    printf("Malloc: %lu bytes @%p\n", size, lptr); 
    return lptr; 
} 

thử nghiệm ứng dụng testapp.c:

#include <stdio.h> 
#include <stdlib.h> 
int main() 
{ 
    free(malloc(1024)); // malloc will resolve to __wrap_malloc 
    return 0; 
} 

Sau đó biên dịch ứng dụng:

gcc -c malloc_wrapper.c 
gcc -c testapp.c 
gcc -Wl,-wrap,malloc testapp.o malloc_wrapper.o -o testapp 

Kết quả của việc áp dụng kết quả sẽ là:

$ ./testapp 
Malloc: 1024 bytes @0x20d8010 
+3

+1 điều này thật thú vị: D –

+1

Có vẻ như chức năng gọi malloc không thể được liên kết động. Ví dụ, tôi đã viết một tools.c, chứa hàm perform_alloc() gọi hàm malloc. Sau đó, nếu tôi tạo một libtools.so trước và liên kết nó với '-ltools',' -Wl, -wrap, malloc' sẽ không hoạt động. – xanpeng

+1

Được trả lời trong http: // stackoverflow.com/questions/3826108/có-bất cứ ai-một-ví dụ-cho-gói-một-chức năng-in-c nó là cần thiết để tiền tố các định nghĩa chức năng với 'extern" C "' khi sử dụng mã này trong một chương trình C + +. – MKroehnert

2

Ký hiệu được giải quyết bởi trình liên kết theo thứ tự bạn liệt kê chúng trên dòng lệnh, vì vậy nếu bạn liệt kê thư viện của mình trước thư viện chuẩn mà bạn muốn có trước. Đối với gcc, bạn cần phải chỉ định

gcc <BLAH> -nodefaultlibs <BLAH BLAH> -lYOUR_LIB <OTHER_LIBS> 

Cách này thư viện của bạn sẽ được tìm kiếm và tìm thấy trước tiên.

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