首页 > 编程语言 > 详细

C++ 语言反汇编-类的反汇编

时间:2020-04-25 14:33:59      阅读:69      评论:0      收藏:0      [点我收藏+]

反汇编就是将机器指令翻译为汇编指令的过程,编译器在编译时会将高级语言降级并转换为对应的机器指令,反汇编就是将机器指令汇编的过程,通过阅读汇编代码,我们可以更好的理解程序逻辑,从而推测出程序运作机理,下面的案例将使用VS2013 Express版本的编译器进行编译.

c语言使用printf函数输出,printf函数的输出方式很好理解,反汇编后会发现代码不过就那么几句,而C++则不同,C++输出数据时,使用了一种流的输出方式,通常是调用 ostream 类里面的cin或者是cout,你可以把输入输出理解为小河流水,如下反汇编代码,先来观察一下输出格式的变化。

#include <iostream>
#include <string>

using namespace std;

int main(int argc, char* argv[])
{
	int number =100 ;
	int age = 33;

	std::cin >> number >> age;
	std::cout << "number: " << number << "age: "<< age << std::endl;

	system("pause");
	return 0;
}

cin接收参数看起来是这样

00415ED4 | 8D4D F8                  | lea ecx,dword ptr ss:[ebp-0x8]                                                        |
00415ED7 | 51                       | push ecx                                                                              |
00415ED8 | 8B0D A8004200            | mov ecx,dword ptr ds:[<&?cin@std@@3V?$basic_istream@DU?$char_traits@D@std@@@1@A>]     | 获取cin地址
00415EDE | FF15 A4004200            | call dword ptr ds:[<&??5?$basic_istream@DU?$char_traits@D@std@@@std@@QAEAAV01@AAH@Z>] | 第一次cin接收参数
00415EE4 | 3BFC                     | cmp edi,esp                                                                           |
00415EE6 | E8 53B4FFFF              | call 0x41133E                                                                         |
00415EEB | 8BC8                     | mov ecx,eax                                                                           |
00415EED | FF15 A4004200            | call dword ptr ds:[<&??5?$basic_istream@DU?$char_traits@D@std@@@std@@QAEAAV01@AAH@Z>] | 第二次cin接收参数
00415EF3 | 3BF4                     | cmp esi,esp                                                                           |
00415EF5 | E8 44B4FFFF              | call 0x41133E                                                                         |

cout打印参数也是如此。。

