2011-07-30 25 views
6

Tiêu đề rõ ràng, chúng tôi có thể tải thư viện theo dl_open v.v.Có thể nhận được chữ ký của hàm trong thư viện được chia sẻ theo chương trình không?

Nhưng làm cách nào tôi có thể nhận được chữ ký của hàm?

+0

Bạn có thể tìm thấy các bài viết Wikipedia vào tên mangling thông tin , để xem các thông tin được mã hóa trong tên mã đối tượng cho C vs C++ và làm thế nào nó thay đổi theo trình biên dịch: http://en.wikipedia.org/wiki/Name_mangling – HostileFork

+0

@Hostile Fork, trong một ** đơn ** '.so ', là nó có thể có mang tên khác nhau? –

+0

Như đã lưu ý trong bài viết trên Wikipedia, tên mangling trong C chỉ hỗ trợ các quy ước của Windows và sẽ không xuất hiện trong các tệp '.so'. Đối với C++ có, các cây con khác nhau của cùng một tên hàm xuất hiện trong một '.so' để hỗ trợ tính năng ngôn ngữ của quá tải. http://en.wikipedia.org/wiki/Function_overloading – HostileFork

Trả lời

4

Không thể thực hiện điều này. Chữ ký của một hàm không có nghĩa là bất cứ thứ gì trong thời gian chạy, nó là một mẩu thông tin hữu ích trong thời gian biên dịch cho trình biên dịch để xác nhận hợp lệ chương trình của bạn.

+0

Tôi không nghĩ rằng tuyên bố này là chính xác, bạn về cơ bản chỉ khoát nói rằng nó là không thể. Có rất nhiều thứ có thể được thực hiện để khôi phục chữ ký; bạn có thể nhìn vào quy ước gọi, và nếu bạn có thể sử dụng phân tích taint, bạn có thể theo dõi các đối số từ các chữ ký đã biết khác và trả về các kiểu trở lại hàm mong muốn. –

1

Bạn không thể. Thư viện xuất bản API công khai trong tiêu đề hoặc bạn cần biết chữ ký của một số phương tiện khác.

0

Các tham số của hàm ở cấp thấp hơn phụ thuộc vào số lượng đối số ngăn xếp trong khung ngăn xếp mà bạn xem xét và cách bạn diễn giải chúng. Do đó một khi hàm được biên dịch thành mã đối tượng thì không thể có được chữ ký như thế. Một khả năng từ xa là để tháo rời mã và đọc nó hoạt động như thế nào để biết số nếu các tham số, nhưng vẫn loại sẽ khó hoặc không thể xác định được. Trong một từ, nó là không thể.

0

Thông tin này không có sẵn. Ngay cả trình gỡ rối cũng biết:

$ cat foo.c 
#include <stdio.h> 
#include <string.h> 

int main(int argc, char* argv[]) 
{ 
    char foo[10] = { 0 }; 
    char bar[10] = { 0 }; 
    printf("%s\n", "foo"); 
    memcpy(bar, foo, sizeof(foo)); 
    return 0; 
} 

$ gcc -g -o foo foo.c 
$ gdb foo 
Reading symbols from foo...done. 
(gdb) b main 
Breakpoint 1 at 0x4005f3: file foo.c, line 5. 
(gdb) r 
Starting program: foo 

