美文网首页
C++虚表引出的问题。黑客指日可待。

C++虚表引出的问题。黑客指日可待。

作者: 晴空一垩 | 来源:发表于2019-08-07 18:33 被阅读0次

    笔者环境:

    $ gcc --version
    gcc (Debian 6.3.0-18+deb9u1) 6.3.0 20170516
    $ uname -a
    Linux debian9-64-Desktop 4.9.0-8-amd64 #1 SMP Debian 4.9.110-3+deb9u6 (2018-10-08) x86_64 GNU/Linux
    

    虚表:

    #include<iostream>
    
    typedef void (*fun)(void) ;
    
     class A{
         private:
         virtual void printA(){
             std::cout<<"hello A"<<std::endl;
         }
         virtual void printB(){
             std::cout<<"hello B"<<std::endl;
         }
         void printC(){
             std::cout<<"hello C"<<std::endl;
         }
     };
    
    int main(int argc,char * argv[]){
        A a;
        long* pa =(long*)&a;
        long* ppa = (long*)(*pa);
        void (*funA)(void) =(void (*)(void))(*ppa);
        funA();
        fun funB =(fun)(*(++ppa));
        funB();
        return 0;
    }
    

    问题一:

    请问上例中的,sizeof(A) 有多少个字节?

    在64位机,是8个字节

    在32位机,是4个字节,

    问题二:

    请问上例中,为什么要使用 long * 呢?

    因为笔者的环境是64位机,void* 是占用8个字节的。所以这里使用long 方便我调用下一个虚方法,只需要通过 long* +1 即可

    问题三:

    请问上例中,为啥会取了那么多次的指针,分别是干什么的。

    long* pa =(long*)&a; 表示取得类的地址

    long* ppa = (long*)(*pa); 表示取得虚表的地址

    void (*funA)(void) =(void (*)(void))(*ppa); 表示取得在虚表中首个虚函数的地址

    ++ppa 表示地址往后偏移8个字节,就是第二个虚函数的地址

    问题四:

    请问上例中,如果编译出可执行文件,可以看得到 printC 的函数符号吗?为什么?

    让我们执行编译然后验证一下:

    $ g++ -I. main.cpp
    
    $ objdump -Tt a.out  |grep print
    0000000000000b0a  w    F .text 0000000000000037              _ZN1A6printBEv
    0000000000000ad2  w    F .text 0000000000000037              _ZN1A6printAEv
    

    经过 粉碎命名 ,但是也依旧可以看到是没有 printC 的签名的。

    那我们换种方式

    $ strings a.out |grep print
    vfwprintf
    printB
    vwprintf
    vswprintf
    printA
    _ZN1A6printAEv
    printC
    _ZN1A6printBEv
    _ZN1A6printCEv
    _ZN1A6printBEv
    _ZN1A6printAEv
    

    可以看到也是有的,证明这个符号在,并且存在在代码区。

    问题五:

    请问上例中,如果我要按照你这样调用 printC 可不可以呢?

    经过一通询问,与查找,发现,可以使用这里的文章所列举的方法进行调用

    参考

    虚表(C++)virtual table

    C++访问类中私有成员变量的方法

    C++获取private的变量-偷走private

    相关文章

      网友评论

          本文标题:C++虚表引出的问题。黑客指日可待。

          本文链接:https://www.haomeiwen.com/subject/jtkodctx.html