Czy można uzyskać dostęp do funkcji członka prywatnego przez rzutowanie na typy zgodne z układem?
Z dyskusji na to pytanieW jaki sposób dostęp do zmiennych prywatnych zaimplementowanych w C ++ jest chroniony? Postawiłem wariację: zamiast uzyskiwać dostęp do prywatnego członka danych, czy można wywołać funkcję członka prywatnego przez rzutowanie i polegać na zgodności układu?
Jakiś kod (zainspirowany kolumną Herba Suttera)Zastosowania i nadużycia praw dostępu )
#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;
};
Uwaga: to działa (przynajmniej w Ideone)! Czy jest jakiś nowy sposóbC ++ 11 Standard dajegwarantowane lub przynajmniejzdefiniowane wdrożenie sposób na obejście kontroli dostępu polegający na zgodności układu i reinterpret_cast / static_cast?
EDIT1: wyjście włączoneIdeone
EDIT2: W kolumnie Suttera wymienia dwa powody, dla których powyższy kod nie ma gwarancji, że działa (chociaż działa w praktyce)
a) Układy obiektów X i BaitAndSwitch nie są gwarantowane, ale w praktyce prawdopodobnie zawsze będą takie same.
b) Wyniki reinterpret_cast są niezdefiniowane, chociaż większość kompilatorów pozwoli ci użyć wynikowego odniesienia w sposób zamierzony przez hakera.
Czy nowy C ++ 11 Standard zapewnia teraz gwarancje layout / reinterpret_cast?