C++逆向第十一课-----结构体和类

    xiaoxiao2021-03-25  87

    0x00 C++ 结构体和类的对齐值

    在这里我们以VC6.0编译器的对齐策略为准 在VC6.0中对应调整对齐值的编译选项为/ZP 默认对齐值为8

    对于C++类和结构体的对齐值申请空间时候会遵守两条规则。

    规则一:当前成员对齐值 = min(当前成员大小,指定对齐值),并且地址还要为对齐值得倍数值规则二:结构体整体对齐值 = min(数据成员大小最大值,指定对齐值)

    举例说明

    情况一:简单的结构体

    stuct{ double dDouble; +0 int nInt; +8 short sShort; +12 } +16

    解析: 第一个成员为double,大小为8,指定对齐值为8,取两者最小值,所以第一个数据成员的对齐值为8,结构体内偏移为0 第二个数据成员为int,大小为4,指定的对齐值为8,所以第二个数据对齐值为4,结构体内偏移为8 第三个数据成员为short,大小为2,指定的对齐值为8,所以第三个数据对齐值为2,结构体内偏移为12

    综上,结构体的大小为14,但是,还要求结构体的整体对齐值:结构体中最大的数据类型为double,大小为8 ,指定的对齐值为8,求二者最小值为8,所以结构体整体对齐值为8,所以14字节补上两字节对齐,总体大小为16.

    情况二:结构体中有数组

    struct{ char cChar; //0 int nArray[4]; //4 short sShort; //20 }

    数组的对齐值依然按照数组类型的大小定义,所以上例子中数组对齐值为4,占用大小为16字节,结构体总大小为24

    情况三:结构体中有结构体

    stuct tagTest1{ double dDouble; +0 int nInt; +8 short sShort; +12 } stuct tagTest2{ tagTest1 tagtest; +0 int nInt; +16 short sShort; +12 }

    在上面这个例子中tagTest2中定义了tagTest1的成员变量,这时候变量tagtest的对齐值并不是以tagTest2的大小为对齐值,而是以tagTest2中最大的成员变量的大小为对齐值,所以就为8。

    0x01 this指针

    在调用成员方法的时候,以及取出数据成员的时候,编译器做了一个小动作,利用寄存器ecx保存了对象的首地址,并且以寄存器的方式传递到成员函数中,这就是this指针的由来,这样的调用约定称为thiscall。

    thiscall的栈平衡方式与__stdcall相同。

    0x02 构造和析构

    识别构造函数的必要条件

    This指针传递给ecx构造函数是这个对象进入作用域的第一个成员函数调用。返回值为this指针,做返回值检查,相当于new的返回值

    识别析构函数的必要条件

    对象出作用域的最后一个调用未定义返回值Thiscall

    注意:调用约定对析构和构造无效

    转载请注明原文地址: https://ju.6miu.com/read-15538.html

    最新回复(0)