一直听说 C++ 继承体系中对虚函数调用的动态绑定是基于虚函数表和虚表指针的,但是因为一些原因,我一直没有去搞清楚。今天想起这件事情,就去翻看了 C++ 的标准文档。然而,标准文档只提及了动态绑定的各种规则,却并没有提及任何有关虚函数表或虚表指针的内容。显然,我看的不会是假的标准文档,那么只可能是动态绑定是由编译器实现决定的了。
intmain(){ Derived d; auto f = fuckcxx(&d, 0); auto g = fuckcxx(&d, 1); // 2. f(); g(); return0; }
编译并执行。
1 2 3 4 5 6 7 8 9 10
$ g++-6 --version g++-6 (Homebrew GCC 6.4.0_1) 6.4.0 Copyright (C) 2017 Free Software Foundation, Inc. This is free software; see the sourcefor copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ g++-6 crack_private.cc $ ./a.out Your are calling Base::f (public). Your are calling Base::g (private).
无疑,我们已经成功地访问了 Base 类的私有函数 g。现在我们来看看是怎样做到的。
主函数很简单,无非是取了一个 Derived 类型的变量 d。而后借助它,用 fuckcxx 函数通过偏移量,去获得 Base 的函数指针。最后实现函数调用。这里可以作出几个推断。