您当前的位置:首页 > 计算机 > 编程开发 > Other

Main()函数的前世今生

时间:10-06来源:作者:点击数:

在开始分析程序之前,我们第一个要解决的问题,就是如何定位到main函数,想要从二进制逆向的角度分析出main函数,就必须要了解正向的代码下main函数的所有的细节和特

征。毕竟逆向的本质就是正向。

调用main()堆栈

样例代码

#include <stdio.h>


int main()
{
	printf("Hello World!");

	return 0;
}

通过VS2019查看main()函数调用的堆栈空间

转到mainCRTStartup()的反汇编,这是C++程序执行的第一个函数

mainCRTStartup先调用__scrt_common_main函数

转到__scrt_common_main()的反汇编

在反汇编代码中,__scrt_common_main第二个调用函数是__scrt_common_main_seh

之后__scrt_common_main_seh调用invoke_main()

转到invoke_main()的反汇编,发现调用_main()函数

回到源代码

这就到main函数了,这里就到了main函数了,这里main函数有三个参数,分别是

  • __argc是参数个数
  • __argv是参数列表
  • 最后一个是环境指针

里面的每一个参数都是单独的一个函数

可以得出规律

  1. mainCRTStartup调用__scrt_common_main
  2. __scrt_common_main调用__scrt_common_main_seh,对应汇编是在第二个call上
  3. __scrt_common_main_seh调用invoke_main,对应在汇编的特征如下:
    1. int const main_result = invoke_main();源码是赋值给一个变量
    2. 这个函数参数是0个,后面会跟exit函数,而exit函数的参数 是 invoke_main的返回值
    3. call指令后面必有一个mov [ebp-0xXXX],eax
  4. invoke_main调用main

x64dbg定位main函数

进入程序入口,调用mainCRTStartup函数

调用__scrt_common_main函数

调用_scrt_common_main_seh

调用invoke_main比较复杂,先分析一下它的特征,在scrt_common_main_seh

会把invoke_main的返回值给main_result
int const main_result = invoke_main();


返回值会伴随一个exit 和 一个main_result,必然有一个ret
if (!__scrt_is_managed_app())
   exit(main_result);

return main_result;

定位invoke_main方法:

  1. 找到第一个ret
  2. 定位到call XXXX
  3. call指令后面必有一个mov [ebp-0xXXX],eax

定位ret

定位invoke_main()

在这里会看到四个函数调用,最后一个才是main函数

定位到main()函数

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门