陈浩 C++ 对象的内存布局(下)勘误

不知道大家有没有看过 陈浩的C++ 对象的内存布局(下),作者给的代码并不能运行

作者文章 :http://blog.csdn.net/haoel/article/details/3081328

 

我改过的代码如下 重点是这句

 

#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
#include <list>
using namespace std;

class B

{

public:

	int ib;

	char cb;

public:

	B():ib(0),cb('B') {}



	virtual void f() { cout << "B::f()" << endl;}

	virtual void Bf() { cout << "B::Bf()" << endl;}

};

class B1 : virtual public B

{

public:

	int ib1;

	char cb1;

public:

	B1():ib1(11),cb1('1') {}



	virtual void f() { cout << "B1::f()" << endl;}

	virtual void f1() { cout << "B1::f1()" << endl;}

	virtual void Bf1() { cout << "B1::Bf1()" << endl;}



};

class B2: virtual public B

{

public:

	int ib2;

	char cb2;

public:

	B2():ib2(12),cb2('2') {}



	virtual void f() { cout << "B2::f()" << endl;}

	virtual void f2() { cout << "B2::f2()" << endl;}

	virtual void Bf2() { cout << "B2::Bf2()" << endl;}



};



class D : public B1, public B2

{

public:

	int id;

	char cd;

public:

	D():id(100),cd('D') {}



	virtual void f() { cout << "D::f()" << endl;}

	virtual void f1() { cout << "D::f1()" << endl;}

	virtual void f2() { cout << "D::f2()" << endl;}

	virtual void Df() { cout << "D::Df()" << endl;}



};

void main()
{
	D dd;

	typedef void(*Fun)(void);

	int** pVtab = NULL;

	Fun pFun = NULL;


	pVtab = (int**)&dd;

	cout << "[0] D::B1::_vptr->" << endl;

	pFun = (Fun)pVtab[0][0];

	cout << "     [0] ";    pFun(); //D::f1();

	pFun = (Fun)pVtab[0][1];

	cout << "     [1] ";    pFun(); //B1::Bf1();

	pFun = (Fun)pVtab[0][2];

	cout << "     [2] ";    pFun(); //D::Df();

	pFun = (Fun)pVtab[0][3];

	cout << "     [3] ";

	cout << pFun << endl;



	//cout << pVtab[4][2] << endl;

	cout << "[1] = 0x";

	cout <<  (int*)((&dd)+1) <<endl; //????



	cout << "[2] B1::ib1 = ";

	cout << *((int*)(&dd)+2) <<endl; //B1::ib1

	cout << "[3] B1::cb1 = ";

	cout << (char)*((int*)(&dd)+3) << endl; //B1::cb1



	//---------------------

	cout << "[4] D::B2::_vptr->" << endl;

	pFun = (Fun)pVtab[4][0];

	cout << "     [0] ";    pFun(); //D::f2();

	pFun = (Fun)pVtab[4][1];

	cout << "     [1] ";    pFun(); //B2::Bf2();


	pFun = (Fun)pVtab[4][2];

	cout << "     [2] ";

	cout << pFun << endl;



	cout << "[5] = 0x";

	cout << *((int*)(&dd)+5) << endl; // ???



	cout << "[6] B2::ib2 = ";

	cout << (int)*((int*)(&dd)+6) <<endl; //B2::ib2

	cout << "[7] B2::cb2 = ";

	cout << (char)*((int*)(&dd)+7) << endl; //B2::cb2



	cout << "[8] D::id = ";

	cout << *((int*)(&dd)+8) << endl; //D::id

	cout << "[9] D::cd = ";

	cout << (char)*((int*)(&dd)+9) << endl;//D::cd



	cout << "[10]  = 0x";

	cout << (int*)*((int*)(&dd)+10) << endl;

	//---------------------

	cout << "[11] D::B::_vptr->" << endl;

	pFun = (Fun)pVtab[11][0];

	int temp = 0;

	__asm
	{
		mov temp, ecx //保存原始的ecx
	}

	//原始例子中注释掉 cout << "     [0] ";这句就行,不注释的话也可以这样做

	cout << "     [0] ";    //pFun(); //D::f();

	//pFun();
	
	__asm
	{
		mov ecx, temp //还原过来
	}

	pFun(); //这样就可以直接调用了

	__asm
	{
		call pFun //继续汇编调用方法 简单直接call
	}


	//不用还原ecx  都可以直接调用 ,大家可以把上面的保护ecx操作注释掉试试
	__asm
	{
		mov edx, pFun;
		mov eax, [edx]
		shr eax, 8 //调整偏移
		add eax, 5  
		add edx, eax;
		add edx, 3 //由于thunk  就是那个vdisp什么的,必须跳过 sub ecx, [ecx-4]这句
		call edx  
	}



	pFun = (Fun)pVtab[11][1];

	cout << "     [1] ";    pFun(); //B::Bf();

	pFun = (Fun)pVtab[11][2];

	cout << "     [2] ";

	cout << pFun << endl;

	



	cout << "[12] B::ib = ";

	cout << *((int*)(&dd)+12) << endl; //B::ib

	cout << "[13] B::cb = ";

	cout << (char)*((int*)(&dd)+13) <<endl;//B::cb


}


运行结果如图

之所以要调过那个ecx-4是因为图形

估计这篇文章没人看 屌丝文章,就算了,不解释了 无非是调过这句 sub ecx,dword ptr[ecx-4]  ,如果加了cout << "[0]"什么的 改了ecx,导致取ecx-4异常违规而已

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值