2010-12-16 4 views
16

От ReadProcessMemory in MSDN:Почему у ReadProcessMemory есть `lpNumberOfBytesRead`?

lpBaseAddress [в]:
указатель на базовый адрес в указанном процессе, из которого читать. Прежде чем произойдет какая-либо передача данных, система проверит, что все данные в базовом адресе и памяти указанного размера доступны для доступа к чтению, а если он недоступен, функция выходит из строя.

nРазмер: [в]:
Число байтов, которые должны быть считаны из указанного процесса.

lpNumberOfBytesRead [выход]
Указатель на переменную, которая получает число байтов, переданных в указанный буфер. Если значение lpNumberOfBytesRead равно NULL, параметр игнорируется.

So .. ReadProcessMemory может полностью преуспеть или полностью провалиться. И размер, очевидно, известен вызывающему, - должен был передать его, чтобы позвонить. Почему есть lpNumberOfBytesRead?

+5

Это хороший вопрос. – paxdiablo 2010-12-16 03:30:38

+0

@paxdiablo: Спасибо :) – 2010-12-16 03:32:30

+0

Тёмная магия здесь. Существует определенная ошибка ERROR_PARTIAL_COPY, которая гласит: «Выполняется только часть запроса ReadProcessMemory или WriteProcessMemory». Это, кажется, летит перед лицом «полного успеха или неудачи», но я понятия не имею, что правильно. – paxdiablo 2010-12-16 03:49:54

ответ

10

От winerror.h:

// 
// MessageId: ERROR_PARTIAL_COPY 
// 
// MessageText: 
// 
// Only part of a ReadProcessMemory or WriteProcessMemory request was completed. 
// 
#define ERROR_PARTIAL_COPY    299L 

ReadProcessMemory возвратит FALSE и GetLastError вернется ERROR_PARTIAL_COPY когда копия попадает страничную ошибку. Это общий сценарий в самосвалах, которые должны работать с потенциально поврежденным процессом, поэтому они не могут быть уверены, что запрашиваемая область действительна или нет (указатель, который они преследовали, чтобы получить начальный адрес, мог быть поврежден и указать на la- ла-земля), но они все равно хотели бы скопировать как можно больше на свалку.

3

Возможно, в некоторых предыдущих версиях API эта функция не полностью провалилась, но могла возвращать частичные результаты. Таким образом, параметр out сохраняется для совместимости, но более новые программы могут передавать NULL и игнорировать его.

0

Другая возможность, кроме 9000's answer, заключается в том, что этот параметр существует для будущих целей расширения. Возможно, в какой-то момент (и, возможно, даже сейчас) планировалось реализовать реализации ReadProcessMemory, которые могли бы частично потерпеть неудачу, поэтому по этой причине был поставлен параметр out. Это было бы (не особенно хорошим) способом избежать всего API/APIEx/APIEx2/любой проблемы, с которой API-интерфейсы Win32 работали в течение многих лет.

1

Я предполагаю, что область может быть доступна с точки зрения разрешений, но ошибка в ошибке страницы может позволить только ее части читать. Впрочем, это только предположение.

Edit: Смотрите эту страницу: ReactOS - STATUS_PARTIAL_COPY

> // Otherwise, we failed probably during the move 

Похоже, что любая проблема, которая находится вне контроля функции может вернуть этот код ошибки.

0

Существует неотъемлемое состояние гонки. Копии не мгновенные. Конечно, функция проверяет, будет ли она успешной, но возможно, что диапазон памяти не будет отображаться во время копирования. Это еще один процесс, который вы ищете, в конце концов, скорее всего, не знает о вашем текущем ReadProcessMemory().

(Remus Rusanu также намекнул на такую ​​частичную копию, но предположил, что причиной является коррумпированный процесс, а не гонка.)

Смежные вопросы