随笔 - 8  文章 - 26  trackbacks - 0
<2008年11月>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456

常用链接

留言簿(4)

随笔档案

文章分类

文章档案

相册

C++语言

搜索

  •  

最新评论

阅读排行榜

评论排行榜

 

今天在网上看了一篇关于C++虚函数表的文章,让我对C++又有了更深了的理解,文章链接:http://www.51cto.com/art/200712/62673_2.htm

在这篇文章中讲到了通过虚函数表访问私有的虚函数的问题,问题就出在C++在虚函数表中保存了虚函数的地址,而这个地址又很方便查找。
在每个C++对象实例的开头存储这这个对象的虚函数表的指针,通过这个指针可找到虚函数表,在虚函数表中就存着虚函数指针,这样我们就可以骗过编译器访问私有的虚函数了。

 1class base
 2{
 3private:
 4    virtual    void f(){cout<<"base_f()"<<endl;}
 5}
;
 6class child:public base
 7{
 8private:
 9    virtual void f(){cout<<"child_f()"<<endl;};
10    void g(){cout<<"base_g()"<<endl;}
11    
12}
;
13void main()
14{
15    typedef void(*Fun)(void);
16    child b;
17    Fun pFun;
18    pFun = (Fun)*((int*)*(int*)(&b));
19    pFun();
20}

输出结果:child_f();

这样就访问了私有的虚函数了。

但是这样只能访问私有的虚函数,那怎么才能访问任意的私有函数呢,像child类的g()函数,还请高人指点。
posted on 2008-11-03 20:43 杨彬彬 阅读(2786) 评论(10)  编辑 收藏 引用

FeedBack:
# re: 通过虚函数表访问私有虚函数 2008-11-03 22:50 giscn
私有函数本来就是防止别人访问的。最简单的办法是将类定义中的 private 改成 public  回复  更多评论
  
# re: 通过虚函数表访问私有虚函数 2008-11-03 23:08 lonkil
这种将地址转成函数指针的方法,好像只能访问第一个吧?如果有两个虚拟函数,就不好访问了吧?

其实这个实验只能让你更清楚,虚函数表的物理位置,没有什么实际意义,个人愚见,哈哈。

  回复  更多评论
  
# re: 通过虚函数表访问私有虚函数 2008-11-04 12:23 abc
函数带参数的怎么访问?  回复  更多评论
  
# re: 通过虚函数表访问私有虚函数 2008-11-04 15:15 zuhd
看了那篇文章,好像只要是虚函数,就可以通过虚表的指针获得,至于每个函数在虚表中的偏移量,我也没有理解  回复  更多评论
  
# re: 通过虚函数表访问私有虚函数 2008-11-04 15:31 zuhd
http://blog.csdn.net/haoel/archive/2007/12/18/1948051.aspx
这是原文地址,看了就明白了,写得很赞  回复  更多评论
  
# re: 通过虚函数表访问私有虚函数 2008-11-04 19:08 空明流转
私有函数仅仅在编译期间起作用。  回复  更多评论
  
# re: 通过虚函数表访问私有虚函数 2008-11-12 20:28 imdavid
child cc;

int *p = (int *)&cc + 1;

__asm
{
call p ;// call the point to the address
}

如果类有构造函数, 不加1直接取到其地址并调用.

# re: 通过虚函数表访问私有虚函数 2008-11-04 19:08 空明流转
私有函数仅仅在编译期间起作用。

这个是对, 但是想要弄明白一个类的内存分配。可能还需要找点资料. 另外函数的前后分布也有关系。


13void main()
14{
15 typedef void(*Fun)(void); // 这个局限性比较大
16 child b;
17 Fun pFun;
18 pFun = (Fun)*((int*)*(int*)(&b));
19 pFun();
20}


写个类的内存分布扫描器还是有必要的. :)

  回复  更多评论
  
# re: 通过虚函数表访问私有虚函数 2008-11-13 19:01 杨彬彬
@imdavid
“int *p = (int *)&cc + 1; ”小弟不才,对于这还是不明白,那p所指向的究竟是什么?是虚函数的指针,但虚函数指针不是在虚函数表里吗。。真晕啊。
有没有好的资料能看看
  回复  更多评论
  
# re: 通过虚函数表访问私有虚函数 2008-11-13 19:30 imdavid
呵呵, 以为没有人关注了呢, +1 是class里面的成员顺序也就是虚函数指针. 别问我+2为什么不对 :)

但虚函数指针不是在虚函数表里吗.

个人认为:在编译时确实存在VTable. 但是在运行时里"感觉"就不分VT了。而是直接指向类首地址,在进行地址加减就可以得到.

你们自定义函数指针是可以,但局限性太大太大.

另外说明:这东西没有资料可寻。 有问题一起msn聊聊. imdavid2msn@msn.com  回复  更多评论
  
# re: 通过虚函数表访问私有虚函数 2008-11-13 19:32 imdavid
个人认为:在编译时确实存在VTable. 但是在运行时里"感觉"就不分VT了。而是直接指向类首地址,在进行地址加减就可以得到.

关于这句话有所保留。 不过因为是先指向class首地址 然后在进行查找。所以可行。

另外也用过struct的一些方法。 例如: ((类指针*)0)->xxx 但编译有问题。 还在琢磨。
  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理