初探vftable

初探vftable

vftable是用来存放虚函数地址的,下面简单探索一下vftable中存储的内容

#include <iostream>
#include <cstdio>

class Base
{
public:
	Base(){}
	virtual void BaseFunc1()
	{

	}
};

class Chil : public Base
{
public:
	Chil(){}
	virtual void ChilFun1()
	{

	}
};


int main()
{
	Chil *c = new Chil();
	printf("Base:BaseFunc1=%p\n", &Base::BaseFunc1);
	printf("Chil:ChilFun1=%p\n", &Chil::ChilFun1);
	return  0;
}
输出:
Base:BaseFunc1=001012D0
Chil:ChilFun1=00101064

这一串代码中有两个虚函数,所以vftable中应该是占用8个字节,每4个字节为一个函数地址,下面通过vptr找到vftable的内容

0x00109C40  cc 11 10 00 c6 12 10 00

这里非常奇怪,就是vftable中的内容跟输出的地址是不一样的,这就很疑惑了,两个都是同一个函数的地址,为什么会存在地址不一样的情况

汇编

为了解惑,就只有看汇编代码,以其中一个函数为例子

	printf("Base:BaseFunc1=%p\n", &Base::BaseFunc1);
00102F50  push        offset Base::`vcall'{0}' (01012D0h)  
00102F55  push        offset string "Base:BaseFunc1=%p\n" (0109C4Ch)  
00102F5A  call        _printf (0101055h)  
00102F5F  add         esp,8  
------------------------------------------------------------------------
Base::`vcall'{0}':
001012D0  jmp         Base::`vcall'{0}' (0102CEAh)
------------------------------------------------------------------------
Base::`vcall'{0}':
00102CEA  mov         eax,dword ptr [ecx]  
00102CEC  jmp         dword ptr [eax]  

可以清楚的看到,它经过了一系列的vcall调用后,最终还是调用的vftable中的地址,在最后两行可以清晰的看到

vftable内存的内容

偶偶与我的程序程序编译了,所以vftable的内容改变了,下面是新的

0x000D9C40  cc 11 0d 00 c6 12 0d 00
//在汇编中找到代码
Base::BaseFunc1:
000D11CC  jmp         Base::BaseFunc1 (0D2D00h)
//在继续往下找
000D2D00  push        ebp  
	virtual void BaseFunc1()
	{
000D2D01  mov         ebp,esp  
000D2D03  sub         esp,0CCh  
000D2D09  push        ebx  
000D2D0A  push        esi  
000D2D0B  push        edi  
000D2D0C  push        ecx  
000D2D0D  lea         edi,[ebp-0CCh]  
000D2D13  mov         ecx,33h  
000D2D18  mov         eax,0CCCCCCCCh  
000D2D1D  rep stos    dword ptr es:[edi]  
000D2D1F  pop         ecx  
000D2D20  mov         dword ptr [this],ecx  
000D2D23  mov         ecx,offset _14314AF1_vftable地址@cpp (0DE05Eh)  
000D2D28  call        @__CheckForDebuggerJustMyCode@4 (0D128Ah)  

	}

总结

函数的地址跟vftable中的地址是不一样的,函数地址是通过vcall去调用vftable的,vftable是直接调用的是

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值