Trong chương trình của tôi C++ (trên Windows), tôi đang phân bổ một khối bộ nhớ và có thể chắc chắn rằng nó vẫn bị khóa (unswapped và tiếp giáp) trong bộ nhớ vật lý (tức là sử dụng VirtualAllocEx(), MapUserPhysicalPages() v.v.)
Không, bạn thực sự không thể đảm bảo rằng nó vẫn bị khóa. Điều gì sẽ xảy ra nếu quá trình của bạn bị lỗi hoặc thoát sớm? Nếu người dùng giết nó thì sao? Bộ nhớ đó sẽ được tái sử dụng cho một thứ khác và nếu thiết bị của bạn vẫn đang thực hiện DMA, điều đó cuối cùng sẽ dẫn đến mất dữ liệu/tham nhũng hoặc kiểm tra lỗi (BSOD).
Ngoài ra, MapUserPhysicalPages
là một phần của Windows AWE (Tiện ích mở rộng địa chỉ cửa sổ), để xử lý hơn 4 GB RAM trên các phiên bản Windows Server 32 bit. Tôi không nghĩ rằng nó được dự định sẽ được sử dụng để hack DMA chế độ người dùng.
1. Có cách nào để tôi có thể dịch địa chỉ ảo sang địa chỉ thực trong chương trình của tôi, ở chế độ USER không?
Có trình điều khiển cho phép bạn thực hiện việc này, nhưng bạn không thể lập trình DMA từ chế độ người dùng trên Windows và vẫn có hệ thống ổn định và bảo mật. Để một quá trình chạy như một tài khoản người dùng hạn chế đọc/ghi bộ nhớ vật lý cho phép quá trình sở hữu hệ thống. Nếu điều này là cho một hệ thống một lần hoặc một mẫu thử nghiệm, điều này có thể chấp nhận được, nhưng nếu bạn mong đợi những người khác (đặc biệt là khách hàng trả tiền) sử dụng phần mềm và thiết bị của bạn, bạn nên viết một trình điều khiển.
2. Nếu không, tôi có thể tìm hiểu bản đồ ảo này với vật lý chỉ trong chế độ KERNEL. Tôi đoán nó có nghĩa là tôi phải viết một trình điều khiển để làm điều đó ...?
Đó là cách được đề xuất để tiếp cận vấn đề này.
Bạn có biết bất kỳ trình điều khiển/API/API sẵn có nào mà tôi có thể sử dụng, mà ứng dụng (chương trình) của tôi sẽ giao tiếp với bản dịch không?
Bạn có thể sử dụng MDL (Memory Descriptor List) để khóa bộ nhớ tùy ý, bao gồm bộ đệm được sở hữu bởi quy trình chế độ người dùng và dịch địa chỉ ảo của nó thành địa chỉ thực. Bạn cũng có thể có Windows tạm thời tạo MDL cho bộ đệm được chuyển vào cuộc gọi đến DeviceIoControl
bằng cách sử dụng METHOD_IN_DIRECT
hoặc METHOD_OUT_DIRECT
.
Lưu ý rằng các trang tiếp giáp trong không gian địa chỉ ảo hầu như không bao giờ tiếp giáp trong không gian địa chỉ thực. Hy vọng rằng thiết bị của bạn được thiết kế để xử lý điều đó.
3. Trong trường hợp tôi phải tự mình viết trình điều khiển, làm cách nào để thực hiện bản dịch này? tôi sử dụng chức năng nào? Có phải mmGetPhysicalAddress() không? Làm thế nào để tôi sử dụng nó?
Có nhiều thứ để viết trình điều khiển hơn là chỉ cần gọi một vài API. Nếu bạn định viết trình điều khiển, tôi khuyên bạn nên đọc nhiều tài liệu liên quan như bạn có thể từ MSDN và OSR. Ngoài ra, hãy xem các ví dụ trong số Windows Driver Kit.
4. Ngoài ra, nếu tôi hiểu chính xác, mmGetPhysicalAddress() trả về địa chỉ vật lý của địa chỉ cơ sở ảo trong ngữ cảnh của quá trình gọi. Nhưng nếu quá trình gọi là trình điều khiển, và tôi đang sử dụng ứng dụng của mình để gọi trình điều khiển cho chức năng đó, tôi đang thay đổi ngữ cảnh và tôi không còn trong ngữ cảnh của ứng dụng khi thường trình mmGetPhysicalAddress được gọi là ... làm cách nào để dịch địa chỉ ảo trong không gian bộ nhớ của ứng dụng (chế độ người dùng), không phải trình điều khiển?
Trình điều khiển không phải là quy trình. Một trình điều khiển có thể chạy trong bối cảnh của bất kỳ quá trình nào, cũng như các bối cảnh nâng cao khác nhau (các trình xử lý ngắt và các DPC).
Tôi tò mò, thiết bị bên ngoài có thể làm gì với địa chỉ bộ nhớ vật lý? – jyoung
Nếu không đi vào chi tiết, nó là một thiết bị trên máy có quyền truy cập trực tiếp vào RAM của máy, nhưng không biết về ánh xạ hệ điều hành (đó là lý do tại sao địa chỉ ảo hoặc sử dụng đối tượng bộ nhớ chia sẻ sẽ không hoạt động). –