当前位置:网站首页>The underlying mechanism of the class
The underlying mechanism of the class
2022-08-05 05:05:00 【Chicken Island~】
提出问题:
- Why class function calling convention must bethis call
- 为什么静态成员函数没有this指针
- 为什么类的静态成员函数不能访问类的非静态成员函数
- Do classes really have constructors?
C++代码
class T {
int hp;
public:
int Add(int a, int b) {
return hp + a + b;
}
};
int main(int count, char** args)
{
T t1;
t1.Add(100, 200);
}
汇编代码
00241034 push 0C8h
00241039 push 64h
0024103B lea ecx,[ebp-4]
0024103E call 00241000
00241000 55 push ebp
00241001 8B EC mov ebp,esp
00241003 51 push ecx
00241004 89 4D FC mov dword ptr [ebp-4],ecx //ecxvalue becomes a local variable
00241007 8B 45 FC mov eax,dword ptr [ebp-4]
0024100A 8B 00 mov eax,dword ptr [eax] //this->hp
0024100C 03 45 08 add eax,dword ptr [ebp+8]
0024100F 03 45 0C add eax,dword ptr [ebp+0Ch]
00241012 8B E5 mov esp,ebp
00241014 5D pop ebp
00241015 C2 08 00 ret 8
设计实验:
when the function is usedthis->hp时,ecxwill be used to store类的首地址
when the function is not usedthis->hp时,ecxwill also be used to store类的首地址
发现规律:当调用类的成员函数的时候,ecxwill store the first address of the class,will then be treated as局部变量来使用
得出结论
_thiscall 是C++中 When accessing a member function of a class Defined function calling convention
(1) 寄存器ecxpointer to store the class
(2) 参数由右到左入栈
(3) 堆栈由 被调用者 负责恢复
All non-static member functions of a class can be usedthis指针,thisA pointer is essentially a pointer in an object through a registerecxto pass into member functions,So member functions in a class access its member variables,through pointers+offset to access the,whether or not explicitly usedthis指针
设计实验
C++代码
class T {
inline static int count;
public:
static int GetCount(int a, int b) {
count++;
return 2;
}
};
int main(int count, char** args)
{
T t1;
t1.GetCount(2, 3);
汇编代码
00D31023 6A 03 push 3
00D31025 6A 02 push 2
00D31027 E8 D4 FF FF FF call T::GetCount (0D31000h)
00D3102C 83 C4 08 add esp,8**
count++;
00A21003 A1 28 31 A2 00 mov eax,dword ptr ds:[00A23128h]
00A21008 83 C0 01 add eax,1
00A2100B A3 28 31 A2 00 mov dword ptr ds:[00A23128h],eax
得出结论:
类的静态成员函数,essentially adopted_cdecl约定
(1)参数由右到左入栈
(2) 由[调用者]restore stack balance
答:Because a static member function of a class is essentially an ordinary function,So no pointer to the object is passed at all,Therefore, it cannot access its member variables.;
The static member variable of the class is essentially equivalent to a global variable,有固定的内存地址,Has nothing to do with class objects,So a static member of a class can be passed without an instance of the class[类::静态成员]access in this form
设计实验:
int hp{
1};
发现规律:
- 当int hp{1}时,The disassembled code calls the constructor,The purpose of the call is to make给hp赋值
- 当int hp 时,Disassembled code doesn't call constructor
得出结论:
类TMost of the time there is no constructor,这是因为C++The standards committee requires every class to have a default constructor.
But an empty constructor actually don't have any meaning,So in some cases the compiler will delete meaningless constructors,这是编译器优化的结果.
原则上来讲,Every class has a default constructor.
提出问题:
- 为什么AIM的大小为8个字节?
- p->Die()is how to ensure that the call isWOLF里面的Die()
class AIM {
public :
int HP;
virtual void Eat() {
std::cout << "AIM" << std::endl;
}
virtual void Die() {
std::cout << "AIM-DIE" << std::endl;
}
};
class WOLF :public AIM{
public:
virtual void Eat() {
std::cout << "WOLF" << std::endl;
}
virtual void Die() {
std::cout << "WOLF-DIE" << std::endl;
}
void Sound() {
std::cout << "aoaoaoaoaoaoao!!!!" << std::endl;
}
};
int main(int count, char** args)
{
AIM* p = new WOLF();
p->Die();
std::cout << sizeof(AIM) << std::endl;
}
猜测+实证:AIMThe class should storea four-byte address,through it you can goaccess the address of a virtual function.Through the following print statement, we can see that the four bytes are placed in theAIM类的首地址
std::cout << p << " " << &p << std::endl;
问题2猜测:调用p->Die()function will be passed存储了WOLFpointer to the address of the virtual function of the class进去,然后计算出对应的虚函数地址
实证:逆向分析
[ebp-4]里面的地址→eax
eaxthe memory address inside前四个字节→edx
[edx+4]这个内存地址的前四个字节→ eax
p->Die();
00D11A5D 8B 45 FC mov eax,dword ptr [p]
00D11A60 8B 10 mov edx,dword ptr [eax]
00D11A62 8B 4D FC mov ecx,dword ptr [p]
00D11A65 8B 42 04 mov eax,dword ptr [edx+4]
00D11A68 FF D0 call eax
发现规律:
- 虚函数的地址will be placed in a virtual table
- 这个虚表的地址会被放在类的首地址,当我们通过指针调用虚函数will pass the virtual table when计算out this address,然后执行
直接构建
std::cout << std::hex << "vtable地址:" << pTable[0] << std::endl;
int* func = (int*)pTable[0];
std::cout << std::hex << "Eat地址:" << func[0] << std::endl;
std::cout << std::hex << "Die地址:" << func[1] << std::endl;
unsigned* eat = (unsigned*)func[1];
__asm {
call eat
}
得出结论
(1)Multiple instances of the same class all point to the same virtual function table
(2)The virtual function table is called only if the virtual function is accessed through a pointer
边栏推荐
- 【学习笔记之菜Dog学C】动态内存管理之经典笔试题
- C language - vernacular to understand the original code, inverse code and complement code
- How to deal with DNS hijacking?
- dedecms error The each() function is deprecated
- 『递归』递归概念与典型实例
- 【学生毕业设计】基于web学生信息管理系统网站的设计与实现(13个页面)
- Detailed explanation of each module of ansible
- 类的底层机制
- 【cesium】Load and locate 3D Tileset
- 判断语句_switch与case
猜你喜欢
一篇博客通关Redis技术栈
浅析主流跨端技术方案
WPF中DataContext作用
【cesium】加载并定位 3D Tileset
Excel Paint
逆向理论知识4
MySQL Foundation (1) - Basic Cognition and Operation
LeetCode:1403. 非递增顺序的最小子序列【贪心】
8.04 Day35-----MVC three-tier architecture
The solution to the failure to read channel information when dedecms generates a message in the background
随机推荐
[8.2] Code Source - [Currency System] [Coins] [New Year's Questions (Data Enhanced Edition)] [Three Stages]
【转】什么是etcd
Flutter学习-开篇
In the hot summer, teach you to use Xiaomi smart home accessories + Raspberry Pi 4 to connect to Apple HomeKit
虚证、实证如何鉴别?
Day019 方法重写与相关类的介绍
仪表板展示 | DataEase看中国:数据呈现中国资本市场
[Nine Lectures on Backpacks - 01 Backpack Problems]
作业8.4 进程间的通信 管道与信号
University Physics---Particle Kinematics
【informix】解决启动报错大全,以及解决办法
MySQL Foundation (1) - Basic Cognition and Operation
大学物理---质点运动学
creo怎么测量点到面的距离
淘宝账号如何快速提升到更高等级
Flutter learning 2-dart learning
判断语句_switch与case
动力小帆船制作方法简单,电动小帆船制作方法
雷克萨斯lm的安全性到底体现在哪里?一起来看看吧
Learning and finishing of probability theory 8: Geometric and hypergeometric distributions