C++虚函数系列之二:绕过class的访问机制访问虚函数

来源:互联网 发布:js弹出输入框 并取值 编辑:程序博客网 时间:2024/06/05 17:51

AuthorJeff   2005-12-2

关键字:C++ 虚函数 访问机制

环境:Window XP Professional + SP2, VC6.0

 

上一篇文章中,在统计虚函数的个数时,依靠的就是其地址。虚函数的地址都有了,如果不调用一下,太对不起人了。*_*! 但令人沮丧的是,C++中对类的成员变量及成员函数有严格的访问权限,你光明正大地调用C++private虚函数,在编译期就通不过,即使你知道其地址又有什么用~~~

 

看看下面这个简单的代码:

#include <stdio.h>

void outp(void) {

    printf("function Outp()/n");

}

 

int  main(void)

{

void   (*k)(void) = outp;

int    *s = (int *)outp;

 

k();   // correct

// s();   incorrect

 

 return 0;

}

对于s来说,其实它已经取得了函数Outp()的入口地址,但是就是不能像这样调用:s()。因为s所拥有的信息不允许这样匹配,在语法分析阶段就夭折了。要躲过C++编译器语法分析和语义分析阶段的盘查,只得用比较原始的方法,汇编调用:

_asm {

         call [s]

};

呵呵,效果等同于k()

 

classprivate虚函数,也可以用汇编代码来调用,巧妙地绕过class的访问权限(其实是绕过C++编译器语法分析和语义分析阶段)。

借助上一篇章的代码,在main()函数加入下面的代码:

int    *p  = (int *)&c1;

int    *q, *r;

 

q = (int *)*((int *)(*p) + 1);

r = (int *)*((int *)(*p) + 2);      

        _asm {

              call [q]     ; // complement second virtual function

        };

        _asm{

              push 23

          call [r]     ; // complement third virtual function

};

程序忠实地执行了C001::Display()C001::Outp(),再现了private虚函数运行后的结果。

遗憾的是,对于带参数的虚函数,在使用汇编代码调用时,需要知道参数的个数、大小和类型,和普通方式调用差不多。在没有源代码的情况下,很难调用成功。

原创粉丝点击