MCCP 缓冲区保护

从 Windows Vista 开始,RPC 封送处理引擎会采取进一步步骤来尝试防止客户端缓冲区因返回的数据而溢出。 此设施称为微型计算一致性保护 (MCCP) 。

当客户端将指向现有缓冲区的指针传递给 [out] 或 [inout] 参数时,该参数的返回数据将复制到现有缓冲区中。 如果返回的数据大于传递的缓冲区,则 RPC 将返回的数据复制到太小的缓冲区时,可能会发生缓冲区溢出。 请参阅 顶级指针和嵌入指针

使用 MCCP 时,RPC 会尝试检测此情况,并在检测到该调用时拒绝该调用。 对于具有相关值的缓冲区(如 [size_is]),如果返回的数据不适合指定的缓冲区大小,则会拒绝调用并引发RPC_X_BAD_STUB_DATA异常。 对于未大小的字符串,如果现有字符串大小 (长度,直到 null 终止符) 不足以保存返回的字符串,则拒绝调用。 RPC 无法检测所有情况下的缓冲区溢出,因此建议开发人员继续对缓冲区溢出采取正常预防措施。

如果客户端不为 [out] 参数传递现有缓冲区,而是将取消引用指针传递到 NULL,则 RPC 将遵循常规规则来代表客户端分配新缓冲区。 此缓冲区将分配足够的空间来保存返回的数据。

第二种保护是,对于相关参数,RPC 将强制在相关计数变量为非 null 时传递非 null 缓冲区。

HRESULT PassString( [in] DWORD Length, [in, unique, string, size_is( Length )]LPWSTR MyString );

如果 MyStringNULL,RPC 将拒绝调用,除非 Length 设置为 0。 请注意,当 MyString 为非 NULL 时,RPC 将允许 Length 为 0,RPC 会将 MyString 视为 0 长度缓冲区分配。