vtable

编译器会为每一个包含虚函数的类(或通过继承得到的子类)生成一个表,其中包含指向类中每一个虚函数的指针,这样的表就叫做虚表(vtable)

__vfptr

每个包含虚函数的类对象都获得__vfptr指针,并且是对象的第一个数据成员

编译器必须要保证虚函数表的指针存在于对象实例中最前面的位置

在计算对象的总大小时,也必须考虑到虚表指针。比如new,传递给new的大小值不仅包括类(以及任何超类)中的所有显式声明的字段占用的空间,而且包括虚表指针所需的任何空间 
示例代码:

class Base
{
public:   (10个字节,0,4,8,12,this)virtual void vf1() = 0;virtual void vf2(){ cout<<"Base::vf2"<<endl; }virtual void vf3(){ cout<<"Base::vf3"<<endl; }virtual void vf4(){ cout<<"Base::vf4"<<endl; }
private:int x,y;
};class Sub: public Base
{
public:virtual void vf1(){cout<<"Sub::vf1"<<endl; }virtual void vf3(){cout<<"Sub::vf3"<<endl; }virtual void vf5(){cout<<"Sub::vf5"<<endl; }
private:int z;
};void call_vf(Base* b)
{b->vf3();
}int _tmain(int argc, _TCHAR* argv[])
{Base *b = new Sub;call_vf(b);
}

IDA分析如下:

值得注意的是,虚表索引操作非常类似于结构体引用操作。实际上,它们之间并无区别 。因此,我们可以定义一个结构体来表示一个类的虚表的布局,然后利用这个已定义的结构体来提高反汇编代码清单的可读性

这个结构体允许将虚表引用操作重新格式化成以下形式:

注意:

C++虚函数绝不会被直接引用,也绝不应成为调用交叉引用的目标。所有C++虚函数应由至少一个虚表条目引用,并且始终是至少一个偏移量交叉引用的目标。

我们随便找到 vf1函数定义,然后点击它的交叉引用:

从而跳转到虚表,其显示如下:

.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)

可以看到,类构造函数Sub:: Sub(void)使用了虚表的地址Sub::Sub(void)+12↑o, 那是因为new sub 调用了sub的隐式构造函数

windbg观察:

注意,Base的虚表第一个是002816e4 Test!purecall,这时因为在Base中,没有针对纯虚函数vf1的实现,所以在Base的虚表中并没有存储vf1的地址,这时,编译器会插入一个错误处理函数的地址,通常,该函数名为purecall,一旦它被调用,程序就会被终止

附 
可以观察到:

1.new指针不为空,才会调用构造函数,这是由Visual C++的内部机制来保证的 
2.函数的虚表位置一般都可以在构造函数中找到(很明显,this指针指向的地址就是虚表的位置)

