Day8:thiscall、类

thiscall、类

调用约定:thiscall

  • 对于C++this指针的特性,有一种专门的调用约定叫thiscall,主要用于类出现的场景
  • 无论x86/x64,this指针均由ecx/rcx扮演,指向对象的内存地址
  • thiscall由被调用者清理参数占用的栈空间

类(一)

  • 简单的构造析构分析

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    ;main函数
    .text:004641E0 var_EC = dword ptr -0ECh
    .text:004641E0 var_30 = byte ptr -30h
    .text:004641E0 var_20 = dword ptr -20h
    .text:004641E0 var_4 = dword ptr -4
    .text:004641E0
    .text:004641E0 push ebp
    .text:004641E1 mov ebp, esp
    .text:004641E3 sub esp, 0F0h
    .text:004641E9 push ebx
    .text:004641EA push esi
    .text:004641EB push edi
    .text:004641EC lea edi, [ebp+var_30]
    .text:004641EF mov ecx, 0Ch
    .text:004641F4 mov eax, 0CCCCCCCCh
    .text:004641F9 rep stosd
    .text:004641FB mov eax, ___security_cookie
    .text:00464200 xor eax, ebp
    .text:00464202 mov [ebp+var_4], eax
    .text:00464205 mov ecx, offset unk_54D014
    .text:0046420A call sub_45FF30
    .text:0046420F nop
    .text:00464210 push offset aXiaoming ; 参数"xiaoming"
    .text:00464215 push 1 ; 另一个参数
    .text:00464217 lea ecx, [ebp+var_20] ; [ebp+var_20]是一个对象,this指针指向该对象
    .text:0046421A call sub_46062E ; 构造函数
    .text:0046421F nop
    .text:00464220 push offset aPause ; "pause"
    .text:00464225 call sub_45F98B ; system
    .text:0046422A add esp, 4
    .text:0046422D mov [ebp+var_EC], 0
    .text:00464237 lea ecx, [ebp+var_20] ; this指针
    .text:0046423A call sub_45D38E ; 析构函数
    .text:0046423F mov eax, [ebp+var_EC]
    .text:00464245 push edx
    .text:00464246 mov ecx, ebp
    .text:00464248 push eax
    .text:00464249 lea edx, dword_464274
    .text:0046424F call sub_45EC4D
    .text:00464254 pop eax
    .text:00464255 pop edx
    .text:00464256 pop edi
    .text:00464257 pop esi
    .text:00464258 pop ebx
    .text:00464259 mov ecx, [ebp+var_4]
    .text:0046425C xor ecx, ebp ; StackCookie
    .text:0046425E call j_@__security_check_cookie@4 ; __security_check_cookie(x)
    .text:00464263 add esp, 0F0h
    .text:00464269 cmp ebp, esp
    .text:0046426B call sub_45F175
    .text:00464270 mov esp, ebp
    .text:00464272 pop ebp
    .text:00464273 retn

    ;构造函数
    .text:00463FC0 var_C = byte ptr -0Ch
    .text:00463FC0 var_8 = dword ptr -8
    .text:00463FC0 arg_0 = dword ptr 8
    .text:00463FC0 arg_4 = dword ptr 0Ch
    .text:00463FC0
    .text:00463FC0 push ebp
    .text:00463FC1 mov ebp, esp
    .text:00463FC3 sub esp, 0CCh
    .text:00463FC9 push ebx
    .text:00463FCA push esi
    .text:00463FCB push edi
    .text:00463FCC push ecx
    .text:00463FCD lea edi, [ebp+var_C]
    .text:00463FD0 mov ecx, 3
    .text:00463FD5 mov eax, 0CCCCCCCCh
    .text:00463FDA rep stosd
    .text:00463FDC pop ecx
    .text:00463FDD mov [ebp+var_8], ecx ; 当前对象地址保存到[ebp+var_8]
    .text:00463FE0 mov ecx, offset unk_54D014
    .text:00463FE5 call sub_45FF30
    .text:00463FEA nop
    .text:00463FEB mov eax, [ebp+var_8] ; 第一个对象成员
    .text:00463FEE mov ecx, [ebp+arg_0] ; 第一个参数1
    .text:00463FF1 mov [eax], ecx
    .text:00463FF3 push 4
    .text:00463FF5 mov eax, [ebp+arg_4] ; 第二个参数"xiaoming"
    .text:00463FF8 push eax
    .text:00463FF9 mov ecx, [ebp+var_8]
    .text:00463FFC add ecx, 4 ; 第二个对象成员
    .text:00463FFF push ecx
    .text:00464000 call sub_45FCF1 ; memcpy()
    .text:00464005 add esp, 0Ch
    .text:00464008 mov eax, [ebp+var_8] ; 返回的是对象地址
    .text:0046400B pop edi
    .text:0046400C pop esi
    .text:0046400D pop ebx
    .text:0046400E add esp, 0CCh
    .text:00464014 cmp ebp, esp
    .text:00464016 call sub_45F175
    .text:0046401B mov esp, ebp
    .text:0046401D pop ebp
    .text:0046401E retn 8

    ;析构函数
    .text:00464040 var_C = byte ptr -0Ch
    .text:00464040 var_8 = dword ptr -8
    .text:00464040
    .text:00464040 push ebp
    .text:00464041 mov ebp, esp
    .text:00464043 sub esp, 0CCh
    .text:00464049 push ebx
    .text:0046404A push esi
    .text:0046404B push edi
    .text:0046404C push ecx
    .text:0046404D lea edi, [ebp+var_C]
    .text:00464050 mov ecx, 3
    .text:00464055 mov eax, 0CCCCCCCCh
    .text:0046405A rep stosd
    .text:0046405C pop ecx
    .text:0046405D mov [ebp+var_8], ecx ; 把对象地址存到[ebp+var_8]
    .text:00464060 mov ecx, offset unk_54D014
    .text:00464065 call sub_45FF30
    .text:0046406A nop
    .text:0046406B push offset aDestructing ; "destructing......"
    .text:00464070 call sub_45DB59 ; printf
    .text:00464075 add esp, 4
    .text:00464078 pop edi
    .text:00464079 pop esi
    .text:0046407A pop ebx
    .text:0046407B add esp, 0CCh
    .text:00464081 cmp ebp, esp
    .text:00464083 call sub_45F175
    .text:00464088 mov esp, ebp
    .text:0046408A pop ebp
    .text:0046408B retn

    源码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    class Student {
    private:
    int ID;
    char name[20];
    public:
    Student(int n = 0, const char* na = "NONE") :ID(n) {
    memcpy(name, na, sizeof(na));
    }
    void show();
    ~Student();
    };
    void Student::show() {
    printf("%d %s\n", ID, name);
    }
    Student::~Student() {
    printf("destructing......");
    }
    int main() {
    Student stu(001, "xiaoming");
    system("pause");
    return 0;
    }
作者

SydzI

发布于

2025-07-21

更新于

2025-10-03

许可协议

评论