构造函数的识别
来源:互联网 发布:mysql联合主键怎么设置 编辑:程序博客网 时间:2024/06/01 14:49
1.局部对象
CNumber Number;00408F7D 8D 4D EC lea ecx,[Number] ;this指针的来源 对象的首地址00408F80 E8 AA B0 FF FF call CNumber::CNumber (040402Fh) ;调用构造函数 先到跳转表
CNumber();栈操作00408900 55 push ebp 00408901 8B EC mov ebp,esp 00408903 81 EC CC 00 00 00 sub esp,0CCh 00408909 53 push ebx 0040890A 56 push esi 0040890B 57 push edi 0040890C 51 push ecx 0040890D 8D BD 34 FF FF FF lea edi,[ebp-0CCh] 00408913 B9 33 00 00 00 mov ecx,33h 00408918 B8 CC CC CC CC mov eax,0CCCCCCCCh 0040891D F3 AB rep stos dword ptr es:[edi] ;主体部分0040891F 59 pop ecx 00408920 89 4D F8 mov dword ptr [this],ecx ;this指针始出面 { m_nNumber = 1;00408923 8B 45 F8 mov eax,dword ptr [this] 00408926 C7 00 01 00 00 00 mov dword ptr [eax],1 ;这就很奇怪了哈 这是绕了两个弯啊 特征无疑 }0040892C 8B 45 F8 mov eax,dword ptr [this] ;还有这里 完全是程式化的多此一举 0040892F 5F pop edi 00408930 5E pop esi 00408931 5B pop ebx 00408932 8B E5 mov esp,ebp 00408934 5D pop ebp 00408935 C3 ret
2.堆对象
CNumber * pNumber = NULL;00408F7D C7 45 EC 00 00 00 00 mov dword ptr [pNumber],0 pNumber = new CNumber[4];00408F84 6A 14 push 14h ;类的大小00408F86 E8 F8 A7 FF FF call operator new[] (0403783h) 00408F8B 83 C4 04 add esp,4 00408F8E 89 85 FC FE FF FF mov dword ptr [ebp-104h],eax ;保存new返回值的临时变量00408F94 C7 45 FC 00 00 00 00 mov dword ptr [ebp-4],0 ;保存申请空间的次数00408F9B 83 BD FC FE FF FF 00 cmp dword ptr [ebp-104h],0 ;判断堆空间是否申请成功00408FA2 74 3A je main+9Eh (0408FDEh) ;失败则跳过构造函数;构造函数00408FA4 8B 85 FC FE FF FF mov eax,dword ptr [ebp-104h] 00408FAA C7 00 04 00 00 00 mov dword ptr [eax],4 00408FB0 68 9B 3D 40 00 push offset CNumber::~CNumber (0403D9Bh) 00408FB5 68 2F 40 40 00 push offset CNumber::CNumber (040402Fh) 00408FBA 6A 04 push 4 00408FBC 6A 04 push 4 00408FBE 8B 8D FC FE FF FF mov ecx,dword ptr [ebp-104h] 00408FC4 83 C1 04 add ecx,4 00408FC7 51 push ecx 00408FC8 E8 9C 8F FF FF call `eh vector constructor iterator' (0401F69h);堆对象代理函数; eh vector constructor iterator(pArrayAddress, sizeof(object), object_count, ;pFunConstructor, pFunDestructor)其中 pFunDestructor为析构函数, pFunConstructor为构造函数,;object_count为对象数量, sizeof(object)为对象大小,pArrayAddress为起始地址。5个参数的函数并不多啊00408FCD 8B 95 FC FE FF FF mov edx,dword ptr [ebp-104h] ;this指针00408FD3 83 C2 04 add edx,4 00408FD6 89 95 C4 FE FF FF mov dword ptr [ebp-13Ch],edx 00408FDC EB 0A jmp main+0A8h (0408FE8h) ;申请堆空间失败00408FDE C7 85 C4 FE FF FF 00 00 00 00 mov dword ptr [ebp-13Ch],0 ;this指针倒啊倒00408FE8 8B 85 C4 FE FF FF mov eax,dword ptr [ebp-13Ch] ;this指针00408FEE 89 85 08 FF FF FF mov dword ptr [ebp-0F8h],eax 00408FF4 C7 45 FC FF FF FF FF mov dword ptr [ebp-4],0FFFFFFFFh 00408FFB 8B 8D 08 FF FF FF mov ecx,dword ptr [ebp-0F8h] 00409001 89 4D EC mov dword ptr [pNumber],ecx pNumber->m_nNumber = 2;00409004 8B 45 EC mov eax,dword ptr [pNumber] ;一个this指针传出花来了00409007 C7 00 02 00 00 00 mov dword ptr [eax],2 printf("%d \r\n", pNumber->m_nNumber);0040900D 8B 45 EC mov eax,dword ptr [pNumber] 00409010 8B 08 mov ecx,dword ptr [eax] 00409012 51 push ecx 00409013 68 14 C0 49 00 push offset string "%d \r\n" (049C014h) 00409018 E8 9C AD FF FF call _printf (0403DB9h) 0040901D 83 C4 08 add esp,8
3.参数对象:
1.浅拷贝:如没有定义拷贝构造函数,编译器会对原对象与拷贝对象中的各数据成员直接进行数据复制,称为默认拷贝构造函数,属浅拷贝。
CNumber one;004090EA 8D 4D D4 lea ecx,[one] 004090ED E8 3D AF FF FF call CNumber::CNumber (040402Fh) 004090F2 C7 45 FC 02 00 00 00 mov dword ptr [ebp-4],2 CNumber two(one);004090F9 8B 45 D4 mov eax,dword ptr [one] 004090FC 89 45 C8 mov dword ptr [two],eax 004090FF C6 45 FC 03 mov byte ptr [ebp-4],3
2.深拷贝
CMyString MyString;00416273 8D 4D BC lea ecx,[MyString] 00416276 E8 4E DA FE FF call CMyString::CMyString (0403CC9h) 0041627B C6 45 FC 04 mov byte ptr [ebp-4],4 MyString.SetString("Hello");0041627F 68 1C C0 49 00 push offset string "Hello" (049C01Ch) 00416284 8D 4D BC lea ecx,[MyString] 00416287 E8 37 D1 FE FF call CMyString::SetString (04033C3h) Show(MyString);0041628C 51 push ecx ;这里的作用是sub esp,4 主要因为MyString的类型长度为4 push ecx更短更快, 如果长度是其他值 ;这里是要变成 sub esp,sizeof(MyString)用来保存参数对象0041628D 8B CC mov ecx,esp ;保存参数对象的地址0041628F 89 A5 9C FE FF FF mov dword ptr [ebp-164h],esp ;保存参数对象的地址00416295 8D 45 BC lea eax,[MyString] ;取对象地址 00416298 50 push eax 00416299 E8 9E CB FE FF call CMyString::CMyString (0402E3Ch) ;调用构造函数0041629E 89 85 94 FE FF FF mov dword ptr [ebp-16Ch],eax 004162A4 E8 D9 C1 FE FF call Show (0402482h) 004162A9 83 C4 04 add esp,4
CMyString(CMyString& obj){;栈操作00408800 55 push ebp 00408801 8B EC mov ebp,esp 00408803 81 EC E4 00 00 00 sub esp,0E4h 00408809 53 push ebx 0040880A 56 push esi 0040880B 57 push edi 0040880C 51 push ecx 0040880D 8D BD 1C FF FF FF lea edi,[ebp-0E4h] 00408813 B9 39 00 00 00 mov ecx,39h 00408818 B8 CC CC CC CC mov eax,0CCCCCCCCh 0040881D F3 AB rep stos dword ptr es:[edi] ;拷贝构造函数主体0040881F 59 pop ecx 00408820 89 4D F8 mov dword ptr [this],ecx int nLen = strlen(obj.m_pString);00408823 8B 45 08 mov eax,dword ptr [obj] 00408826 8B 08 mov ecx,dword ptr [eax] 00408828 51 push ecx int nLen = strlen(obj.m_pString);00408829 E8 DD 95 FF FF call _strlen (0401E0Bh) 0040882E 83 C4 04 add esp,4 00408831 89 45 EC mov dword ptr [nLen],eax this->m_pString = new char[nLen + sizeof(char)];00408834 8B 45 EC mov eax,dword ptr [nLen] 00408837 83 C0 01 add eax,1 0040883A 50 push eax 0040883B E8 43 AF FF FF call operator new[] (0403783h) 00408840 83 C4 04 add esp,4 00408843 89 85 20 FF FF FF mov dword ptr [ebp-0E0h],eax 00408849 8B 4D F8 mov ecx,dword ptr [this] 0040884C 8B 95 20 FF FF FF mov edx,dword ptr [ebp-0E0h] 00408852 89 11 mov dword ptr [ecx],edx strcpy(this->m_pString, obj.m_pString);00408854 8B 45 08 mov eax,dword ptr [obj] 00408857 8B 08 mov ecx,dword ptr [eax] 00408859 51 push ecx 0040885A 8B 55 F8 mov edx,dword ptr [this] 0040885D 8B 02 mov eax,dword ptr [edx] 0040885F 50 push eax 00408860 E8 05 96 FF FF call _strcpy (0401E6Ah) 00408865 83 C4 08 add esp,8 }00408868 8B 45 F8 mov eax,dword ptr [this] ;返回this指针0040886B 5F pop edi 0040886C 5E pop esi 0040886D 5B pop ebx 0040886E 81 C4 E4 00 00 00 add esp,0E4h 00408874 3B EC cmp ebp,esp 00408876 E8 F4 9A FF FF call __RTC_CheckEsp (040236Fh) 0040887B 8B E5 mov esp,ebp 0040887D 5D pop ebp 0040887E C2 04 00 ret 4
class CMyString{public: CMyString(){ m_pString = NULL; } CMyString(CMyString& obj){ // 注:如在拷贝构造中这样拷贝指针,仍然属于浅拷贝,并没有拷贝指针所指向的 // 堆空间中的数据制作副本,仍然会造成错误。 // this->m_pString = obj.m_pString; int nLen = strlen(obj.m_pString); this->m_pString = new char[nLen + sizeof(char)]; strcpy(this->m_pString, obj.m_pString); } ~CMyString(){ if (m_pString != NULL) { delete [] m_pString; m_pString = NULL; } } void SetString(char * pString){ int nLen = strlen(pString); if (m_pString != NULL) { delete [] m_pString; m_pString = NULL; } m_pString = new char[nLen + sizeof(char)]; strcpy(m_pString, pString); } char * m_pString;};
0 0
- 构造函数的识别
- 一个将类的构造函数调用识别成函数指针的问题
- 逆向 C++-- 识别类及其构造函数
- 识别合法的构造方法
- 构造函数的构造顺序
- main函数的识别
- 成员函数的识别
- 构造函数中显式的调基类构造函数
- 构造函数、拷贝构造函数的运用
- 类的构造函数、拷贝构造函数
- String的构造函数拷贝构造函数
- 【构造函数】解析构造函数的作用
- WebService的构造函数
- 类的构造函数
- private的构造函数
- C#的构造函数
- 类的构造函数
- 构造函数 的protected
- Cookie和Session的区别
- 网络令牌的解释
- 周三项目4--顺序表应用
- 编译和解释的区别是什么?来看看
- 初学java,对3+1层架构的一些简单理解:MVC+S
- 构造函数的识别
- 你知道为什么Android手机总是越用越慢?
- CSDN 深度学习优质内容
- CSS概述和选择器及优先级
- 16 增删改查取联系人
- lightoj 1008 - Fibsieve`s Fantabulous Birthday(简单模拟)
- EventBus使用详解
- Android应用程序访问linux驱动第一步:实现并测试Linux驱动
- Python基础-String字符串