最后一个方式 模板尚未弄清楚.

我们在写代码的时候,按约定都是把成员数据放到private访问区中,然后在通过相应的函数来存取。那又有什么样的代码可以突破访问权限来直接操作类中private区段中的成员数据呢?

首先,我们想到了指针,对吧~指针可是万能之王,然而也是万恶之源。那我们就先来看看指针如何突破马其诺防线的。

先定义一个测试类

)
    { }

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

 
利用指针偏移
好了,成功突破!我们再来看看其他的方式。
 
 
 
1.伪造者方式
这个伎俩是现将某个有待伪造的类定义复制一份,然后通过该复制后的“赝品”来达到目的,且看
;
}

)
    {}

template<typename T>
void Func(const T&t)
{}

const int GetValue()
{
return m_nPrivate;
}
};

类定义覆盖(改写类定义)失败
这个伎俩被VC2008的编译器逮住了,没有编译通过。因为他违反了唯一定义规则(ODR,One Definition Rule)。看来语言律师还是不会放过这种没脑子的造假者!打假、打假,越打越假!
 
2. 偷窃者方式
偷偷的改变定义类的含义。且看:
#;
}

他的两根手指头很灵活哟。在VC2008成功执行得到。然而他却有两个违背标准的行为:

1)#define 保留字是非法的

2)违反了唯一定义规则(ODR),然而类的底层内存布局没改变,故可行

用#define private public 偷梁换柱

 

3.骗子方式

// 同X的内存布局,只有一个int型的变量

;
}
在VC2008上成功运行达到目的,但是却有漏洞:
标准中reinterpret_cast的行为未定义,VC2008允许返回的结果引用。所以也成功让骗子得逞。
仿造相同内存结构的新public类,指针类型转换
 
 
4.语言律师方式
律师就是钻法律的漏洞,永远也不会被逮住,他是在钻法律的空子!且看
;
}

void Test()
{
    X x;
    cout << x.GetValue() << endl;

x.Func(Y());
    cout << x.GetValue() << endl;
}

他能成功主要是利用了X具有一个成员模板的事实,代码完全符合标准,标准也确保这种行为会按照编码者的意图行事。boost和loki中大量运用此手法。
模板编译的过程在实际编译以前...活生生的给X类添加了一个成员函数.
原来,类里面有一个实现了的模板函数!
那么在外面再加一个模板函数,导致模板推演的过程中多出来一个自己写的并且加入了备选组中,所以相当于多了一个重载。
 
并且由于此函数的参数是匿名空间里面的特定的类别,完全避免了搅乱原本该函数的功能。
高招啊!
 
看法:
我相信这并不是C++访问控制机制的漏洞,或许,我们本不应该这样做。用成员模板提供一种有效的访问似有成员数据可以绕过类的访问控制,这也许就是我们想达到的目的。

