类的汇编形式和反汇编破解

此篇幅主要研究简单类内存结构,用于学习反汇编

 

class CClassTest
{
public:
	CClassTest();
	~CClassTest();

public:
	virtual void _stdcall SetAge(const int age);

	virtual int GetAge();

	void _stdcall Geive();

	void static StaticFun(int staticParam);

private:
	void _stdcall SSk();

private:
	int m_age;
	int m_session;
	static int m_global;
};

 

int CClassTest::m_global = 12;
CClassTest::CClassTest()
{	
	m_age = (int)GetTickCount();
	m_session = 10;
}

CClassTest::~CClassTest()
{

}

int CClassTest::GetAge()
{	
	return m_age;
}

void CClassTest::SetAge(const int age)
{
	m_age += 56;

	m_session = 89;
	SSk();
}

void CClassTest::SSk()
{
	m_age = 59;
	m_session += m_age;
	CClassTest::m_global += 98;
}

void _stdcall CClassTest::Geive()
{
	m_session = m_age;
}

void CClassTest::StaticFun(int staticParam)
{
	printf("CClassTest::StaticFun param=%d\r\n", staticParam);
}

 

//主程序调用部分

 

 

CClassTest *w = new CClassTest();

int _tmain(int argc, _TCHAR* argv[])
{	
	//printf("w=%x size=%d\r\n", w, sizeof(*w));
	//普通函数
	int res = w->GetAge();
	printf("age=%d\r\n", res);

	//虚函数
	w->SetAge(argc);

	w->Geive();
	
	//静态函数
	CClassTest::StaticFun(156);
	
	
	return 0;
}

 

这个类,我们定义的非常简单,主要用于研究其内存结构,代码没有任何意义,同时编译时关闭优化,不然这个类转为汇编后将面目全非。

1、类是怎么分布的

2、程序变量和函数怎么分布

3、静态成员怎么分布

4、调用类函数汇编是什么样的

 

首先看看MAIN函数:

可以看到头两行是例行保存SP,然后保存cx,

调用GetAge虚函数,图中1位置

开始正式工作,首先将[w]放入ax(w是一个指针,他的值就是一个地址,这里就是this指针),然后把[ax]的值(就是函数的虚表地址)放入dx,然后[dx+4]就是函数GetAge的地址(这个函数在类中是第二虚函数,vptr+0=SetAge, vptr+4=GetAge),我看的在调用GetAge之前,我们将this指针放入了cx中,便于在GetAge函数中使用,(注意,我发现只有在调用对象的第一个函数的时候才会这样传值,而在其后调用SetAge时,this指针式被当做参数push进去的,而且永远是第一个参数,也就是最后一个入栈的)

我们再看GetAge内容

 

函数定义的时候采用了GetAge(CClassTest *this)的方式,但是函数内部并没有使用到这个参数,而是重新定义了一个局部变量来存放this指针, 将cx入栈,这时候[bp-4]就是刚刚入栈的cx的位置,将cx的值放入其中,然后ax中存放的是对象的起始地址,偏移4字节,就是跳过虚函数指针变量(因为这个类带有虚函数),刚好是m_age变量的地址,[ax+4]放入ax函数调用结束

 

 

继续看=SetAge函数,就是图中2的部分,有两个push第一个是age参数,第二个是this指针,

SetAge函数体:

 

m_age是this偏移4字节,m_session是this偏移8字节,这样看代码应该很清楚了,然后是调用SSK()函数,可以看到,直接this指针入栈,然后调用,等价于 SSk(CClassTest* this);

 

 

下面看普通函数Geive调用(不占用类内存),图中3

首先是push了this指针,然后直接调用了一个函数,等价于调用了 Geive(CClassTest* this);

图说明了一切。

 

 

下面是类静态函数调用(不占用类内存),图中4位置

调用之前将staticParam入栈了


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值