12.IDA-虚函数和虚表(vf代表虚函数,vf3代表this指向第三个函数)
vtable
編譯器會(huì)為每一個(gè)包含虛函數(shù)的類(或通過(guò)繼承得到的子類)生成一個(gè)表,其中包含指向類中每一個(gè)虛函數(shù)的指針,這樣的表就叫做虛表(vtable)
__vfptr
每個(gè)包含虛函數(shù)的類對(duì)象都獲得__vfptr指針,并且是對(duì)象的第一個(gè)數(shù)據(jù)成員
編譯器必須要保證虛函數(shù)表的指針存在于對(duì)象實(shí)例中最前面的位置
在計(jì)算對(duì)象的總大小時(shí),也必須考慮到虛表指針。比如new,傳遞給new的大小值不僅包括類(以及任何超類)中的所有顯式聲明的字段占用的空間,而且包括虛表指針?biāo)璧娜魏慰臻g?
示例代碼:
IDA分析如下:?
值得注意的是,虛表索引操作非常類似于結(jié)構(gòu)體引用操作。實(shí)際上,它們之間并無(wú)區(qū)別?。因此,我們可以定義一個(gè)結(jié)構(gòu)體來(lái)表示一個(gè)類的虛表的布局,然后利用這個(gè)已定義的結(jié)構(gòu)體來(lái)提高反匯編代碼清單的可讀性?
這個(gè)結(jié)構(gòu)體允許將虛表引用操作重新格式化成以下形式:?
注意:
C++虛函數(shù)絕不會(huì)被直接引用,也絕不應(yīng)成為調(diào)用交叉引用的目標(biāo)。所有C++虛函數(shù)應(yīng)由至少一個(gè)虛表?xiàng)l目引用,并且始終是至少一個(gè)偏移量交叉引用的目標(biāo)。
我們隨便找到 vf1函數(shù)定義,然后點(diǎn)擊它的交叉引用:?
從而跳轉(zhuǎn)到虛表,其顯示如下:
.rdata:004031B8 const Base::`vftable' dd offset __purecall ; DATA XREF: Base::Base(void)+A↑o
.rdata:004031BC ? ? ? ? ? ? ? ? dd offset Base::vf2(void)
.rdata:004031C0 ? ? ? ? ? ? ? ? dd offset Base::vf3(void)
.rdata:004031C4 ? ? ? ? ? ? ? ? dd offset Base::vf4(void)
.rdata:004031C8 ? ? ? ? ? ? ? ? dd offset const Sub::`RTTI Complete Object Locator'
.rdata:004031CC const Sub::`vftable' dd offset Sub::vf1(void)
.rdata:004031CC ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ; DATA XREF: Sub::Sub(void)+12↑o
.rdata:004031D0 ? ? ? ? ? ? ? ? dd offset Base::vf2(void)
.rdata:004031D4 ? ? ? ? ? ? ? ? dd offset Sub::vf3(void)
.rdata:004031D8 ? ? ? ? ? ? ? ? dd offset Base::vf4(void)
.rdata:004031DC ? ? ? ? ? ? ? ? dd offset Sub::vf5(void)
可以看到,類構(gòu)造函數(shù)Sub:: Sub(void)使用了虛表的地址Sub::Sub(void)+12↑o, 那是因?yàn)閚ew sub 調(diào)用了sub的隱式構(gòu)造函數(shù)?
windbg觀察:?
注意,Base的虛表第一個(gè)是002816e4 Test!purecall,這時(shí)因?yàn)樵贐ase中,沒(méi)有針對(duì)純虛函數(shù)vf1的實(shí)現(xiàn),所以在Base的虛表中并沒(méi)有存儲(chǔ)vf1的地址,這時(shí),編譯器會(huì)插入一個(gè)錯(cuò)誤處理函數(shù)的地址,通常,該函數(shù)名為purecall,一旦它被調(diào)用,程序就會(huì)被終止
附?
可以觀察到:
1.new指針不為空,才會(huì)調(diào)用構(gòu)造函數(shù),這是由Visual C++的內(nèi)部機(jī)制來(lái)保證的?
2.函數(shù)的虛表位置一般都可以在構(gòu)造函數(shù)中找到(很明顯,this指針指向的地址就是虛表的位置)
?
?
?
?
?
?
總結(jié)
以上是生活随笔為你收集整理的12.IDA-虚函数和虚表(vf代表虚函数,vf3代表this指向第三个函数)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Z-Stack Home Develop
- 下一篇: caffe使用训练好的模型对自己的一张图