00415F12 | 68 84CC4100              | push consoleapplication2.41CC84                                                       | 41CC84:"number: "
00415F17 | 8B15 AC004200            | mov edx,dword ptr ds:[<&?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A>]    | 获取cout地址
00415F1D | 52                       | push edx                                                                              |
00415F1E | E8 94B3FFFF              | call 0x4112B7                                                                         |
00415F23 | 83C4 08                  | add esp,0x8                                                                           |
00415F26 | 8BC8                     | mov ecx,eax                                                                           |
00415F28 | FF15 98004200            | call dword ptr ds:[<&??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@H@Z>]   | 输出第一个参数
00415F2E | 3BDC                     | cmp ebx,esp                                                                           |
00415F30 | E8 09B4FFFF              | call 0x41133E                                                                         |
00415F35 | 50                       | push eax                                                                              |
00415F36 | E8 7CB3FFFF              | call 0x4112B7                                                                         |
00415F3B | 83C4 08                  | add esp,0x8                                                                           |
00415F3E | 8BC8                     | mov ecx,eax                                                                           |
00415F40 | FF15 98004200            | call dword ptr ds:[<&??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@H@Z>]   | 输出第二个参数
00415F46 | 3BFC                     | cmp edi,esp                                                                           |
00415F48 | E8 F1B3FFFF              | call 0x41133E                                                                         |
00415F4D | 8BC8                     | mov ecx,eax                                                                           |
00415F4F | FF15 94004200            | call dword ptr ds:[<&??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@P6AAAV0 | 结束cout

ida 也同样可识别出来。

技术分享图片

分析类的实现原理

在C语言中我们学习过结构体类型,其实C++中的类就是在结构体这个数据类型的基础上衍生出来的,两者之间的反汇编代码几乎一致,结构体和类都具有构造函数,析构函数和成员函数,但两者之间还是会有细微的不同,首先结构体的访问控制默认是Public,而类的访问控制是Private,这些属性是由编译器在编译的时候进行检查和确认的,一旦编译成功,程序在执行过程中就不会在访问控制方面做任何检查和限制了.

简单地定义一个类: 首先我们来定义一个Student学生类,然后赋予不同的属性,最后调用内部的成员函数,观察其反汇编代码.

#include <iostream>
using namespace std;

class Student
{
	public:
		int number;
		char *name;

	private: void p_display()
	{
				 std::cout << "name:" << name << std::endl;
	}
	public:void display()
	{
			   p_display();
			   std::cout << "num: " << number << std::endl;
	}
};

int main(int argc, char* argv[])
{
	Student student;
	student.number = 22;
	student.name = "lyshark";

	student.display();
	system("pause");
	return 0;
}

通过反汇编这段代码,你会发现其实类这个东西并不存在于汇编层面,因为所谓的面向对象其实都是编译器来帮你映射成相应的C语言代码,换句话说,其实并不存在面向对象,你所写的面向对象代码最终都会被编译器降级为C语言代码,然后C代码又会被降级为机器指令,而中间的转换过程都是由编译器来完成的,只不过面向对象更易于使用,但是其本质上还是C代码.

008E12A6 | 68 E0198E00              | push <class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl std::en | main.cpp:27
008E12AB | 51                       | push ecx                                                                              | ecx:&"ALLUSERSPROFILE=C:\\ProgramData"
008E12AC | 8B0D 54308E00            | mov ecx,dword ptr ds:[<&?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A>]    | ecx:&"ALLUSERSPROFILE=C:\\ProgramData"
008E12B2 | BA BC318E00              | mov edx,consoleapplication2.8E31BC                                                    | 8E31BC:"name:"
008E12B7 | E8 E4040000              | call <class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl std::op |
008E12BC | BA CC318E00              | mov edx,consoleapplication2.8E31CC                                                    | 8E31CC:"lyshark"
008E12C1 | 8BC8                     | mov ecx,eax                                                                           | ecx:&"ALLUSERSPROFILE=C:\\ProgramData"
008E12C3 | E8 D8040000              | call <class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl std::op |
008E12C8 | 83C4 04                  | add esp,0x4                                                                           |
008E12CB | 8BC8                     | mov ecx,eax                                                                           | ecx:&"ALLUSERSPROFILE=C:\\ProgramData"
008E12CD | FF15 5C308E00            | call dword ptr ds:[<&??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@P6AAAV0 |
008E12D3 | 8B0D 54308E00            | mov ecx,dword ptr ds:[<&?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A>]    | ecx:&"ALLUSERSPROFILE=C:\\ProgramData"
008E12D9 | BA C4318E00              | mov edx,consoleapplication2.8E31C4                                                    | 8E31C4:"num: "
008E12DE | 68 E0198E00              | push <class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl std::en |
008E12E3 | 6A 16                    | push 0x16                                                                             |
008E12E5 | E8 B6040000              | call <class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl std::op |
008E12EA | 8BC8                     | mov ecx,eax                                                                           | ecx:&"ALLUSERSPROFILE=C:\\ProgramData"
008E12EC | FF15 34308E00            | call dword ptr ds:[<&??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@H@Z>]   |
008E12F2 | 8BC8                     | mov ecx,eax                                                                           | ecx:&"ALLUSERSPROFILE=C:\\ProgramData"
008E12F4 | FF15 5C308E00            | call dword ptr ds:[<&??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@P6AAAV0 |
008E12FA | 68 D4318E00              | push consoleapplication2.8E31D4                                                       | main.cpp:29, 8E31D4:"pause"==L"慰獵e"
008E12FF | FF15 E0308E00            | call dword ptr ds:[<&system>]                                                         |
008E1305 | 83C4 04                  | add esp,0x4                                                                           

IDA 的识别更能说明这一点。

技术分享图片

未完待续.......

C++ 语言反汇编-类的反汇编

原文:https://www.cnblogs.com/LyShark/p/12771924.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!