高人看看属于C++漏洞否(很有意思)

xxyakoo 2008-11-20 03:19:57

class A
{
virtual void fun(){printf("this is a's private fun\n");}
};

class B
{
public:
virtual void fun(){printf("this is b's public fun\n");}
};

int _tmain(int argc, _TCHAR* argv[])
{
A* pa = new A;
B* pb=(B*)pa;
pb->fun();
return 0;
}

新一篇: 标准c字符和字符串操作 atof() 函数 | 旧一篇: vprintf, vfprintf和 vsprintf 函数
...全文
452 41 打赏 收藏 转发到动态 举报
写回复
用AI写文章
41 条回复
切换为时间正序
请发表友善的回复…
发表回复
dnhan 2008-11-21
  • 打赏
  • 举报
回复
很厉害的代码,受教了!

[Quote=引用 27 楼 Demon__Hunter 的回复:]
首先c++访问控制只是代码级别的,二进制层面c++没有也很难实现访问控制的。
由于有虚函数所以A* pa = new A; pa指向的是A对象的起始地址,一般也是其虚表指针的地址。
而B的对象的首地址同样是虚表指针的地址,所以 B* pb=(B*)pa; 强制转换时A对象起始部分恰好符合B对象的起始部分,而pb->fun();虚表+函数索引偏移 使用的这部分数据 正好是虚表指针的数据,所以程序能够运行。虚函数的调用时,由于是虚表中索引,由于是父类的虚…
[/Quote]

同意!
ForestDB 2008-11-21
  • 打赏
  • 举报
回复
窃以为是C灵活的表现(C++到底还是处于C的啊)。
lostbyte2006 2008-11-21
  • 打赏
  • 举报
回复
Mark!学习了。
帅得不敢出门 2008-11-21
  • 打赏
  • 举报
回复
还是vptr搞的鬼
wanglikun 2008-11-21
  • 打赏
  • 举报
回复
[Quote=引用 27 楼 Demon__Hunter 的回复:]
首先c++访问控制只是代码级别的,二进制层面c++没有也很难实现访问控制的。
由于有虚函数所以A* pa = new A; pa指向的是A对象的起始地址,一般也是其虚表指针的地址。
而B的对象的首地址同样是虚表指针的地址,所以 B* pb=(B*)pa; 强制转换时A对象起始部分恰好符合B对象的起始部分,而pb->fun();虚表+函数索引偏移 使用的这部分数据 正好是虚表指针的数据,所以程序能够运行。虚函数的调用时,由于是虚表中索引,由于是父类…
[/Quote]
还是他说的实质,把问题说的实质一点,大家共同学习,挺好的
qingkongyihe2008 2008-11-21
  • 打赏
  • 举报
回复
强制转换很危险的
qingkongyihe2008 2008-11-21
  • 打赏
  • 举报
回复
强制转换很危险的
xianyuxiaoqiang 2008-11-21
  • 打赏
  • 举报
回复
很恶毒的代码。
mujiok2003 2008-11-21
  • 打赏
  • 举报
回复
访问权限控制只能在编译时启作用,而访问权限又是实现信息隐藏的手段.你故意作强制类型转换,既是故意避开访问权限,破坏对象的信息隐藏,责任在于编程者,而不是语言本身.


以下代码一样能做相同的事情:
typedef void (*pf)(void);
pf p= NULL;
p = (pf)*((int*)*((int*)pa+0)+0);
p();



eatsweetpotato 2008-11-21
  • 打赏
  • 举报
回复
mark
liumingrong 2008-11-21
  • 打赏
  • 举报
回复
如果lz对这种东西感兴趣的话,那推荐看《深度探索c++对象模型》,
看完之后,这些东西你会非常清楚,并且明白不应该这样绕过编译器,
当然作为例子了解对象模型是可以的

[Quote=引用楼主 xxyakoo 的帖子:]

class A
{
virtual void fun(){printf("this is a's private fun\n");}
};

class B
{
public:
virtual void fun(){printf("this is b's public fun\n");}
};

int _tmain(int argc, _TCHAR* argv[])
{
A* pa = new A;
B* pb=(B*)pa;
pb->fun();
return 0;
}

新一篇: 标准c字符和字符串操作 atof() 函数 | 旧一篇: vprintf, vfprintf和 vsprintf 函数
[/Quote]
CPlusPlusFans 2008-11-21
  • 打赏
  • 举报
回复
这不是漏洞,强烈建议楼主参考一下COM相关的知识,
里面详细的讲述了C++多态技术的实现方法
实际上所有的虚函数地址存在一个vtab表中,
你的例子仅仅是两个函数占用了相同的位置。
你可以修改其中一个函数的名字,还是可以执行的。
但不推荐这样使用,不同的编译器,不同的平台,可能有不同的问题。
endlessdream 2008-11-21
  • 打赏
  • 举报
回复
这不是漏洞。
你在强制类型转换的时候就相当于向编译器保证“我知道我在做些什么,我能承担我这样做的后果。所以不要管我。”

但这个思路的意思,可以学习一下
a7785577 2008-11-21
  • 打赏
  • 举报
回复
嗯嗯··同意楼上的
机智的呆呆 2008-11-20
  • 打赏
  • 举报
回复
首先c++访问控制只是代码级别的,二进制层面c++没有也很难实现访问控制的。
由于有虚函数所以A* pa = new A; pa指向的是A对象的起始地址,一般也是其虚表指针的地址。
而B的对象的首地址同样是虚表指针的地址,所以 B* pb=(B*)pa; 强制转换时A对象起始部分恰好符合B对象的起始部分,而pb->fun();虚表+函数索引偏移 使用的这部分数据 正好是虚表指针的数据,所以程序能够运行。虚函数的调用时,由于是虚表中索引,由于是父类的虚表,所以调用的是父类的函数。
wzfxyer 2008-11-20
  • 打赏
  • 举报
回复
感觉没什么,
hznat 2008-11-20
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 Mougou 的回复:]
恭喜楼主,用这种方法实际上实现了简单的反射功能,B就是A的一个反射类。
小弟不才,这几天正在研究C++的反射,你给我提供了一个新的思路。
[/Quote]

学习
Donald_Duck 2008-11-20
  • 打赏
  • 举报
回复
up
daozi1 2008-11-20
  • 打赏
  • 举报
回复
这正是C类型强制转换的一个弊端,没有类型检测
倘若用C++的强制类型转换,这是不会得逞的
Qlaiaqu 2008-11-20
  • 打赏
  • 举报
回复
组件对象模型(com)中,对于组件复用的聚合方法采用的就是依赖这种强转,这没什么稀奇的。人家都玩了十几年了,是你才知道。
加载更多回复(21)

65,211

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