当前位置: 首页 > wzjs >正文

濮阳佳杰网站建设巧用不对称培训机构有哪些

濮阳佳杰网站建设巧用不对称,培训机构有哪些,8x8x域名解析ip地址查询,wordpress多城市子站尝试修改虚函数表 本期纯整活儿好吧!!!! 初衷 有一天我突然开始好奇虚函数表是否真的存在,于是我开始想是否能够从C中查看或者调用虚函数表中的内容。,于是有了下面的操作。 操作过程 起初我并没有思路…

尝试修改虚函数表

本期纯整活儿好吧!!!!

初衷

有一天我突然开始好奇虚函数表是否真的存在,于是我开始想是否能够从C++中查看或者调用虚函数表中的内容。,于是有了下面的操作。

操作过程

起初我并没有思路,但是我知道,每一个类对应一个虚函数表,因此首先我需要一个虚函数,因此我随便写了一个基类:

class Base {
public:void output() {cout << "Class Base" << endl; };virtual void say() {cout << "Class Base" << endl;}
};

然后写一个子类,去 override 一下他的这个函数:

class A : public Base {
public:void output() {cout << "Class A" << endl;}void say() override {cout << "Class A" << endl;}int x;
};

然后按照同样的方式再创建一个 B 类:

class B : public Base {
public:void output() {cout << "Class B" << endl;}void say() override {cout << "Class B" << endl;}
};

这样以来,应该会有三个虚函数表,分别是:

  • Base基类对应的虚函数表
  • A类对应的虚函数表
  • B类对应的虚函数表

然后如何调用他们呢?我想了好久,想出这样的一个方法:

int main() {A a;B b;cout << "A's virtual table address : " << ((void **)(&a))[0] << endl;cout << "A's virtual table address : " << ((void **)(&b))[0] << endl;return 0;
}

根据理论来说,C++中的虚函数表应该在类内空间的第一个位置,占八个字节,是一个指向函数表的指针,那么我们就应该这样做:

((void **)(&b))[0];

这会返回一个虚函数表的地址。

这句话是什么意思呢?首先我们要清楚,对象的空间分配与结构体是一样的,而根据理论来看,虚函数表的指针会被编译器自动添加在对象空间的初始位置,也就是说,对象所在的空间的第一个单元存储的是虚函数表的地址。

如何获得这个首地址呢?首先我们要像取数组首地址一样,用取地址符号获得对象的首地址。然后将其强制转换为 (void **) 类型,这相当于让电脑将这个对象的空间看作一个数组,这个数组中存放的全部都是指向 void * 类型的数据的地址。

void * 类型是函数指针类型,我们不用管,最后在末尾添加[0]就相当于得到了虚函数表的地址。

尝试输出一下:
1
嗯,看起来没啥问题,但是如何证明他是个虚函数表的地址呢?

我能否将一个类中的修改到另一个虚函数表中?然后让这个对象执行的时候出现另外一个类的动作?

于是我开始了下面的尝试:

int main() {A a;B b;cout << "Class A virtual table address : " << ((void **)(&a))[0] << endl;cout << "Class B virtual table address : " << ((void **)(&b))[0] << endl;((void **)(&a))[0] = ((void **)(&b))[0]; // 把b对应的类的虚函数表覆盖到a上a.say(); // 如果虚函数表被覆盖了的话,那么就会出现a执行了b的say方法的状况b.say();return 0;
}

然而结果是这样的:

2
发现结果并没有被改变,这是怎么回事?我百思不得其解,多方询问过之后了解到是gcc编译器把我的虚函数的调用过程给优化掉了,无奈我只能使用指针和引用来赋值:

int main() {A a;B b;Base *ap = &a, *bp = &b;cout << "Class A virtual table address : " << ((void **)(&a))[0] << endl;cout << "Class B virtual table address : " << ((void **)(&b))[0] << endl;((void **)(&a))[0] = ((void **)(&b))[0]; // 把b对应的类的虚函数表覆盖到a上ap->say(); // 如果虚函数表被覆盖了的话,那么就会出现a执行了b的say方法的状况bp->say();return 0;
}

3
执行成功啦!!!

其实后面我还做了很多好玩的操作,这里先不放出来,写的有点累,下次再凑出一篇来!

:wq 拜拜~~

http://www.dtcms.com/wzjs/95464.html

相关文章:

  • 手机网站 ui公司网络营销推广软件
  • 找公司做网站注意事项公司关键词排名优化
  • 怎么在自己做的网站上发视频安仁网络推广
  • 长春网站建设5219网站服务器怎么搭建
  • 黑龙江建设网网站漯河网络推广哪家好
  • 一级做爰A视频免费网站网站排名优化化快排优化
  • 福州网站关键词推广免费网上销售平台
  • 做网站需要域名吗手机如何建网站
  • 试玩平台网站怎么做杭州网站建设方案优化
  • 成品网站建设价格网络营销讲师
  • 标准网站建设服务器淘宝宝贝关键词排名查询工具
  • 成都网站建设公司电话百度有几个总部
  • 网站建设公司客户开发手册seo网络推广经理招聘
  • 合肥品牌型网站建设地址免费打广告网站
  • 俄文手机网站制作百度信息流开户多少钱
  • 网站续费如何做分录德阳seo优化
  • 8黄页网站建设黑龙seo网站优化
  • 网站做交叉连接免费外链发布
  • 用html5做的网站网络营销成功案例3篇
  • 西安做北郊做网站抖音seo优化
  • 郑州网站推广电话中小企业管理培训课程
  • 网站建设如何处理病毒木马百度收录提交网址
  • 济宁网站建设软件开发营销型网站制作
  • 微信官方网站是多少钱网站建设推广服务
  • 空白网站怎么建立广州各区最新动态
  • wordpress进会员投稿太原seo优化
  • 洛阳网站设计公司百度整站优化
  • 奖励网站源码南通做网站推广的公司
  • 怎么样免费做自己的网站游戏优化
  • 广东网站制作平台国外网络推广