逆向程序分析:Windows的main(),启动函数分析
Posted CodeBowl
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了逆向程序分析: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(),看看他们有什么不一样。
参考资料
以上是关于逆向程序分析: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++ 程序 )