逆向程序分析:Windows的main(),启动函数分析

Posted CodeBowl

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了逆向程序分析:Windows的main(),启动函数分析相关的知识,希望对你有一定的参考价值。

Windows main 启动函数分析

实验环境

Windows10
Vs2015
x86程序

启动函数

C/C++的运行时启动函数,该函数负责对C/C++运行库进行初始化。

启动函数的作用

检索指向新进程的命令行指针、检索指向新进程的环境变量指针、全局变量初始化、内存初始化等。

当所有的初始化操作完成之后,启动函数会调用应用程序的进入点函数。

调试实战

我们写一个简单的main函数,然后F5进入调试。

mainCRTStartup()

这个函数调用了__scrt_common_main(),我们直接来看它。

__scrt_common_main()

发现这个函数主要在做,GS和SEH检查,这俩个检查主要是防止内存溢出的,想要了解的可以进一步了解一下。

__scrt_common_main_seh()

这里代码比较多,直接贴出来

static __declspec(noinline) int __cdecl __scrt_common_main_seh() throw()
{
    if (!__scrt_initialize_crt(__scrt_module_type::exe))
        __scrt_fastfail(FAST_FAIL_FATAL_APP_EXIT);

    bool has_cctor = false;
    __try
    {
        bool const is_nested = __scrt_acquire_startup_lock();

        if (__scrt_current_native_startup_state == __scrt_native_startup_state::initializing)
        {
            __scrt_fastfail(FAST_FAIL_FATAL_APP_EXIT);
        }
        else if (__scrt_current_native_startup_state == __scrt_native_startup_state::uninitialized)
        {
            __scrt_current_native_startup_state = __scrt_native_startup_state::initializing;

            if (_initterm_e(__xi_a, __xi_z) != 0)
                return 255;

            _initterm(__xc_a, __xc_z);

            __scrt_current_native_startup_state = __scrt_native_startup_state::initialized;
        }
        else
        {
            has_cctor = true;
        }

        __scrt_release_startup_lock(is_nested);

        // If this module has any dynamically initialized __declspec(thread)
        // variables, then we invoke their initialization for the primary thread
        // used to start the process:
        _tls_callback_type const* const tls_init_callback = __scrt_get_dyn_tls_init_callback();
        if (*tls_init_callback != nullptr && __scrt_is_nonwritable_in_current_image(tls_init_callback))
        {
            (*tls_init_callback)(nullptr, DLL_THREAD_ATTACH, nullptr);
        }

        // If this module has any thread-local destructors, register the
        // callback function with the Unified CRT to run on exit.
        _tls_callback_type const * const tls_dtor_callback = __scrt_get_dyn_tls_dtor_callback();
        if (*tls_dtor_callback != nullptr && __scrt_is_nonwritable_in_current_image(tls_dtor_callback))
        {
            _register_thread_local_exe_atexit_callback(*tls_dtor_callback);
        }

        //
        // Initialization is complete; invoke main...
        //

        int const main_result = invoke_main();

        //
        // main has returned; exit somehow...
        //

        if (!__scrt_is_managed_app())
            exit(main_result);

        if (!has_cctor)
            _cexit();

        // Finally, we terminate the CRT:
        __scrt_uninitialize_crt(true, false);
        return main_result;
    }
    __except (_seh_filter_exe(GetExceptionCode(), GetExceptionInformation()))
    {
        // Note:  We should never reach this except clause.
        int const main_result = GetExceptionCode();

        if (!__scrt_is_managed_app())
            _exit(main_result);

        if (!has_cctor)
            _c_exit();

        return main_result;
    }
}

invoke_main()

初始化环境变量,并且在最后调用了main函数,进入了程序。

总结

本片文章分析的是32位程序的入口函数,并且这只是入口函数的一种main(),下一篇文章我们将分析Winmain(),看看他们有什么不一样。

参考资料

C语言中的main函数为什么被称作程序入口

windows编程 进程(一):进程简介

以上是关于逆向程序分析:Windows的main(),启动函数分析的主要内容,如果未能解决你的问题,请参考以下文章

Windows 逆向内存地址分析 ( 内存条 | 虚拟内存 | 内存地址及寻址范围 | 内存地址与数据的关系 )

Android 逆向Android 进程注入工具开发 ( 注入代码分析 | 注入工具的 main 函数分析 )

Windows 逆向使用 CE 分析内存地址 ( 运行游戏 | 使用 CE 工具分析游戏内子弹数量对应的内存地址 | 内存地址初步查找 | 使用二分法定位最终的内存地址 )

Android 逆向Android 逆向通用工具开发 ( Android 端远程命令工具 | Android 端可执行程序的 main 函数操作 | TCP 协议服务器建立 | 接收客户端数据 )(代

XCTF-攻防世界CTF平台-Reverse逆向类——2answer_to_everything

Windows 逆向CheatEngine 工具 ( 汉化版 CE 工具推荐 | 编写简单 C++ 程序 | C++ 程序执行分析 | 使用 CE 修改上述 C++ 程序 )