Страницы

Поиск по вопросам

воскресенье, 26 января 2020 г.

Управление доступом

#cpp #ооп #классы #инкапсуляция


Как еще можно обойти защищенность полей в ооп? кроме дружественных функций 
    


Ответы

Ответ 1



Если говорить действительно о "взломах защиты", т.е. о способах, которые не требуют кооперации со стороны "взламываемого" класса (т.е. не опираются на изначально заложенные в класс возможности, типа "друзей", методов, возвращающих указатели на члены и т.п.), то одна из малоизвестных "дыр", созданных в языке намеренно - это разрешение для явного инстанциирования шаблона игнорировать ограничения доступа. В следующем примере мы, не используя никаких "хаков", "друзей" или методов самого класса, обходим защиту доступа к private методу #include class Private { void private_func() { std::cout << "Pwned!" << std::endl; } }; using PTR = void (Private::*)(); PTR ptr; template struct Exploit { static inline struct D { D() { ::ptr = ptr; } } d; }; template struct Exploit<&Private::private_func>; int main() { (Private().*ptr)(); } Ключевой момент этой возможности - в разрешении (данном нам разделом 14.7.2/12 стандарта языка) делать template struct Exploit<&Private::private_func>; несмотря на то, что функция Private::private_func является private.

Ответ 2



В общем случае? Или в каких-то конкретных? Читерство типа #define private public считаем недостойным настоящего программиста? :) Копирование описания класса из заголовочного файла с добавлением в него, например, дружественной функции - тоже? Есть вариант с созданием своего класса с аналогичным размещением членов в памяти и reinterpret_cast указателя на один объект в указатель на свой - незаконно, UB, но... обычно вполне прокатывает :) Например, через указатель - если тот же друг создаст указатель на что-то закрытое и вернет его, типа class X { private: int y; friend int* z(X&x) { return &x.y; }; ... int * p = z(x); *p = 5; Или это не годится, хотя дружественная функция используется опосредованно? Вот вариант со специализацией шаблонной функции. Допустим, есть некий класс. class X { public: template void f(const T& t) { /* ... */ } private: int p; }; Специализируем эту функцию... namespace { struct Y{}; } template<> void X::f(const Y&) { p = 5; } и все. Ловкость рук и никакого мошенничества...

Комментариев нет:

Отправить комментарий