Làm thế nào một người sẽ đi về đọc bộ nhớ từ một quá trình? Có khác hệ điều hành không?


11

Là một nhà phát triển web có kinh nghiệm, nhưng là một lập trình viên "cấp thấp" mới làm quen, công cụ này vẫn còn khá tốt đối với tôi.

Tôi tò mò về cách người ta thậm chí sẽ bắt đầu tìm kiếm một khối bộ nhớ, và sau đó đọc nó (ví dụ, đọc bộ đếm thời gian trong trò chơi khai thác mỏ)? Đây có phải là khác nhau bởi phiên bản OS / OS?

Câu trả lời:


14

Đây là một câu hỏi hơi khó và thậm chí phức tạp, theo một nghĩa nào đó mà bạn có thể đi khá sâu với điều này. Nhưng để đơn giản hóa mọi thứ một chút:

Xem xét ví dụ của bạn về " đọc bộ đếm thời gian trong trò chơi mỏ ":

Bước đầu tiên là tìm địa chỉ bộ nhớ . Điều này thường được thực hiện với một công cụ gọi là trình soạn thảo bộ nhớ (một trình gỡ lỗi cũng sẽ làm như vậy, trong một số trường hợp) có thể sử dụng các phương pháp khác nhau để tìm vị trí của một biến trong bộ nhớ tiến trình . Cách phổ biến là tìm kiếm một giá trị nhất định (ví dụ giá trị của bộ định thời gian) trong không gian bộ nhớ của quá trình đích, sau đó thay đổi giá trị đích (ví dụ: nâng cao bộ hẹn giờ) và tìm lại kết quả khớp. Quá trình này ghim các ứng cử viên mỗi lần lặp cho đến khi chỉ còn lại biến chính xác. Lấy địa chỉ của biến đó trong không gian bộ nhớ của quy trình chỉ là vấn đề nhấp chuột với trình chỉnh sửa bộ nhớ.

Bước thứ hai là sửa đổi dữ liệu trong địa chỉ cụ thể đó . Làm thế nào điều này được thực hiện phụ thuộc vào hệ điều hành. Với Windows , có một cuộc gọi WinAPI có tên WriteProcessMemoryđược sử dụng để ghi dữ liệu được xác định trước vào một địa chỉ nhất định trong không gian bộ nhớ của quy trình đích. Trong ví dụ của chúng tôi, bạn sẽ sử dụng chức năng này để ghi đè biến hẹn giờ trong quy trình mục tiêu với giá trị mong muốn của riêng bạn, thay đổi hiệu quả bộ hẹn giờ trong trò chơi.

Trong thực tế, bạn phải tìm ID tiến trình của quy trình đích , sau đó đính kèm quy trình giả mạo của bạn vào quy trình đích để có được khả năng sửa đổi không gian bộ nhớ của nó. Đây là một nhiệm vụ khá nhỏ, nhưng không góp phần trả lời câu hỏi nên tôi đã bỏ nó ra như một bài tập cho người đọc. ;)


Vị trí của biến có giống nhau mỗi khi tiến trình chạy không?
brunoqc

1
@brunoqc Không, gần như chắc chắn là không.
Dan

2

Nó hoàn toàn khác biệt bởi HĐH. Một số sẽ không cho phép bạn làm điều đó và bạn phải có một số phương tiện để biết dữ liệu bạn muốn ở đâu trong không gian bộ nhớ của mục tiêu.

Đây là cách thực hiện trên Linux: /unix/6301/how-do-i-read-from-proc-pid-mem-under-linux


HĐH nào không cho phép? Dường như bạn có thể làm điều đó trong Linux và Windows, ít nhất là
Eva

