逆向程序分析:C++的一个空类,为什么在内存中占1字节
Posted CodeBowl
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了逆向程序分析:C++的一个空类,为什么在内存中占1字节相关的知识,希望对你有一定的参考价值。
普通的空类
空类的定义
空类就是没有任何数据成员的类。
空类的内存大小
按道理讲,没有数据成员,就不会占用内存,那么空类的大小就为0。
但是真实场景下,即便是空类在内存中,也占一个字节。
#include <iostream>
class CPeople
{
};
int main()
{
std::cout << "sizeof(CPeople): " << sizeof(CPeople) << std::endl;
CPeople *v1;
return 0;
}
输出结果为:
sizeof(CPeople): 1
为了对比,我们建一个新类,里面增加一个数据成员。
#include <iostream>
class A
{
};
class B
{
int i;
};
int main()
{
std::cout << "sizeof(A): " << sizeof(A) << std::endl;
std::cout << "sizeof(B): " << sizeof(B) << std::endl;
return 0;
}
输出结果为:
sizeof(A): 1
sizeof(B): 4
为什么呢?
从其他地方看到的解释:
C++标准指出,
不允许一个对象(当然包括类对象)的大小为0,不同的对象不能具有相同的地址。
这是由于:
new需要分配不同的内存地址,不能分配内存大小为0的空间
避免除以 sizeof(T)时得到除以0错误 故使用一个字节来区分空类。
带有虚函数的空类
虚类空类在内存中的大小
给空类A加一个虚成员函数,那么这个类也变成了虚类。
#include <iostream>
class A
{
public:
virtual int a() {
}
};
class B
{
public:
virtual int b() { }
int i;
};
int main()
{
std::cout << "sizeof(A): " << sizeof(A) << std::endl;
std::cout << "sizeof(B): " << sizeof(B) << std::endl;
return 0;
}
输出结果:
sizeof(A): 4
sizeof(B): 8
为什么?
因为,虚类中有一个虚表存放着虚函数的地址,虚类对象调用虚函数的时候,是通过虚表指针去寻址的,所以内存中存放着虚表指针,在32位下,占4字节。
A::A:
00A716E0 55 push ebp
00A716E1 8B EC mov ebp,esp
00A716E3 81 EC CC 00 00 00 sub esp,0CCh
00A716E9 53 push ebx
00A716EA 56 push esi
00A716EB 57 push edi
00A716EC 51 push ecx
00A716ED 8D BD 34 FF FF FF lea edi,[ebp-0CCh]
00A716F3 B9 33 00 00 00 mov ecx,33h
00A716F8 B8 CC CC CC CC mov eax,0CCCCCCCCh
00A716FD F3 AB rep stos dword ptr es:[edi]
00A716FF 59 pop ecx
00A71700 89 4D F8 mov dword ptr [this],ecx
00A71703 8B 45 F8 mov eax,dword ptr [this]
00A71706 C7 00 34 6B A7 00 mov dword ptr [eax],offset A::`vftable' (0A76B34h)
00A7170C 8B 45 F8 mov eax,dword ptr [this]
00A7170F 5F pop edi
00A71710 5E pop esi
00A71711 5B pop ebx
00A71712 8B E5 mov esp,ebp
00A71714 5D pop ebp
00A71715 C3 ret
以上是关于逆向程序分析:C++的一个空类,为什么在内存中占1字节的主要内容,如果未能解决你的问题,请参考以下文章
Windows 逆向CheatEngine 工具 ( 汉化版 CE 工具推荐 | 编写简单 C++ 程序 | C++ 程序执行分析 | 使用 CE 修改上述 C++ 程序 )