gpt4 book ai didi

c++ - 可以通过强制转换为布局兼容类型来访问私有(private)成员函数吗?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:41:32 24 4
gpt4 key购买 nike

来自对这个问题的讨论How is access for private variables implemented in C++ under the hood?我提出了一个变体:不是访问私有(private)数据成员,而是可以通过强制转换和依赖布局兼容性来调用私有(private)成员函数吗?

一些代码(灵感来自 Herb Sutter 的专栏 Uses and Abuses of Access Rights )

#include <iostream>

class X
{
public:
X() : private_(1) { /*...*/ }

private:
int Value() { return private_; }
int private_;
};

// Nasty attempt to simulate the object layout
// (cross your fingers and toes).
//
class BaitAndSwitch
// hopefully has the same data layout as X
{ // so we can pass him off as one
public:
int Value() { return private_; }
private:
int private_;
};

int f( X& x )
{
// evil laughter here
return (reinterpret_cast<BaitAndSwitch&>(x)).Value();
}

int main()
{
X x;
std::cout << f(x) << "\n"; // prints 0, not 1
return 0;
};

注意:这有效(至少在 Ideone 上)!有什么办法新的C++11 Standard提供一种保证或至少一种实现定义的方式来依靠布局兼容性和reinterpret_cast/static_cast来规避访问控制?

EDIT1:在 Ideone 上输出

EDIT2:在 Sutter 的专栏中,他列出了上述代码不能保证有效(尽管在实践中有效)的两个原因

a) The object layouts of X and BaitAndSwitch are not guaranteed to be the same, although in practice they probably always will be.

b) The results of the reinterpret_cast are undefined, although most compilers will let you try to use the resulting reference in the way the hacker intended.

新的 C++11 标准现在是否提供这些布局/reinterpret_cast 保证?

最佳答案

是的,您可以创建一个类型,它使用与您试图窃取的类型相同的布局,然后 reinterpret_cast从该类型到您的布局兼容类型。但只有当源类型和目标类型都是标准布局类型时,这才受标准保护(当然,只有它们的布局相同时才有效)。所以如果源代码有虚函数,你就完蛋了。

这似乎满足了 Sutter 的两个问题。标准布局规则确保以相同顺序定义相同成员的两种标准布局类型是布局兼容的(第 9.2 节,第 17 段):

Two standard-layout struct (Clause 9) types are layout-compatible if they have the same number of non-static data members and corresponding non-static data members (in declaration order) have layout-compatible types (3.9).

以及 reinterpret_cast 的规则指定两种标准布局类型之间转换的含义(第 5.2.10 节,第 7 段):

An object pointer can be explicitly converted to an object pointer of a different type. When a prvalue v of type “pointer to T1” is converted to the type “pointer to cv T2”, the result is static_cast<cv T2*>(static_cast<cv void*>(v)) if both T1 and T2 are standard-layout types (3.9) and the alignment requirements of T2 are no stricter than those of T1, or if either type is void.

关于c++ - 可以通过强制转换为布局兼容类型来访问私有(private)成员函数吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11494403/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com