2012-06-18 44 views
5

Địa chỉ bắt đầu có thể được lấy từ tên hàm, cách tìm địa chỉ kết thúc của một hàm? Tôi đã được hỏi câu hỏi này trong cuộc phỏng vấn:Làm thế nào để tìm địa chỉ kết thúc của một hàm trong một prog C?

Xem xét hàm f() mà tôi đã viết đã vượt qua phần văn bản và bắt đầu ghi phần lân cận (phần dữ liệu). Làm thế nào tôi có thể xử lý tình trạng này? Ngoài ra, ông nói thêm rằng tôi nên xử lý nó thông qua mã C. Tôi không nên xem tập tin bản đồ ký hiệu và lấy địa chỉ.

+0

Không có cách tiêu chuẩn. Bạn có thể thử lấy địa chỉ của hàm tiếp theo trong tệp, sau đó trừ đi - nhưng không đảm bảo nó sẽ hoạt động. Ví dụ: trình liên kết có thể sắp xếp các hàm theo thứ tự bảng chữ cái, để có thể bao gồm khoảng trống cho các hàm khác hoặc có thể cung cấp kích thước âm. –

+1

Bạn phải chỉ định kiến ​​trúc và ABI hoặc bạn sẽ không nhận được câu trả lời hữu ích. –

+0

"Tôi đã được hỏi câu hỏi này trong cuộc phỏng vấn" Tôi nghi ngờ rằng bạn đã hiểu sai câu hỏi, và họ đã hỏi làm thế nào để nói nếu bạn bắt đầu vô tình thực hiện dữ liệu. Câu trả lời sẽ là "Data Execution Prevention" nếu không được biết đến là một tính năng phần cứng để gắn cờ bộ nhớ không được thực hiện. – Ben

Trả lời

1

Bạn không thể tự sử dụng ngôn ngữ, C không hiển thị khái niệm "kích thước" cho các chức năng.

Điều bạn có thể làm là kiểm tra tệp nhị phân của chương trình và phân tích cú pháp các bảng biểu tượng, v.v.

+0

Bạn có thư viện nào để đề nghị giúp phân tích cú pháp bảng biểu tượng không? Kỳ lạ là tôi không thể tìm thấy một "thư viện đọc elf" nhưng chỉ có một công cụ dòng lệnh –

2

Chuẩn C không đảm bảo rằng có một thứ như địa chỉ kết thúc của hàm.

Trong thực tế, các hàm không nhất thiết là một phần bộ nhớ liên tục duy nhất, nhưng có thể chồng lên nhau hoặc bị phân mảnh trên nhiều phần bằng trình tối ưu hóa mã.

Vì lý do đó, không có cách nào để tìm ra điều này trong thời gian chạy.

Hơn nữa, không có gì đảm bảo rằng "địa chỉ bắt đầu" bạn nhận được từ GetProcAddress hoặc bằng cách lấy địa chỉ của hàm (cho một con trỏ hàm) mang bất kỳ liên quan đến mã thực sự ở đâu.

Tất cả một con trỏ hàm đảm bảo là nếu bạn gọi qua địa chỉ, hàm sẽ được thực hiện. Nó không đảm bảo rằng mã thực sự nằm ở đó. Nó có thể chỉ là địa chỉ của một thunk, ví dụ.

0

Trình biên dịch của bạn có thể tạo tệp danh sách lắp ráp và trình liên kết của bạn có thể tạo tệp bản đồ. Những điều này sẽ cho phép bạn xem một hàm cụ thể theo cách thủ công trong bao lâu. Không chắc chắn nếu bạn cần xác định kích thước từ bên trong chính chương trình C.

5

Với GCC, bạn có thể lấy địa chỉ của nhãn, với toán tử && (có - &&, không phải &).
này có thể được sử dụng như sau:

void f(void) { 
    printf("Start %p End %p\n", f, &&f_end); 
    f_end: return; 
} 

này sẽ không cung cấp cho bạn một cách chính xác khi kết thúc, bởi vì có một số mã lời bạt sau khi nhãn, nhưng tôi nghĩ đó là đủ tốt cho một câu trả lời phỏng vấn.

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