Tôi tự hỏi nếu có cách viết bảo vệ mọi trang trong không gian địa chỉ của quá trình Linux '(từ bên trong của quá trình, theo cách mprotect()
). Bởi "mọi trang", tôi thực sự có nghĩa là mọi trang trong không gian địa chỉ của quá trình có thể được viết bởi chương trình thông thường đang chạy ở chế độ người dùng - vì vậy, văn bản chương trình, hằng số, các hình cầu và đống - - nhưng tôi sẽ hạnh phúc chỉ với các hằng số, hình cầu và đống. Tôi không muốn viết-bảo vệ ngăn xếp - rằng có vẻ như là một ý tưởng tồi.Tôi có thể viết-bảo vệ mọi trang trong không gian địa chỉ của một quy trình Linux không?
Một vấn đề là tôi không biết bắt đầu từ đâu để bảo vệ ghi bộ nhớ. Nhìn vào /proc/pid/maps
, hiển thị các phần của bộ nhớ khi sử dụng cho một pid đã cho, chúng dường như luôn bắt đầu với địa chỉ 0x08048000
, với văn bản chương trình. (Trong Linux, theo như tôi có thể biết, bộ nhớ của một quá trình được đặt ra với văn bản chương trình ở đáy , sau đó hằng số trên đó, sau đó tổng số, sau đó heap, sau đó một khoảng trống có kích thước khác nhau tùy thuộc vào trên kích thước của đống hoặc ngăn xếp, và sau đó ngăn xếp phát triển từ đầu bộ nhớ tại địa chỉ ảo 0xffffffff
.) Có cách để biết vị trí đầu của số là (bằng cách gọi sbrk(0)
, con trỏ tới số hiện tại "ngắt", nghĩa là phần trên cùng của vùng heap), nhưng không thực sự là cách để cho biết nơi bắt đầu đống.
Nếu tôi cố gắng bảo vệ tất cả các trang từ 0x08048000
đến giờ nghỉ, tôi cuối cùng cũng gặp lỗi mprotect: Cannot allocate memory
. Tôi không biết tại sao mprotect
sẽ là vẫn phân bổ bộ nhớ - và Google không hữu ích lắm. Ý tưởng nào?
Nhân tiện, lý do tôi muốn làm điều này là vì tôi muốn tạo một danh sách của tất cả các trang được viết trong khi chạy chương trình và cách tôi có thể nghĩ đến việc này là viết bảo vệ tất cả các trang, cho phép bất kỳ lần ghi nào gây ra lỗi ghi, sau đó thực hiện ghi xử lý lỗi sẽ thêm trang vào danh sách rồi xóa bảo vệ viết . Tôi nghĩ rằng tôi biết làm thế nào để thực hiện xử lý, nếu chỉ tôi có thể tìm ra các trang để bảo vệ và làm thế nào để làm điều đó.
Cảm ơn!
Tôi thực sự đã có mã thực hiện chính xác những gì bạn đang cố gắng làm. Ý tưởng của bạn sẽ hoạt động, nhưng bạn không thể bảo vệ các trang mà danh sách "những trang được viết" của bạn sẽ cư trú, hoặc trình xử lý SEGV của bạn sẽ gây ra SEGV! – Borealid
@Borealid, cảm ơn, và đó là vấn đề mà tôi đang cố gắng giải quyết (tôi đã có trình xử lý segfault và phân tích/proc/self/maps đang hoạt động ngay bây giờ). Làm cách nào để tránh bảo vệ (các) trang có chứa danh sách đó? Phân bổ danh sách trên ngăn xếp sẽ hoạt động, nhưng sau đó tôi không thấy bất kỳ cách nào để chuyển nó cho trình xử lý. Ngoài ra, tôi có thể phân bổ nó như là một toàn cầu, nhưng tôi muốn sử dụng một cấu trúc dữ liệu fancier hơn một mảng có độ dài cố định (như một container STL), và tôi không phải lúc nào cũng biết danh sách mà tôi đang viết ở đâu trong trí nhớ. –
@borealid: Bạn nói rằng bạn có mã thực hiện chính xác điều này - bạn có nhớ chia sẻ mã của mình không? Tôi mới ở đây và tôi không thể tìm cách liên hệ trực tiếp với bạn (kênh sau). Tôi đang cố gắng làm chính xác những gì Linsey đang làm, vì vậy mọi mẫu mã sẽ rất hữu ích. –