2010-02-22 29 views
12

Chỉ vì tò mò tôi tự hỏi nếu nó có thể di chuyển một đoạn mã trong việc thực hiện một chương trình. Ví dụ, tôi có một chức năng và chức năng này nên được thay thế trong bộ nhớ mỗi lần sau khi nó đã được thực hiện. Một ý tưởng nảy sinh trong tâm trí của chúng tôi là sử dụng mã tự sửa đổi để thực hiện điều đó. Theo một số tài nguyên trực tuyến, tự sửa đổi mã có thể được thực hiện trên Linux, nhưng tôi vẫn không chắc chắn liệu việc di chuyển động có thể thực hiện được hay không. Có ai trải nghiệm điều đó không?di dời động của mã phần

+0

Như rleir cho thấy, sẽ không dễ dàng hơn để trao đổi xung quanh các con trỏ hàm thay vì thực sự di chuyển nội dung? – joveha

Trả lời

8

Có khả năng di chuyển động chắc chắn là có thể. Tuy nhiên, bạn phải đảm bảo rằng mã hoàn toàn độc lập hoặc truy cập vào các hàm tổng quát/hàm bên ngoài theo tham chiếu tuyệt đối. Nếu mã của bạn có thể hoàn toàn độc lập, nghĩa là các tham chiếu duy nhất mà nó tạo ra có liên quan đến chính nó, bạn đã được thiết lập. Nếu không, bạn sẽ cần phải tự sửa lỗi khi tải.

Với GCC, bạn có thể sử dụng -fpic để tạo mã độc lập vị trí. Việc chuyển -q hoặc --emit-relocs tới trình liên kết sẽ làm cho nó phát ra thông tin di chuyển. ELF specification (liên kết PDF) có thông tin về cách sử dụng thông tin di chuyển đó; nếu bạn không sử dụng ELF, bạn sẽ phải tìm tài liệu thích hợp cho định dạng của mình.

0

Nếu tất cả các chức năng khác nhau này tồn tại trong thời gian biên dịch thì bạn có thể chỉ cần sử dụng con trỏ hàm để theo dõi bước tiếp theo sẽ được gọi. Nếu bạn hoàn toàn phải sửa đổi hàm tại thời gian chạy và sửa đổi đó không thể được thực hiện tại chỗ thì bạn cũng có thể sử dụng một con trỏ hàm được cập nhật với địa chỉ của hàm mới khi nó được tạo/nạp. Phần còn lại của hệ thống của bạn sau đó sẽ gọi chức năng tự sửa đổi thông qua con trỏ hàm và do đó không phải biết hoặc quan tâm đến mã tự sửa đổi và bạn chỉ phải thực hiện việc sửa chữa ở một nơi.

3

Như Carl nói, có thể thực hiện được, nhưng bạn đang mở một hộp giun. Trong thực tế, những người duy nhất gặp khó khăn để làm điều này là các tác giả học giả hoặc phần mềm độc hại (giờ đã mặc chiếc áo choàng chống cháy của tôi).

Bạn có thể sao chép một số mã vào vùng heap malloc'd, sau đó gọi nó qua con trỏ hàm, nhưng tùy thuộc vào hệ điều hành bạn có thể phải bật thực thi trong phân khúc. Bạn có thể thử sao chép một số mã vào phân đoạn mã (chú ý không ghi đè lên hàm sau), nhưng hệ điều hành có thể đã tạo phân đoạn này chỉ đọc. Bạn có thể muốn xem hạt nhân Linux và xem nó tải các mô-đun của nó như thế nào.

+1

+1 tổng hợp một số điểm tốt đẹp. Về các chế độ trang để viết/thực thi: Bạn có thể thay đổi những điều đó khi đang bay với VirtualProtect trên win32 và mprotect trên linux. Và tất cả các trang có thể đọc được cũng có thể thực thi được vì tổ tiên của chúng ta đã hiểu lầm điều gì đó – joveha

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