- C和C++安全編碼(原書第2版)
- (美)Robert C.Seacord
- 617字
- 2020-10-30 17:56:50
3.7 虛指針
在C++中可以定義虛函數(virtual function)。虛函數就是用virtual關鍵字聲明的類成員函數。該函數可以由派生類中的同名函數重寫。一個指向派生類對象的指針可以被賦給基類指針,并且通過該指針來調用函數。如果沒有虛函數,則調用的是基類的函數,因為它和指針的靜態類型相關聯。當使用虛函數時,調用的則是派生類的函數,因為該函數和對象的動態類型相關聯。
例3.10描述了虛函數的語義。類a是一個基類,它包含一個常規函數f()和一個虛函數g()。
類b派生自a,分別重寫了這兩個函數。在main()中,聲明了一個指向基類的指針my_b,但它被賦值為指向一個派生類b對象。當在第25行中調用非虛函數my_b-﹥f()時,與a(基類)相關聯的函數f()被調用。而當在第26行中調用虛函數my_b-﹥g()時,與b(派生類)相關聯的函數g()被調用。
例3.10 虛函數的語義
01 class a { 02 public: 03 void f(void) { 04 cout << "base f" << '\n'; 05 }; 06 07 virtual void g(void) { 08 cout << "base g" << '\n'; 09 }; 10 }; 11 12 class b: public a { 13 public: 14 void f(void) { 15 cout << "derived f" << '\n'; 16 }; 17 18 void g(void) { 19 cout << "derived g" << '\n'; 20 }; 21 }; 22 23 int main(void) { 24 a *my_b = new b(); 25 my_b->f(); 26 my_b->g(); 27 return 0; 28 }
大多數C++編譯器使用虛函數表(Virual Function Table,VTBL)實現虛函數。VTBL是一個函數指針數組,用于在運行時派發虛函數調用。在每一個對象的頭部,都包含一個指向VTBL的虛指針(Virtual Pointer,VPTR)。VTBL含有指向虛函數的每一個實現的指針。圖3.2展示了例3.10中的數據結構。
圖3.2 VTBL的運行時表示
覆寫VTBL中的函數指針或者改變VPTR使其指向其他任意的VTBL都是可能的,可以通過任意內存寫或者利用緩沖區溢出直接寫入對象實現這一操作。通過對對象的VTBL和VPTR的覆寫,攻擊者可以使函數指針執行任意的代碼。VPTR粉碎(VPTR smashing)攻擊尚未泛濫,但在其他攻擊手段都失效的情況下它就可能會被采用[Pincus 2004]。
推薦閱讀
- 精通JavaScript+jQuery:100%動態網頁設計密碼
- MATLAB圖像處理超級學習手冊
- 程序員面試算法寶典
- JavaScript從入門到精通(第3版)
- Visual Basic程序設計習題解答與上機指導
- Securing WebLogic Server 12c
- 單片機應用與調試項目教程(C語言版)
- Getting Started with NativeScript
- Hands-On Reinforcement Learning with Python
- Java EE核心技術與應用
- Ext JS 4 Plugin and Extension Development
- H5匠人手冊:霸屏H5實戰解密
- Learning Zimbra Server Essentials
- Unity與C++網絡游戲開發實戰:基于VR、AI與分布式架構
- 零基礎入門Python數據分析與機器學習