C++ 突破私有成员访问限制
2017-09-29 17:16
197 查看
C++ 突破私有成员访问限制
我们在写代码的时候,按约定都是把成员数据放到private访问区中,然后在通过相应的函数来存取。那又有什么样的代码可以突破访问权限来直接操作类中private区段中的成员数据呢?
首先,我们想到了指针,对吧~指针可是万能之王,然而也是万恶之源。那我们就先来看看指针如何突破马其诺防线的。
先定义一个测试类
class X { private: int m_nPrivate; public: X() : m_nPrivate(1) { } template<typename T> void Func(const T&t)// 类中存在一个模板函数 { } const int GetValue() { return m_nPrivate; } };
很简单是吧,私有成员m_nPrivate就是我们的目标。
利用指针偏移
来看看突破代码:void *p = &x;// 获取类的起始地址,其实也就是m_nPrivate数据成员的地址 int *n = (int *)p; int tmp = 2; *n = tmp; // 改写其值 cout << x.GetValue() << endl; // 输出为2
伪造者方式:
类定义覆盖(改写类定义)这个伎俩是现将某个有待伪造的类定义复制一份,然后通过该复制后的“赝品”来达到目的,且看
void Hijack(X &x) { x.m_nPrivate = 2; } class X { // 手工添加 friend ::Hijack(X &); // 这里是复制X类定义 private: int m_nPrivate; public: X() : m_nPrivate(1) {} template<typename T> void Func(const T&t) {} const int GetValue() { return m_nPrivate; } };
这个伎俩被
VC2008的编译器逮住了,没有编译通过。因为他违反了唯一定义规则(ODR,One
Definition Rule)。看来语言律师还是不会放过这种没脑子的造假者!打假、打假,越打越假!
偷窃者方式:
用#define private public偷梁换柱
偷偷的改变定义类的含义。且看:
#define private public// 万恶的宏伎俩啊 void Hijack(X &x) { x.m_nPrivate = 2; }
他的两根手指头很灵活哟。在
VC2008成功执行得到。然而他却有两个违背标准的行为:
1)
#define保留字是非法的
2)违反了唯一定义规则(ODR),然而类的底层内存布局没改变,故可行
骗子方式:
仿造相同内存结构的新public类,指针类型转换// 同X的内存布局,只有一个int型的变量 class BaitSwitch { public: int m_nNotPrivate; }; void Func(X &x) { (reinterpret_cast(x)).m_nNotPrivate=2; }
在VC2008上成功运行达到目的,但是却有漏洞:
标准中reinterpret_cast的行为未定义,VC2008允许返回的结果引用。所以也成功让骗子得逞。
语言律师方式
律师就是钻法律的漏洞,永远也不会被逮住,他是在钻法律的空子!且看namespace { struct Y{}; } template<> void X::Func(const Y&) { m_nPrivate = 2; } void Test() { X x; cout << x.GetValue() << endl; x.Func(Y()); cout << x.GetValue() << endl; }
他能成功主要是利用了
X具有一个成员模板的事实,代码完全符合标准,标准也确保这种行为会按照编码者的意图行事。
boost和
loki中大量运用此手法。
模板编译的过程在实际编译以前...活生生的给
X类添加了一个成员函数.
原来,类里面有一个实现了的模板函数!
那么在外面再加一个模板函数,导致模板推演的过程中多出来一个自己写的并且加入了备选组中,所以相当于多了一个重载。
并且由于此函数的参数是匿名空间里面的特定的类别,完全避免了搅乱原本该函数的功能。
高招啊!
看法:
我相信这并不是C++访问控制机制的漏洞,或许,我们本不应该这样做。用成员模板提供一种有效的访问似有成员数据可以绕过类的访问控制,这也许就是我们想达到的目的
相关文章推荐
- C++利用指针突破私有成员访问限制
- C++ 突破私有成员访问限制
- C++ 如何突破private成员的访问限制
- C++友元函数访问私有成员
- C++中类的访问权限针对的是类而不是对象!(为什么类中的函数可以访问对象的私有成员?)
- C++对象中的私有成员变量可以被访问
- 友元函数、友元类、访问私有数据成员、友元关系[C++]
- C++私有成员访问
- 【C++】私有数据成员不能用对象去访问吗
- c++中类对象不能访问类的私有成员变量
- C++ 公有继承、保护继承和私有继承中类成员的访问权限的控制
- C++ 为什么类的构造函数可以访问类的私有成员?解惑
- C++中巧用#define访问类的私有成员
- C++中内部类访问外部类的私有成员
- C++中巧用#define访问类的私有成员
- C++私有成员和受保护成员的访问权…
- C++ 公有继承、保护继承和私有继承中类成员的访问权限的控制
- C++在类的成员函数中,允许直接访问该类的成员对象的私有成员变量
- C/C++—— 除了用类成员函数访问类私有成员变量外,还可以通过类对象地址来直接访问和修改类的私有成员变量
- c++中可不可以在一个类中访问另一个类的私有成员?