C++反汇编第一讲,认识构造函数,析构函数,以及成员函数
C++反汇编第一讲,认识构造函数,析构函数,以及成员函数
以前说过在C系列下的汇编,怎么认识函数.那么现在是C++了,隐含有构造和析构函数
一丶认识构造函数
高级代码:
class MyTest
{
public:
MyTest();
~MyTest();
public:
DWORD m_dwTest;
};
MyTest::MyTest()
{
printf("1111\r\n"); //构造的时候先打印 }
MyTest::~MyTest()
{
printf("2222\r\n"); //析构的时候打印
} int main(int argc, char* argv[])
{
MyTest Test; //创建局部对象
getchar();
return ;
}
C++中的类,构造的时候先祖先类,然后父类,最后朋友类,然后在构造自己. 析构的时候 先自己 后朋友 接着父类 然后是祖先类,(明白一下顺序)
Debug下的汇编代码
这个是main函数内部,在创建对象的时候,会先调用构造,然后退出的时候会调用析构(上面是我改名字过后的)
现在我们认识构造有几个必要条件
1.ecx,this传参因为C++下的对象都是 thisCall,和FastCall类似,thisCall会通过寄存器传参.而fastCall最后两个参数会通过寄存器传参.
.鉴定是ecx传参的前提下是函数外面给值,函数内部使用
函数内部会将ecx给存储起来,这个内存空间称之为 this,也就是语法为什么可以这样写: this.xxxx = 1 this.MyTest();
高亮ecx传参的时候的内存地址,会有多处使用.
2.构造会在创建对象的时候先调用
3.构造函数的返回值则是this指针.
详解怎么查看构造函数
1.是ecx传参,确定了一个条件,其余两个条件还没有满足
2.函数内部使用ecx,且给this指针赋值,并且返回了this指针
返回的汇编:
3.该函数是当前栈作用域下的第一次调用
main函数中初始化成员变量为ccc之后,调用的第一个.
PS: 附加条件 我们点击ecx传参的时候的局部变量(this)会有多处使用.
一般来说确定上面三点则可以确定是构造函数了.上面三个都是必要条件.
而充分条件以后学习虚表的时候就知道了,构造会初始化虚表,且是第一个,所以可以直接确定是构造函数了.
说的听过,其实看反汇编代码也就3 - 4秒的事情.
Release下的汇编
根据上面代码,可以确定
1.先调用的第一个函数
2.ecx传参.并且内部使用了ecx,赋值给了this指针,且把this指针返回
注意:构造函数,析构函数只能是thiscall,就算你自己加上调用约定,编译的时候也提示是无效的调用约定,且反汇编代码不会做任何改变.
总结:
1.构造函数优先调用
2.ecx传参,且函数内部会将ecx给this赋值(this可能是一块内存空间,也可能是寄存器变量)且返回this指针
3.可以点击this指针,可能会有多次调用
注: 构造析构都是thiscall,不能修改
二丶识别析构函数
识别析构函数和构造函数类似
1.thiscall,并且最后调用
2.无返回值
看下析构函数
1.最后一次调用的
2.thiscall,无返回值,其内部会使用ecx给this赋值
Release下的汇编和Debug下一样,有优化,可能你不使用this则不会给this赋值.但是还是无返回值
总结:
1.析构最后一次调用
2.thiscall传参
3.无返回值
三丶识别成员函数(c call thiscall fastcall stdcall)
高级代码:
class MyTest
{
public:
MyTest();
~MyTest();
void SetTest(DWORD dwTest);
DWORD GetTest();
public:
DWORD m_dwTest;
};
MyTest::MyTest()
{
printf("1111\r\n"); }
MyTest::~MyTest()
{
printf("2222\r\n");
} void MyTest::SetTest(DWORD dwTest)
{
this->m_dwTest = dwTest;
}
DWORD MyTest::GetTest()
{
return this->m_dwTest;
}
int main(int argc, char* argv[])
{
MyTest Test;
Test.SetTest();
int Number = Test.GetTest(); //添加了Set,Get方法,并调用
getchar();
return ;
}
看上面,我们可以看出都是默认的thiscall,看下反汇编代码 (看各种调用约定会产生什么样的结果)
1.默认的thiscall在汇编中的表现形式
Debug下的反汇编
头尾是构造和析构,中间则是我们的SetGet方法,可以看出,如果是thiscall,那么是ecx传参,且里面ecx会给this指针赋值,且返回this指针
Release和Debug类似,可能有少许优化,为了篇幅原因,不在截图.
2.Stdcall 成员函数表现形式
看上面汇编代码得出
1.this指针是 ebp + var_10,
2.在stdcall下,会将this指针给寄存器,然后push进去
总结:
1.stdcall 会将this指针当做参数push进去.
2. push进去的this指针,会在call上面第一个push,也就是说this指针是第一个参数
3.平栈还是按照stdcall的形式平栈
3.C call下的汇编表现形式
也是通过push的方式,将this指针当做参数传递
然后c调用约定在外面平栈
4.fastCall的汇编表现形式
寄存器传参,然后ecx是外部更改,内部使用
最终的大总结:
1).识别构造
1.构造函数优先调用
2.ecx传参,且函数内部会将ecx给this赋值(this可能是一块内存空间,也可能是寄存器变量)且返回this指针
3.可以点击this指针,可能会有多次调用
注: 构造析构都是thiscall,不能修改
2).识别析构
1.析构最后一次调用
2.thiscall传参
3.无返回值
3).识别各种调用约定的成员函数
1.c调用约定,会将this指针push进去,然后平栈按照c调用约定平栈
2.stdcall,会将this指针push进去,内部平栈
3.thiscall会默认使用ecx,外部更改,内部使用,平栈和stdcall一样
4.fastcall,会使用两个寄存器传参,且也会外部更改ecx,内部使用.
5.c约定,std约定,push的时候都是this指针,且是第一个参数(也就是call上面的最近的一个push,必定为this指针)
C++反汇编第一讲,认识构造函数,析构函数,以及成员函数的更多相关文章
- C++反汇编第一讲,不同作用域下的构造和析构的识别
目录大纲: 1.全局(静态)对象的识别,(全局静态全局一样的,都是编译期间检查,所以当做全局对象看即可.) 1.1 探究本质,理解构造和析构的生成,以及调用方式(重要,如果不想知道,可以看总结.) 2 ...
- 拷贝构造函数,深拷贝,大约delete和default相关业务,explicit,给定初始类,构造函数和析构函数,成员函数和内联函数,关于记忆储存,默认参数,静态功能和正常功能,const功能,朋友
1.拷贝构造 //拷贝构造的规则,有两种方式实现初始化. //1.一个是通过在后面:a(x),b(y)的方式实现初始化. //2.另外一种初始化的方式是直接在构造方法里面实现初始化. 案比例如以 ...
- 拷贝构造函数和const成员函数
实验原因 说明如何使用const描述保护类数据不会意外修改. 编译环境 vc6sp6 + win7x64 工程下载 copyConstruction_constMemberFunction.zip ...
- C++反汇编第二讲,不同作用域下的构造和析构的识别
C++反汇编第二讲,不同作用域下的构造和析构的识别 目录大纲: 1.全局(静态)对象的识别,(全局静态全局一样的,都是编译期间检查,所以当做全局对象看即可.) 1.1 探究本质,理解构造和析构的生成, ...
- C++基础 (3) 第三天 构造函数 构造函数初始化列表 拷贝构造函数 析构函数 静态成员变量
// 同类之间无私处 2构造函数 3析构函数 4构造函数的种类和析构函数的顺序 结论:析构函数的调用顺序,跟对象的构造顺序相反,谁先构造,谁最后一个被析构. 拷贝构造函数: 注意: 等号写在下面和写在 ...
- 异常处理第一讲(SEH),筛选器异常,以及__asm的扩展,寄存器注入简介
异常处理第一讲(SSH),筛选器异常,以及__asm的扩展 博客园IBinary原创 博客连接:http://www.cnblogs.com/iBinary/ 转载请注明出处,谢谢 一丶__Asm的 ...
- 逆向实用干货分享,Hook技术第一讲,之Hook Windows API
逆向实用干货分享,Hook技术第一讲,之Hook Windows API 作者:IBinary出处:http://www.cnblogs.com/iBinary/版权所有,欢迎保留原文链接进行转载:) ...
- MFC原理第一讲.MFC的本质.以及手工编写MFC的程序
MFC原理第一讲.MFC的本质.以及手工编写MFC的程序 PS: 这个博客属于复习知识.从头开始讲解. 在写这篇博客之前.已经写了3篇MFC的本质了.不过掌握知识点太多.所以从简重新开始. 一丶MFC ...
- C++(1)C++类四个默认函数---构造函数、析构函数、拷贝函数、赋值函数
C++构造函数和析构函数 默认构造函数指不带参数或者所有参数都有缺省值的构造函数!!! (1)构造函数.析构函数与赋值函数 构造函数.析构函数与赋值函数是每个类最基本的函数.它们太普通以致让人容易麻痹 ...
随机推荐
- ModelForm
这是一个神奇的组件,通过名字我们可以看出来,这个组件的功能就是把model和form组合起来,对,你没猜错,相信自己的英语水平. 先来一个简单的例子来看一下这个东西怎么用: 比如我们的数据库中有这样一 ...
- CentOS 6.5 + Nginx 1.8.0 + PHP 5.6(with PHP-FPM) 负载均衡源码安装
CentOS 6.5 + Nginx 1.8.0 + PHP 5.6(with PHP-FPM) 负载均衡源码安装 http://www.cnblogs.com/ppoo24/p/4918288.ht ...
- LINUX 笔记-条件测试
格式:test condition 文件测试状态 -d 目录 -s 文件长度大于0,非空 -f 正规文件 -w 可写 -l 符号链接 -u 文件有suid位设置 -r 可读 -x 可执行 字符串测试 ...
- php开发微信公众号获取信息LBS
1.一般的公众号都可以在微信公众平台里面设置自定义菜单和自动回复消息,如果需要获取用户位置,则必须开启 服务器配置,当次功能开启后,微信公众平台的自定义菜单和自动回复则失效. 需要通过接口开发来实现微 ...
- 基于容器微服务的PaaS云平台设计(二)通过kubernetes实现微服务容器管理
版权声明:本文为博主原创文章,欢迎转载,转载请注明作者.原文超链接 ,博主地址:http://www.cnblogs.com/SuperXJ/ 上一章描述了基于spring cloud的微服务实例(实 ...
- [译]ASP.NET Core 2.0 本地文件操作
问题 如何在ASP.NET Core 2.0中受限地访问本地目录和文件信息? 答案 新建一个空项目,修改Startup类,添加访问本地文件所需的服务: public void ConfigureSer ...
- VB 用代码创建的控件和接收事件
在声明公共变量的位置加上这句就可以了 Dim WithEvents NewButton As Button form_load中添加 NewButton = New Button New ...
- WPF获得全局窗体句柄,并响应全局键盘事件
场景 wpf窗体运行后,只能捕获当前Active窗体的按键事件,如果要监听windows全局事件,并对当前窗口事件响应. 第一步:导入Winows API public class Win32 { [ ...
- 机器学习之三:logistic回归(最优化)
一般来说,回归不用在分类问题上,因为回归是连续型模型,而且受噪声影响比较大.如果非要应用进入,可以使用logistic回归. logistic回归本质上是线性回归,只是在特征到结果的映射中加入了一层函 ...
- 通过命令行使用cl.exe编译器
转载http://www.cnblogs.com/mizhongqin/archive/2013/03/11/cmd_cl-exe_vs2010.html 与在IDE中编译相比,命令行模式编译速度更快 ...