[转载] C++ 突破私有成员访问限制的更多相关文章

  1. C++利用指针突破私有成员访问限制

    C++ 面向对象的一大特性就是封装,使用不同的访问控制符来控制外接对其的访问权限.比如: 1 class A 2 { 3 public: 4 A(): i(10){} 5 void print(){ ...

  2. 使用C#反射机制访问类的私有成员【转】

    首先我必须承认访问一个类的私有成员不是什么好做法.大家也都知道私有成员在外部是不能被访问的.而一个类中会存在很多私有成员:如私有字段.私有属性.私有方法.对于私有成员访问,可以套用下面这种非常好的方式 ...

  3. C#中访问私有成员--反射

    首先我必须承认访问一个类的私有成员不是什么好做法.大家也都知道私有成员在外部是不能被访问的.而一个类中会存在很多私有成员:如私有字段.私有属性.私有方法.对于私有成员访问,可以套用下面这种非常好的方式 ...

  4. C++ //继承中的对象模型 //利用开发人员命令提示工具查看对象模型 //父类中所有非静态成员属性都会被 子类继承下去 //父类中私有成员属性 是被编译器给隐藏了 因此是访问不到 但是确实被继承下去了

    1 //继承方式 2 //语法:class 子类 :继承方式 父类 3 //继承方式 三种: 4 //1.公共继承 5 //2.保护继承 6 //3.私有继承 7 8 /* 9 #include &l ...

  5. python 私有和保护成员变量如何实现?—— "单下划线 " 开始的成员变量叫做保护变量,意思是只有类实例和子类实例能访问到这些变量;" 双下划线 " 开始的是私有成员,意思是只有类对象自己能访问,连子类对象也不能访问到这个数据

    默认情况下,Python中的成员函数和成员变量都是公开的(public),在python中没有类似public,private等关键词来修饰成员函数和成员变量.在python中定义私有变量只需要在变量 ...

  6. Delphi 跨单元进入(访问)类的私有成员,protected ,private部分

    http://blog.sina.com.cn/s/blog_5f8861b60102v1nl.html Delphi 跨单元进入(访问)类的私有成员,protected ,private部分 (20 ...

  7. VC6.0中友元函数无法访问类私有成员的解决办法

    举个例子: 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 #inclu ...

  8. VC6.0中重载操作符函数无法访问类的私有成员

    整理日: 2015年03月18日 在 C++ 中,操作符(运算符)可以被重载以改写其实际操作.同时我们可以定义一个函数为类的朋友函数(friend function)以便使得这个函数能够访问类的私有成 ...

  9. C#中访问私有成员

    首先访问一个类的私有成员不是什么好做法.大家都知道私有成员在外部是不能被访问的.一个类中会存在很多私有成员:如私有字段.私有属性.私有方法.对于私有成员造访,可以套用下面这种非常好的方式去解决. pr ...

随机推荐

  1. C#如何把List of Object转换成List of T具体类型

    上周码程序的时候碰到个问题,因为设计上的约束,一个方法接受的参数只能为List<object>类型,然而该方法需要处理的真实数据则是确定的List<Currency>.然而C# ...

  2. Request.GetOwinContext()打不到

    Although it's in the Microsoft.Owin.Host.SystemWeb assembly it is an extension method in the System. ...

  3. webform中使用webapi,并且使用autofac

    private void AutofacIoCRegister() { HttpConfiguration config = GlobalConfiguration.Configuration; if ...

  4. 轻取帝国CMS管理员密码

    “帝国”CMS是一套著名的PHP整站程序,是国内使用人数最多的PHPCMS程序之一.令人无奈的是,“帝国”虽然把势力壮大了,却忽略了自身防护的建设,结果在黑客攻击下,“帝国”沦陷了.“帝国”CMS曝出 ...

  5. Linux静态库生成指南

    Linux静态库生成指南   Linux上的静态库,其实是目标文件的归档文件.在Linux上创建静态库的步骤如下: 写源文件,通过 gcc -c xxx.c 生成目标文件. 用 ar 归档目标文件,生 ...

  6. jQuery.extend和jQuery.fn.extend的区别?

    jquery 本身 是由 Resig: 莱希格, 一个美国的小伙子小伙伴开发的, 在2005年 prototype发表之后, 在2006年1月发表的, 后来进入mozilla工作, mozilla的j ...

  7. [译]git status

    git status git status命令能展示工作目录和stage区的状态. 使用他你能看到那些修改被staged到了, 哪些没有, 哪些文件没有被Git tracked到. git statu ...

  8. 【转载】Unity 优雅地管理资源,减少占用内存,优化游戏

    转自:星辰的<Unity3D占用内存太大的解决方法> 最近网友通过网站搜索Unity3D在手机及其他平台下占用内存太大. 这里写下关于Unity3D对于内存的管理与优化. Unity3D  ...

  9. gdb调试core文件

    本人最近正在学习调试技术,此处对栈溢出做一些总结. gdb的基本使用就不多扯了. 主要针对发行在外的release版本的软件出现问题时的调试. 一般来讲,查看堆栈就是使用bt,这个时候加上bt ful ...

  10. R语言 奇怪的NA

    > 1+NA [1] NA > NA==1 [1] NA > c(NA,1:50) [1] NA 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ...