简体   繁体   English

为什么ReadProcessMemory有`lpNumberOfBytesRead`?

[英]Why does ReadProcessMemory have `lpNumberOfBytesRead`?

From ReadProcessMemory in MSDN: MSDN中的ReadProcessMemory:

lpBaseAddress [in] : lpBaseAddress [in]
A pointer to the base address in the specified process from which to read. 指向要从中读取的指定进程中的基址的指针。 Before any data transfer occurs, the system verifies that all data in the base address and memory of the specified size is accessible for read access, and if it is not accessible the function fails. 在发生任何数据传输之前,系统会验证基本地址和指定大小的内存中的所有数据是否都可以进行读访问,如果无法访问,则该函数将失败。

nSize [in] : nSize [in]
The number of bytes to be read from the specified process. 要从指定进程读取的字节数。

lpNumberOfBytesRead [out] lpNumberOfBytesRead [out]
A pointer to a variable that receives the number of bytes transferred into the specified buffer. 指向变量的指针,该变量接收传输到指定缓冲区的字节数。 If lpNumberOfBytesRead is NULL, the parameter is ignored. 如果lpNumberOfBytesRead为NULL,则忽略该参数。

So.. ReadProcessMemory can only completely succeed or completely fail. 所以.. ReadProcessMemory只能完全成功或完全失败。 And the size is obviously known to the caller -- had to pass it in to make the call. 并且呼叫者显然知道大小 - 必须将其传入以进行呼叫。 Why have the lpNumberOfBytesRead ? 为什么有lpNumberOfBytesRead

From winerror.h : 来自winerror.h

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

ReadProcessMemory would return FALSE and GetLastError would return ERROR_PARTIAL_COPY when the copy hits a page fault. 当副本遇到页面错误时, ReadProcessMemory将返回FALSE并且GetLastError将返回ERROR_PARTIAL_COPY This is a common scenario in dumpers, which have to work on a potentially corrupted process so they can't be sure if the requested area is valid or not (the pointer they chased to get the start address could be corrupted and point to la-la-land), but they would still like to copy as much as possible into the dump. 这是转储器中的常见情况,它必须处理可能已损坏的进程,因此无法确定所请求的区域是否有效(他们追逐以获取起始地址的指针可能已损坏并指向la- la-land),但他们仍然希望尽可能多地复制到垃圾场。

Maybe in some previous API versions this function did not completely fail, but could return partial results. 也许在以前的一些API版本中,此函数并未完全失败,但可能会返回部分结果。 So the out parameter is kept for compatibility, but newer programs can pass a NULL and ignore it. 因此保持out参数以保持兼容性,但较新的程序可以传递NULL并忽略它。

I'm guessing that the area might be accessible in terms of permissions, but an error in a page fault might only allow part of it to be read. 我猜这个区域可能在权限方面是可访问的,但是页面错误中的错误可能只允许读取其中的一部分。 That's just a guess though. 这只是一个猜测。

Edit: See this page: ReactOS - STATUS_PARTIAL_COPY 编辑:请参阅此页: ReactOS - STATUS_PARTIAL_COPY

> // Otherwise, we failed  probably during the move

It seems like any problem that's out of the control of the function might return this error code. 似乎任何不受函数控制的问题都可能返回此错误代码。

There's an inherent race condition. 有固有的竞争条件。 Copies aren't instant. 副本不是即时的。 Sure, the function checks up front whether it's likely to succeed, but it is possible that the memory range becomes unmapped during the copy. 当然,该函数会预先检查它是否可能成功,但是在复制期间内存范围可能会被取消映射。 It's another running process you're looking at, after all, quite likely unaware ofyour ongoing ReadProcessMemory() . 毕竟,这是你正在看的另一个运行过程,很可能不知道你正在进行的ReadProcessMemory()

(Remus Rusanu also hinted at such a partial copy, but suggested a corrupted process as the root cause, not a race.) (Remus Rusanu也暗示了这样的部分副本,但建议将一个损坏的过程作为根本原因,而不是种族。)

Another possibility, aside from 9000's answer is that the parameter is there for future expansion purposes. 除了9000的答案之外,另一种可能性是该参数可用于将来的扩展目的。 Perhaps at one point (and maybe even now) there were plans to provide ReadProcessMemory implementations that could partially fail so the out parameter was put there for that reason. 也许在某一时刻(甚至可能是现在)有计划提供可能部分失败的ReadProcessMemory实现,因此出于那个原因将out参数放在那里。 This would be a (not particularly good) way to avoid the whole API/APIEx/APIEx2/whatever problem that Win32's APIs have laboured under for years. 这将是一种(不是特别好的)方法来避免整个API / APIEx / APIEx2 / Win32的API多年来一直在努力解决的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM