2012-05-02 23 views
15

Hồ ELF cho thực thi có một chương trình (phân đoạn) header và một tiêu đề phần, có thể được nhìn thấy qua readelf -a, đây là một ví dụ:phần nào của tệp ELF phải được tải vào bộ nhớ?

enter image description here

enter image description here

Hai hình ảnh trên là tiêu đề phần và chương trình (phân đoạn) tiêu đề, tương ứng. Có thể thấy rằng một tiêu đề phân đoạn bao gồm một số tiêu đề phần, được sử dụng để tải chương trình vào bộ nhớ.

Chỉ cần các phần .text, .rodata, .data, .bss được tải vào bộ nhớ?

Có phải tất cả các phần khác trong phân khúc (ví dụ: .ctors, .dtors .jcr trong phân khúc thứ 3) được sử dụng để căn chỉnh không?

+1

Đối với _aligning_? –

+0

@ Adriano, có căn chỉnh với kích thước trang, vì vậy bảo vệ khác nhau có thể được sử dụng cho các phần khác nhau của chương trình, ví dụ .tiếp theo (rx), dữ liệu (rw-) –

Trả lời

18

Các phần và phân đoạn là hai khái niệm hoàn toàn khác nhau. Các phần liên quan đến ngữ nghĩa của dữ liệu được lưu trữ ở đó (nghĩa là dữ liệu sẽ được sử dụng) và thực sự không liên quan khi chương trình hoặc thư viện được chia sẻ được liên kết ngoại trừ mục đích gỡ lỗi. Bạn thậm chí có thể loại bỏ các tiêu đề phần hoàn toàn (hoặc ghi đè lên chúng với rác ngẫu nhiên) và một chương trình sẽ vẫn hoạt động.

Phân đoạn (tức là chỉ thị tải chương trình) là những gì mà trình liên kết hạt nhân và/hoặc động thực sự xem xét khi tải chương trình. Ví dụ, trong trường hợp của bạn, bạn có hai chỉ thị tải. Việc đầu tiên gây ra 4k đầu tiên (1 trang) của tệp được ánh xạ tại địa chỉ 0x08048000 và chỉ ra rằng chỉ 0x4b8 byte đầu tiên của ánh xạ này thực sự được sử dụng (phần còn lại là căn chỉnh). Nguyên nhân thứ hai là 8k (2 trang) đầu tiên của tệp được ánh xạ tại địa chỉ 0x08049000. Phần lớn trong số đó là sự liên kết. Các byte 0xf14 đầu tiên không phải là một phần của chỉ thị tải (chỉ cần căn chỉnh) và sẽ bị lãng phí. Bắt đầu từ 0x08049f14, 0x108 byte được ánh xạ từ tệp thực sự được sử dụng và một byte 0x10 khác (để đạt đến MemSize 0x118) được điền bằng trình tải (kernel hoặc liên kết động). Điều này kéo dài lên đến 0x0804a02c (trong trang ánh xạ thứ hai). Phần còn lại của trang được ánh xạ thứ hai không được sử dụng/lãng phí (nhưng malloc có thể khôi phục nó để sử dụng như một phần của vùng heap).

Cuối cùng, trong khi tiêu đề phần sẽ không được sử dụng, nội dung của nhiều phần khác nhau có thể được chương trình của bạn sử dụng trong khi chương trình đang chạy. Lưu ý rằng các dải địa chỉ của .ctors.dtors nằm ở đầu bản đồ tải thứ hai, vì vậy chúng được ánh xạ và truy cập bởi chương trình lúc chạy (mã khởi động/thoát thời gian chạy sẽ sử dụng chúng để chạy các hàm tạo và hủy toàn cầu, nếu C++ hoặc Mã "GNU C" với thuộc tính ctor/dtor đã được sử dụng). Cũng lưu ý rằng .data bắt đầu tại địa chỉ 0x0804a00c, trong trang được ánh xạ thứ hai. Điều này cho phép trang đầu tiên được bảo vệ chỉ đọc sau khi các thay đổi được áp dụng (chỉ thị RELRO trong tiêu đề chương trình).

+0

+1 để chỉ ra GNU_RELRO – SquareRootOfTwentyThree

+0

Có C có nhà thầu hoặc destructors như C++? –

+0

Không, nhưng GCC không phải là C, đó là "GNU C". Bạn có thể làm tất cả các loại công cụ không chuẩn như ngoại lệ và nhà thầu. –

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