Say I am using an open source library of someone who does not know what they're doing well. (no encapsulation for important members) Really it's a coworker who's code I'm not allowed to modify, nor is he willing to modify it for me.
How can I forcefully access a private member without doing something like rewriting a fake class or modifying the original class?
I've tried things like #define private public
, but the class file includes some standard namespace files and this will give a compilation error.
I've tried memory manipulation, but this requires member identification which isn't going to work. (See the following)
#define PX_ACCESS_PRIVATE( pObject, _Member ) ( static_cast< std::size_t >( pObject ) + static_cast< std::size_t >( &( ( decltype( pObject )( nullptr ) )->_Member ) ) )
Any ideas?
Oh, you can break encapsulation gloriously. The type system has a loophole that can be leveraged to that effect. Explicit instantiations of templates don't do access checks on their arguments. You can pass anything there. So with a bit of plumbing...
template<typename Tag>
struct contraband_ {
using type = typename Tag::type;
inline static type ptr;
};
template<typename Tag>
inline auto const contraband = contraband_<Tag>::ptr;
template<typename Tag, typename Tag::type ptr_>
class steal : contraband_<Tag> {
static inline const char filler = [] {
steal::contraband_::ptr = ptr_;
return '\0';
}();
};
... you can have yourself indirect access to any private member via a pointer to it...
class foo {
int x = 3;
};
struct x_tag { using type = int foo::*; };
template class steal<x_tag, &foo::x>;
int main()
{
foo f;
// return f.x; ill-formed! Private!
return f.*contraband<x_tag>; // Okay!
}
See it live.
A fun exercise, but you really should work things out with your colleague instead of resorting to this. Use at your own peril.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With