@Evan Mọi hệ điều hành phải cho phép (bị hạn chế, vì lý do bảo mật) có nghĩa là sửa đổi bộ nhớ quy trình từ xa cho mục đích gỡ lỗi. Tuy nhiên, xin lưu ý rằng ví dụ về sự không phù hợp đặc quyền vì lý do bảo mật có thể khiến nó không thể đọc / ghi bộ nhớ tiến trình của một quy trình đặc quyền cao hơn. Một ví dụ điển hình cho việc này là không để một quy trình có đặc quyền người dùng khách đọc / ghi bộ nhớ của một quy trình với quyền quản trị viên, vì điều đó có khả năng thỏa hiệp toàn bộ hệ thống và là cách trực tiếp để người dùng khách có được quyền quản trị viên trên hệ thống.
zxcdw

1

Một ứng dụng được HĐH cấp cho một bộ nhớ. Nói chung, ứng dụng phải yêu cầu bộ nhớ nhưng chức năng đó có thể bị che khuất đối với lập trình viên vì ngôn ngữ.

Các ngôn ngữ như C cho phép các yêu cầu chặn cho các kích thước cụ thể, trong khi các ngôn ngữ khác như C ++, C # và Java cho phép các yêu cầu thông qua việc sử dụng các từ khóa như new. Mỗi ngôn ngữ có một số cách để phân bổ bộ nhớ, vì vậy đây chỉ là một tổng quan ngắn gọn. Việc giải phóng bộ nhớ trở lại HĐH có thể được thực hiện rõ ràng hoặc thông qua trình thu gom rác.

Truy cập bộ nhớ trong ứng dụng tùy thuộc vào cách phân bổ. C và C ++ được biết đến nhiều nhất khi sử dụng khái niệm con trỏ để chỉ ra / theo dõi vị trí của bộ nhớ. Mặt khác, truy cập bộ nhớ được xử lý thông qua lớp hoặc biến được tạo.

Hầu hết thời gian, bạn không phải lo lắng về việc truy cập bộ nhớ cụ thể trong chương trình của mình. Các cấu trúc ngôn ngữ và hệ điều hành che khuất một cách hiệu quả mối quan tâm dành cho bạn.

Ví dụ về bộ đếm thời gian trong trò chơi của bạn là một ví dụ tuyệt vời về việc bạn không cần phải lo lắng về việc phân bổ bộ nhớ cơ bản. Bạn sẽ có một biến đại diện cho bộ đếm thời gian và bạn sẽ chỉ đọc từ biến đó.

Câu trả lời của tôi có liên quan khi bạn viết ứng dụng, trong khi câu trả lời của zxcdw có liên quan đến việc truy cập bộ nhớ thuộc về ứng dụng khác. Các thuật ngữ LMGTFY của bạn sẽ là "gỡ lỗi" và "kỹ thuật đảo ngược" để đi sâu hơn vào chủ đề đó.

Một số đọc thêm:

  • Bài viết Wikipedia về Bộ nhớ máy tính sẽ cung cấp cho bạn một cái nhìn tổng quan về mọi thứ.
  • Sau đó xem bài viết trên Wikipedia về I / O được ánh xạ bộ nhớ để hiểu sâu hơn về các mưu mô đang diễn ra.
  • Cuối cùng, hãy xem bài viết về Bộ nhớ ảo để có câu trả lời tốt hơn về cách mỗi hệ điều hành sẽ xử lý ánh xạ bộ nhớ khác một chút so với các bộ nhớ khác.

câu trả lời tuyệt vời, mặc dù có, trong trường hợp này tôi quan tâm nhiều hơn đến việc đọc bộ nhớ từ một ứng dụng mà tôi không tự viết. Tôi sẽ nâng cấp ngay khi tôi có 15 đại diện;)
Eva

@Evan - Chắc chắn đã đọc bài viết về Bộ nhớ ảo rồi. Điều đó sẽ cho bạn hiểu rõ hơn về bản đồ đang diễn ra. Bạn phải hiểu bản đồ để chọn ra một ứng dụng. Hầu hết các trình gỡ lỗi sẽ cho phép bạn đính kèm vào một quy trình đang chạy, cho phép bạn xem các hướng dẫn và bộ nhớ của ứng dụng.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.