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 0; }
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(1); int Number = Test.GetTest(); //添加了Set,Get方法,并调用getchar();return 0; }
看上面,我们可以看出都是默认的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指针)
转载于:https://www.cnblogs.com/iBinary/p/7966821.html
C++反汇编第一讲,认识构造函数,析构函数,以及成员函数相关推荐
- 股票选股公式编写教程第一讲:公式编写的基础函数
股票选股公式编写教程 第一讲:公式编写的基础函数 打开技术指标公式,我们最常见的,它的组成不外乎两种情况,一是 K线,二是均线.其他诸如柱状线,彩带,分段线等等,都是在 K线或均线基础上的延伸或变形. ...
- 定义一个复数类complex,包含两个属性:实部和虚部,包含构造函数,包含成员函数void display()输出,包括成员函数complex add(complex a), 进行复数加法。
定义一个复数类complex,包含两个属性:实部和虚部,包含构造函数,包含成员函数void display()输出,包括成员函数complex add(complex a), 进行复数加法,在主函数种 ...
- 拷贝构造,深度拷贝,关于delete和default相关的操作,explicit,类赋初值,构造函数和析构函数,成员函数和内联函数,关于内存存储,默认参数,静态函数和普通函数,const函数,友元
1.拷贝构造 //拷贝构造的规则,有两种方式实现初始化. //1.一个是通过在后面:a(x),b(y)的方式实现初始化. //2.第二种初始化的方式是直接在构造方法里面实现初始化. 案例如下: ...
- C++面向对象笔记:构造、析构函数、成员函数
构造函数:用以对类中数据成员进行初始化 系统会自动生成默认构造函数(参数为空),但是若手动定义了带参的构造函数,会自动覆盖默认构造函数时若需要调用默认构造函数进行实例化,需要手动定义一个不带参的构造函 ...
- 第一讲 高数基本知识1
第一讲 高数基本知识1 函数定义 反函数 性质 复合函数 例题 函数特性 有界性 [注] 单调性 求导证明 定义证明 奇偶性 奇函数 偶函数 [注] 周期性 定义 [注] 对称性 [注] 函数图像 常 ...
- 类的6个默认成员函数:构造函数、析构函数、拷贝构造函数、重载运算符、三/五法则
文章目录 6个默认成员函数 构造函数 概念 默认构造函数的类型 默认实参 概念 默认实参的使用 默认实参声明 全局变量作为默认实参 某些类不能依赖于编译器合成的默认构造函数 第一个原因 第二个原因 第 ...
- C++类的构造函数、析构函数与赋值函数
C++类的构造函数.析构函数与赋值函数 构造函数.析构函数与赋值函数是每个类最基本的函数.它们太普通以致让人容易麻痹大意,其实这些貌似简单的函数就象没有顶盖的下水道那样危险. 每个类只有一个析构函数和 ...
- 【跟学C++】C++类与对象—构造函数—析构函数(Study10)
文章目录 1.面向对象(类与对象) 1.1 类 1.2 对象 1.3 访问之句点运算符(.) 1.4 访问之指针运算符(->) 2.public(公有)和private(私有) 3.构造函数 3 ...
- C#精髓【月儿原创】第一讲 使用垃圾回收器
说明:准备出一个系列,所谓精髓讲C#语言要点.这个系列没有先后顺序,不过尽量做到精.可能会不断增删整理,本系列最原始出处是csdn博客,谢谢关注. C#精髓 第一讲 使用垃圾回收器 作者:清清月儿 主 ...
最新文章
- ocr数据集批量换随机背景
- 006-spring cloud gateway-GatewayAutoConfiguration核心配置-GatewayProperties初始化加载、Route初始化加载...
- java组长一个月工资多少,保准看明白!
- linux history 看更多历史记录_Linux历史记录history常用技巧
- 打造最强加密工具之《绝密信息传递》
- python 模拟用户点击浏览器_使用python进行模拟浏览器操作
- Druid : 慢SQL统计与监控
- 加载java ie停止工作_打开网页,IE浏览器提示Internet Explorer 已停止工作什么原因?怎么解决?...
- 学习MySQL,怎么能不会数据类型和schema优化!
- Spring Boot集成Spring Data Reids和Spring Session实现Session共享(多个不同的应用共用一个Redis实例)...
- mysql可视化界面数据导出_MySQL 使用可视化工具导出与导入数据
- 基于opencv的对CV_16U深度图像MAT中某点的像素值提取问题
- Zemax 全新 22.1 版本产品现已发布
- [嵌入式学习必备网站分享]嵌入式开发必须收藏的二十个网站 内附超链接 实用 嵌入式单片机学习网站
- 经过路由无法找到计算机,共享打印机找不到对方电脑解决方法
- MacOS技巧|Mac如何自定义触控栏Touch Bar?显示Touch Bar教程
- 尚硅谷nodejs入门教程_笔记
- Redis框架(三):大众点评项目 基于Session的短信登录
- 计算机英语单词练习二
- ydisk安卓版本_DiskInfo下载-DiskInfo(手机磁盘使用情况)下载v4.9.9 (build 10) 安卓版-西西软件下载...
热门文章
- CVE-2021-30116: Kaseya VSA 远程代码执行漏洞
- C++二分查找示例(求货物装载量)
- linux 在命令行中复制的快捷键_在 Linux 中加速工作的键盘快捷键 | Linux 中国
- maven项目乱码以及项目名出现红叉
- Filtering 过滤操作
- Java数组学习笔记(遍历、排序、多维数组、命令行参数)
- pc工具不支持stb的加密方式_那些工作中常用的实用工具
- Zabbix(六) zabbix主动模式监控
- fabric8 java api,kubectl apply -f equivalent in fabric8 java api | 易学教程
- js 导出pdf上传至oss_前端上传图片到oss,压缩图片后上传至oss(补充图片文件旋转90度问题)...