从反汇编的角度看C++语法(构造函数)
从反汇编的角度看C++语法(hani199012@gmail.com.cn/QQ :1121797386)
写在前面的话
写这些文章,主要是对自己在学习C++过程中遇到的一些问题进行总结,同时,利用反汇编工具来看C++语法在实际内存中的体现,因为,C++是一门高级语言,其实是写给人看的,但是机器只认识0 1 ,查看在学习过程中编写的一些练习的程序的反汇编代码,这样,看得更加实际,不那么抽象。
主要的参考书籍是《C++反汇编与逆向分析》(钱林松 赵海旭),需要推荐一下这本书,
这本书确实写的很好,我也是通过这本书来学习的,通过这本书,可以深刻的领会,逆向分析的威力。
其实,我也只是个学习者,通过,写一点总结性的文章,放到网上,希望,能够得到读者的批评,进一步能够相互学习。
用到的工具: VC++6.0
构造函数:
#include "stdafx.h"
#include "stdio.h"
class CNumber
{
public:
CNumber()
{
m_nNumber=1;
}
private:
int m_nNumber;
};
int main(int argc, char* argv[])
{
CNumber number;
return 0;
}
这段代码很简单,当然,重点不是代码本身,而是反汇编代码,通过查看反汇编代码,来认识在一个类创建了一个对象,也就是类实例化一个对象时,在内存中究竟发生了什么。
学习编程也应该保持这份好奇心,凡是探个究竟,一直深挖到不能再挖为止。
用VC6.0(我用的是英文版的)自带的反汇编工具查看(最好先设置一个端点, Build->
StartDebug->Go)单击右上角disassembly就可以查看反汇编代码
@ILT+0(??0CNumber@@QAE@XZ):
00401005 jmp CNumber::CNumber (00401060) ;构造函数
@ILT+5(_main):
0040100A jmp main (00401020) ;主函数
0040100F int 3
00401010 int 3
13: private:
14: int m_nNumber;
15: };
16:
17: int main(int argc, char* argv[])
18: {
00401020 push ebp
00401021 mov ebp,esp
00401023 sub esp,44h
00401026 push ebx
00401027 push esi
00401028 push edi
00401029 lea edi,[ebp-44h]
0040102C mov ecx,11h
00401031 mov eax,0CCCCCCCCh
00401036 rep stos dword ptr [edi]
19: CNumber number;
00401038 lea ecx,[ebp-4] ;取得对象首地址,传入ecx中
0040103B call @ILT+0(CNumber::CNumber) (00401005);调用构造函数
20:
21: return 0;
00401040 xor eax,eax
22: }
00401042 pop edi
00401043 pop esi
00401044 pop ebx
00401045 add esp,44h
00401048 cmp ebp,esp
0040104A call __chkesp (004010a0)
0040104F mov esp,ebp
00401051 pop ebp
00401052 ret
1: // construct.cpp : Defines the entry point for the console application.
2: //
3:
4: #include "stdafx.h"
5: #include "stdio.h"
6: class CNumber
7: {
8: public:
9: CNumber()
00401060 push ebp ;一系列的入栈出栈动作
00401061 mov ebp,esp ;入栈前保存一系列的寄存器的值
00401063 sub esp,44h ;出栈的时候恢复这些寄存器的值
00401066 push ebx ;进入一个函数前,这个函数要借寄存器
00401067 push esi ;做到有借有还
00401068 push edi
00401069 push ecx
0040106A lea edi,[ebp-44h]
0040106D mov ecx,11h
00401072 mov eax,0CCCCCCCCh
00401077 rep stos dword ptr [edi] ;
00401079 pop ecx ; 还原ecx,ecx中保存对象的首地址,
0040107A mov dword ptr [ebp-4],ecx ; [ebp-4]就是this指针
10: {
11: m_nNumber=1;
0040107D mov eax,dword ptr [ebp-4]
00401080 mov dword ptr [eax],1
12: }
00401086 mov eax,dword ptr [ebp-4]
00401089 pop edi
0040108A pop esi
0040108B pop ebx
0040108C mov esp,ebp
0040108E pop ebp
0040108F ret
按照内存中地址顺序拷贝出来,可以看到,先执行类的构造函数,在执行main函数,
然而,本来写在一起的类的成员变量和构造函数确实被编译器活生生的分割了,
这里也可以推测,所谓,类(暂时不考虑虚函数静态成员等问题)的大小是类的成员变量的大小,而不包括成员函数,是有一定道理的。
通过分析,可知,this指针是有构造函数产生的,构造函数结束后,会将this指针作为返回值。如果没有构造函数,编译器会默认的提供一个构造函数,而类的成员函数是根据this指针区分每个对象的,所以就算没有构造函数,也不会出现分不清类对象的情况。
接下来的情况没有给出代码,
1、类中有构造函数,但是没有成员变量,依然会执行构造函数,产生tihs指针,
00401079 pop ecx
0040107A mov dword ptr [ebp-4],ecx
2、空类,什么都没有生成,但是仍然会有构造函数,而这个地址却什么都没有
@ILT+0(??0CNumber@@QAE@XZ):
00401005 jmp CNumber::CNumber (00401060)
@ILT+5(_main):
0040100A jmp main (00401020)
据说,C++编译时空类的大小是1,可以推测,这个空类的大小和构造函数没有什么关系,可能仅仅是为了保证语法的一致性,编译器就让空类为1了
3, 没有构造函数或其他成员函数,只有成员变量
同上一个情况类似
4, 有成员函数的时候,会将看到
00401079 pop ecx
0040107A mov dword ptr [ebp-4],ecx
代码的出现,表示this 指针出现,而这唯一的一个成员函数返回this指针,作为这个类的构造函数
13: int foo()
14: {
00401060 push ebp
00401061 mov ebp,esp
00401063 sub esp,44h
00401066 push ebx
00401067 push esi
00401068 push edi
00401069 push ecx
0040106A lea edi,[ebp-44h]
0040106D mov ecx,11h
00401072 mov eax,0CCCCCCCCh
00401077 rep stos dword ptr [edi]
00401079 pop ecx
0040107A mov dword ptr [ebp-4],ecx
15: return 3;
0040107D mov eax,3
16: }
00401082 pop edi
00401083 pop esi
00401084 pop ebx
00401085 mov esp,ebp
00401087 pop ebp
00401088 ret
综上,构造函数并不是总会存在的。
从反汇编的角度看C++语法(构造函数)相关推荐
- 编译器角度看C++复制构造函数
[C++对象模型]复制构造函数的建构操作 关于复制构造函数的简单介绍,可以看我以前写过的一篇文章C++复制控制之复制构造函数该文章中介绍了复制构造函数的定义.调用时机.也对编译器合成的复制构造函数行为 ...
- 从JDK源码角度看Long
概况 Java的Long类主要的作用就是对基本类型long进行封装,提供了一些处理long类型的方法,比如long到String类型的转换方法或String类型到long类型的转换方法,当然也包含与其 ...
- 从一个程序员的角度看——微信小应用
前言: 最近初步了解了一下微信小应用,APP端的同事也非常感兴趣,于是在公司内部做了一个小小的分享,分享的过程中有很多讨论内容,大家也是非常感兴趣和有自己的看法,当时"混乱"的场面 ...
- 公司技术管理角度看C++游戏程序员发展
公司技术管理角度看C++游戏程序员发展 H3D 这是我多年来招聘培训游戏程序员的一点想法.一直想汇总一下.主要目的是为了更好的对公司新进C++程序员进行培训,并且建立起游戏程序员培训,发展,成才,成为 ...
- 从程序员角度看ELF
从程序员角度看ELF 原文:< ELF:From The Programmer's Perspective> 作者:Hongjiu Lu <mailto: hjl@nynexst.c ...
- go conn 读取byte数组后是否要_【技术推荐】正向角度看Go逆向
Go语言具有开发效率高,运行速度快,跨平台等优点,因此正越来越多的被攻击者所使用,其生成的是可直接运行的二进制文件,因此对它的分析类似于普通C语言可执行文件分析,但是又有所不同,本文将会使用正向与逆向 ...
- 2015年《大数据》高被引论文Top10文章No.2——大数据时代的数据挖掘 —— 从应用的角度看大数据挖掘(下)...
2015年<大数据>高被引论文Top10文章展示 [编者按]本刊将把2015年<大数据>高被引论文Top10的文章陆续发布,欢迎大家关注!本文为高被引Top10论文的No.2, ...
- 【2015年第4期】大数据时代的数据挖掘 —— 从应用的角度看大数据挖掘(下)...
大数据时代的数据挖掘 -- 从应用的角度看大数据挖掘(下) 李 涛1,2,曾春秋1,2,周武柏1,2,周绮凤3,郑 理1,2 1. 南京邮电大学计算机学院 南京 210023:2. 美国佛罗里达国际大 ...
- 从用户的角度看 c语言中函数有两种,【南开大学】20秋学期(1709、1803、1809、1903、1909、2003、2009 )《C语言程序设计》在线作业答卷...
20秋学期(1709.1803.1809.1903.1909.2003.2009 )<C语言程序设计>在线作业 试卷总分:100 得分:100 一.单选题 (共 40 道试题,共 80 ...
最新文章
- 微信小程序实例开发教程之知乎新闻
- Fedora 19配置心得
- sobol敏感性分析 matlab代码
- oracle 存储过程 输入,Oracle 存储过程加密方法
- 官方首次披露,TDSQL十年自主可控之路(附PDF)
- 初一七年级计算机信息全册教案,新川教版七年级信息技术全册教案(全册)
- SIEM比以往更重要的5个原因
- Linux 发展历史
- thinkpad解决Win8.1电源管理的方法
- 圆柱体积计算机公式,圆柱体积计算公式
- TypeError: list indices must be integers or slices, not float
- 嵌入式开发培训靠谱吗,嵌入式开发培训怎么样?
- python之selenium爬取数据(爬取airbnb房源信息)
- 在Python中操作谷歌浏览器
- 科研伦理与学术规范期末考试1题库
- ddt数据驱动 python接口 xls_013 python接口 数据驱动ddt
- c624芯片组的服务器,技嘉另类的服务器主板C422芯片组
- python计算长方体体积最简单代码_C语言编程简单的小程序,计算长方体体积!...
- Python实现Catboost分类模型(CatBoostClassifier算法)项目实战
- 移动端H5常见问题以及解决方案
热门文章
- 【LeetCode】860. 柠檬水找零(C语言)
- ieee下载文献的方法
- 小苹果软件_游戏拼音魔卡动画教学软件使用说明书
- 【Python黑科技】tkinter库实战制作一个计算器(保姆级图文+实现代码)
- 实时渲染:Tone Mapping 色调映射
- JAVA计算两个日期相差天、时、分、秒方法
- 如何用计算机打出妈妈我爱你,母亲节快乐!教你用30种语言说“妈妈我爱你”...
- 海康网络摄像机如何配置网络硬盘
- 知道焊缝长度如何确定节点板尺寸_节点板厚根据什么确定
- 影视专家热议新媒体时代如何加强电影新建设