2012-02-02 29 views
6

Làm cách nào chúng ta có thể thay thế hàm thư viện chuẩn C bằng cách thực hiện chức năng đó?Làm thế nào để thay thế hàm thư viện chuẩn C?

Ví dụ: làm thế nào tôi có thể thay thế strcpy() bằng cách triển khai strcpy() của riêng mình và có tất cả các cuộc gọi liên kết đến triển khai mới thay thế?

+0

Tại sao bạn muốn làm điều này? Điều gì có thể * có thể * là điểm? –

+0

Có thực sự đáng giá không? Bạn sẽ phải chỉnh sửa tệp tiêu đề string.h, vị trí của nó phụ thuộc vào hệ thống và môi trường bạn đang sử dụng. Nhưng tôi nghĩ bạn sẽ tốt hơn khi viết một hàm riêng biệt. – Shredderroy

+0

@CodyGray, tôi đoán, nhìn vào câu trả lời của FatalError [http://stackoverflow.com/questions/9107259/how-to-replace-c-standard-library-functioin#9107319), bạn có thể thay thế mọi cuộc gọi trong một thực thi của riêng bạn mà in gỡ lỗi? Hoặc một cái gì đó như thế, tôi đoán vậy. Có lẽ không phải là thực hành tốt mặc dù. Bạn nên viết một hàm mới với một tên khác và thay đổi tất cả các cuộc gọi. – Anthony

Trả lời

12

Ít nhất với GCC và glibc, biểu tượng cho các hàm C chuẩn là yếu và do đó bạn có thể ghi đè lên chúng. Ví dụ,

strcpy.c:

#include <string.h> 
#include <stdio.h> 

char * strcpy(char *dst, const char *src) 
{ 
    char *d = dst; 
    while (*src) { 
    *d = *src; 
    d++; 
    src++; 
    } 
    printf("Called my strcpy()\n"); 

    return (dst); 
} 

int main(void) 
{ 
    char foo[10]; 
    strcpy(foo, "hello"); 

    puts(foo); 

    return 0; 
} 

Và xây dựng nó như thế này:

gcc -fno-builtin -o strcpy strcpy.c 

và sau đó:

$ ./strcpy 
Called my strcpy() 
hello 

Lưu ý tầm quan trọng của -fno-builtin đây. Nếu bạn không sử dụng điều này, GCC sẽ thay thế cuộc gọi strcpy() thành hàm dựng sẵn, trong đó GCC có một số.

Tôi không chắc liệu điều này có hoạt động với các trình biên dịch/nền tảng khác không.

+0

Thực tế thú vị, 'strcpy() 'của tôi ở trên có một lỗ hổng khá nghiêm trọng. Vì nó không thực sự là focuse ở đây, tôi sẽ để nó như một bài tập cho người đọc;). – FatalError

+3

Đó là loại điểm, mặc dù. Thay thế các chức năng thư viện đã thử và đúng với một trong các chức năng của riêng bạn gần như được đảm bảo 100% để có những sai sót nghiêm trọng. –

+0

Đối với lỗ hổng: trong phiên bản này của 'strcpy()', điều kiện vòng lặp sẽ không bao giờ sai nếu 'src' và' dst' bị trùng lặp. – Philip

5

Bạn có thể thử chơi với LD_PRELOAD nếu bạn sử dụng Linux.

+0

Điều này có vẻ là đúng cách. [Ở đây] (https://github.com/nibrahim/Random-hacks/tree/master/malloc-trace) là một ví dụ nhưng câu hỏi thực sự là tại sao? –

+0

Điều này được gọi là interposing một thư viện. Bạn phải tạo một mô-đun C được biên dịch thành PIC (mã vị trí độc lập) thành tệp .so. Sau đó, bạn đặt LD_PRELOAD =/path/to/mystrcpy.so Bạn cũng có thể thực hiện điều tương tự bằng cách gọi dl_open() trong mã của bạn. Nó dễ dàng hơn chỉ đơn giản là để tạo ra biên dịch mystrcpy.c mà vào một mô-đun đối tượng và gọi rằng ở khắp mọi nơi khác trong mã của bạn, và liên kết với mô-đun đối tượng mystrcpy. Bạn sẽ phải sử dụng một khai báo extern cho mystrcpy ở khắp mọi nơi. xem: http://stackoverflow.com/questions/426230/what-is-the-ld-preload-trick –

4

Tôi không chắc chắn sẽ làm cho trình liên kết thực hiện những gì bạn muốn, nhưng đây là giải pháp không liên quan đến việc thay đổi bất kỳ cài đặt trình liên kết nào và sử dụng macro tiền xử lý để bất kỳ mã nào cố gắng gọi strcpy thực sự gọi một chức năng gọi là my_strcpy:

mystuff.h:

#define strcpy my_strcpy 
char * my_strcpy(char * dst, const char * src); 

my_strcpy.c:

#include <mystuff.h> 
char * my_strcpy(char * dst, const char * src); 
{ 
    ... 
} 

my_code.c:

#include <mystuff.h> 

int main() 
{ 
    /* Any call to strcpy will look like a normal call to strcpy 
     but will actually call my_strcpy. */ 
} 
Các vấn đề liên quan