12.IDA-虚函数和虚表(vf代表虚函数,vf3代表this指向第三个函数)相关推荐

  1. dll侧加载_动态载入DLL所需要的三个函数详解(LoadLibrary,GetProcAddress,FreeLibrary)...

    动态载入 DLL 动态载入方式是指在编译之前并不知道将会调用哪些 DLL 函数, 完全是在运行过程中根据需要决定应调用哪些函数. 方法是:用 LoadLibrary 函数加载动态链接库到内存,用 Ge ...

  2. 【转载】动态载入DLL所需要的三个函数详解(LoadLibrary,GetProcAddress,FreeLibrary)...

    原文地址:https://www.cnblogs.com/westsoft/p/5936092.html 动态载入 DLL 动态载入方式是指在编译之前并不知道将会调用哪些 DLL 函数, 完全是在运行 ...

  3. 动态载入DLL所需要的三个函数详解(LoadLibrary,GetProcAddress,FreeLibrary)

    x动态载入 DLL 动态载入方式是指在编译之前并不知道将会调用哪些 DLL 函数, 完全是在运行过程中根据需要决定应调用哪些函数. 方法是:用 LoadLibrary 函数加载动态链接库到内存,用 G ...

  4. java写三次函数导数,用导数研究三次函数

    <用导数研究三次函数>由会员分享,可在线阅读,更多相关<用导数研究三次函数(14页珍藏版)>请在人人文库网上搜索. 1.用导数研究三次函数1. 知识点解析1.定义:定义1.形如 ...

  5. 12.IDA-虚函数和虚表

    vtable 编译器会为每一个包含虚函数的类(或通过继承得到的子类)生成一个表,其中包含指向类中每一个虚函数的指针,这样的表就叫做虚表(vtable) __vfptr 每个包含虚函数的类对象都获得__ ...

  6. 虚函数,虚表深度剖析

    面向对象,从单一的类开始说起. class A { private:int m_a;int m_b; }; 这个类中有两个成员变量,都是int类型,所以这个类在内存中占用多大的内存空间呢? sizeo ...

  7. C++——多态|虚函数|重写|虚表

    文章目录 1. 多态的概念 1.1 概念 2. 多态的定义及实现 2.1多态的构成条件 2.2 虚函数 2.3虚函数的重写 虚函数重写的三个例外: 2.4 普通调用和多态调用: 2.5 C++11 o ...

  8. C++_vptr与vtbl,虚函数与虚表

    C++_vptr与vtbl,虚函数与虚表 一:虚函数表指针(vptr)创建时机 vptr跟着对象走,所以对象什么时候创建出来,vptr就什么时候创建出来,也就是运行的时候. 当程序在编译期间,编译器会 ...

  9. C++中虚函数、虚指针和虚表详解

    关于虚函数的背景知识 用virtual关键字申明的函数叫做虚函数,虚函数肯定是类的成员函数. 存在虚函数的类都有一个一维的虚函数表叫做虚表.每一个类的对象都有一个指向虚表开始的虚指针.虚表是和类对应的 ...

最新文章

  1. C语言实现ifconfig获取网卡接收和发送流量统计
  2. 写文件 —— 将内容按照指定格式写入配置文件(fwrite()函数-》》向指定的文件中写入若干数据块)
  3. 编译我的第一个c语言,linux菜鸟学习写第一个C语言代码--“hello Linux!”
  4. spring注入私有字段_Spring字段依赖注入示例
  5. 运用Arc Hydro提取河网
  6. 《Android开发艺术探索》读书笔记 (10) 第10章 Android的消息机制
  7. 服务器推送_初探 Watermill 构建 Golang 事件驱动程序,SSE 进行 HTTP 服务器推送
  8. android 自定义透明 等待 dialog,Android自定义Dialog内部透明、外部遮罩效果
  9. js打开本地文件_JS逆向|高频问题:为何Reres插件总是替换本地文件失败?
  10. 【Go命令教程】11. go vet 与 go tool vet
  11. Atitit 软件体系的进化,是否需要一个处理中心
  12. 基于Silverlight4开发的相关工具
  13. 免费得了一套做自媒体教程,免费分享给大家
  14. NAS网络配置、资源管理和用户访问权限
  15. QQ小程序开发者工具及官网
  16. 淘宝宝贝的标题,到底要如何优化,不妨进来看看,也许对你有帮助
  17. 【计算机毕业设计】437物流管理系统设计与实现
  18. 微信小程序实现画布生成海报功能
  19. add_metrology_object_circle_measure (对齐测量模型)
  20. Python 3.8详细安装教程

热门文章

  1. PHP个人博客网站设计 学生PHP个人博客网页源码 PHP MYSQL动态网站作品
  2. 第61课 查分程序 《小学生C++趣味编程》
  3. 利用moviepy库制作好用的MP4、mov、mav、avi等视频类型转换gif图片的工具
  4. js扩展滚动窗口小插件实现文字左右上下滚动效果实例
  5. java rtmp推流_rtmp推流直播流程
  6. h5 表单居中_3分钟学会易企秀H5操作(基础篇)
  7. spring boot jwt_springboot整合JWT
  8. Linux工作笔记-根据PID查询进程是否存在(进程管理相关程序中常用)
  9. Java工作笔记-使用IDEA开始我的第一个Spring项目
  10. Qt文档阅读笔记-QGraphicsItem events解析与实例