Breakpoint 1, main (argc=1, argv=0x7fffffffe3e8) at foo.c:5 
5 { 
(gdb) ptype printf 
type = int() 
(gdb) ptype memcpy 
type = int() 
(gdb) 
+0

Ít nhất trình gỡ rối biết đó là hàm, 'int()'. –

+0

@Je Rog, nhưng như bạn có thể nhìn thấy cho 'memcpy' nó chỉ áp dụng các quy tắc mặc định cho kiểu trả về, vì vậy ngay cả đó không phải là rất hữu ích. –

+0

@Jens Gustedt, bạn có biết trình gỡ rối biết đó là chức năng ở nơi đầu tiên không? –

7

Câu trả lời này không thể trả lời được. Về mặt kỹ thuật nếu bạn biên dịch tệp thực thi của mình với thông tin gỡ lỗi toàn diện (mã vẫn có thể là phiên bản được tối ưu hóa), thì tệp thực thi sẽ chứa các phần bổ sung, cung cấp một số loại phản xạ của nhị phân. Trên các hệ thống * nix (bạn gọi là dl_open), điều này được thực hiện thông qua dữ liệu gỡ lỗi DWARF trong các phần bổ sung của mã nhị phân ELF. Tương tự, nó hoạt động với Mach Universal Binaries trên MacOS X.

Windows PEs tuy nhiên sử dụng định dạng hoàn toàn khác nhau, vì vậy không may DWARF không phải là dạng bảng chữ cái truley (thực tế là trong giai đoạn phát triển ban đầu của công cụ 3D của tôi, tôi đã triển khai ELF/Trình tải DWARF cho Windows, để tôi có thể sử dụng một định dạng chung cho các mô-đun động cơ khác nhau, vì vậy với một số nỗ lực nghiêm túc như vậy có thể được thực hiện).

Nếu bạn không muốn triển khai trình tải của riêng mình hoặc gỡ lỗi trình truy cập thông tin, bạn có thể nhúng thông tin phản chiếu thông qua một số biểu tượng bổ sung được xuất (theo một số lược đồ đặt tên chuẩn) tham chiếu đến bảng tên hàm , lập bản đồ cho chữ ký của họ. Trong trường hợp các tệp nguồn C viết một trình phân tích cú pháp để trích xuất thông tin từ tệp nguồn chính nó là khá tầm thường. C++ OTOH rất khó phân tích chính xác, bạn cần một trình biên dịch đầy đủ để có được đúng. Đối với mục đích này GCCXML được phát triển, về mặt kỹ thuật một GCC phát ra AST dưới dạng XML thay vì một đối tượng nhị phân. Sau đó, XML được phát ra dễ phân tích cú pháp hơn.

Từ thông tin được trích xuất, hãy tạo tệp nguồn với một số loại danh sách/mảng được liên kết/v.v. cấu trúc mô tả từng chức năng. Nếu bạn không trực tiếp xuất khẩu biểu tượng của mỗi hàm nhưng thay vì khởi tạo một số trường trong cấu trúc phản chiếu bằng con trỏ hàm, bạn có một lược đồ xuất khẩu chú thích thực sự tốt đẹp và sạch sẽ. Về mặt kỹ thuật, bạn có thể đặt thông tin này trong phần spearate của nhị phân, nhưng đặt nó vào phần dữ liệu chỉ đọc cũng thực hiện công việc.


Tuy nhiên nếu bạn đang đưa ra một nhị phân bên thứ 3 - nói kịch bản trường hợp xấu nhất nó đã được biên soạn từ nguồn C, không có thông tin gỡ lỗi và tất cả các biểu tượng không tham chiếu từ ngoài tước - bạn đang khá nhiều hơi say. Điều tốt nhất bạn có thể làm là áp dụng một số phân tích nhị phân về cách hàm truy cập vào các vị trí khác nhau trong đó các tham số có thể được truyền đi.

này sẽ chỉ cho bạn biết số lượng các thông số và kích thước của mỗi giá trị tham số, nhưng không phải là loại hoặc tên/ý nghĩa. Khi kỹ thuật đảo ngược một số chương trình (ví dụ: phân tích phần mềm độc hại hoặc kiểm tra bảo mật), việc xác định loại và ý nghĩa của các tham số được truyền cho các chức năng là một trong những nỗ lực chính. Gần đây tôi đã xem qua một số tài xế tôi phải đảo ngược cho mục đích gỡ lỗi, và bạn không thể tin như thế nào sửng sốt tôi đã bởi thực tế là tôi thấy C ký ++ trong một mô-đun hạt nhân Linux (bạn không thể sử dụng C++ trong nhân Linux theo một cách lành mạnh), nhưng cũng nhẹ nhõm, vì tên mang tên C++ cung cấp cho tôi nhiều thông tin.

0

Trên Linux (hoặc Mac), bạn có thể sử dụng một sự kết hợp của "nm" và "C++ filt" (đối với C++ thư viện)

nm mylibrary.so | C++ filt

hoặc

nm mylibrary.a | C++ filt

"nm" sẽ cung cấp cho bạn biểu mẫu bị cắt xén và "C++ filt" cố gắng đặt chúng ở định dạng dễ đọc hơn. Bạn có thể muốn sử dụng một số tùy chọn trong nm để lọc xuống các kết quả, đặc biệt là nếu thư viện lớn (hoặc bạn có thể "grep" đầu ra cuối cùng để tìm một mục cụ thể)

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