C++全局对象的构造函数以及析构函数的调用

在main函数和之前_mainCRTStartup的_initterm函数:

extern "C" void __cdecl _initterm(_PVFV* const first, _PVFV* const last)
{
    for (_PVFV* it = first; it != last; ++it)
    {
        if (*it == nullptr)
            continue;
        (**it)();
    }

}

(**it)就是调用构造函数和调用注册析构函数的地方。下断点,跟进可以发现


首先调用了对象的构造函数,然后通过call atexit来注册析构代理函数,这里析构代理函数就是push的参数,地址为04242D0h,注册的析构代理函数会在程序的main函数结束后的doexit函数中进行调用


doexit -> onexit ->_acrt_lock_and_call -> _crt_seh_guarded_call -> lamba -> call esi这里被调用析构代理函数,并且是根据注册的析构代理函数顺序倒序进行调用。


且每个全局对象都会有一个单独的构造和析构代理函数,并且都会分别的调用。

所以要找一个全局对象的析构和构造函数可以通过堆_aexit进行下断点,找它的参数,然后确定构造函数,析构函数的地址以及全局变量的地址,再通过虚表指针会在构造函数和析构函数中赋值给*this这一个特点来更确定全局的构造和析构函数。


猜你喜欢

转载自blog.csdn.net/a893574301/article/details/80377153