C++反汇编之“认识启动函数,找到用户入口”

本文揭示了C++程序启动过程中的细节,指出main或WinMain并非程序第一条执行指令,而是由mainCRTStartup等启动函数调用。在进入main之前,操作系统涉及了资源分配、版本检查、堆初始化、命令行参数处理和环境变量解析等一系列操作。通过分析,我们可以更好地理解程序的启动流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        VC++开发的程序,在调试时总是从main或者WinMain开始的。初学编程时老师一定告诉过我们这是程序的入口,也就是程序的第一条指令执行处。这个认识其实是错误的,在他们之前还要更早的调用者。

        在应用程序被加载时,操作系统会分析执行文件内的数据,分配相关资源,读取文件中的代码和数据适合的内存单元,然后才是执行入口代码,入口代码其实并不是main或WinMain,通常是mainCRTStartup,wmainCRTStartup,WinMainCRTStartup,具体由编译选项而定。

        了解VC++6.0的启动函数

        VC++6.0在控制台和对多字节编码环境下的启动函数为mainCRTStartup,由系统库KERNEL32.dll负责调用。在mainCRTStartup中再调用main函数。我们通过编译器提供的Call Stack观察在main函数启动之前系统进行了哪些操作。

      

        图中调用了5个函数,两个NTDLL,一个KERNEL32,一个mainCRTStartup,一个main,VC++提供了mainCRTStartup()函数的源码,该函数完成了一下调用:

1.GetVersion函数:获取当前运行平台的版本号。

2._heap_init函数:用于初始化堆空间。在函数实现中使用HeapCreate申请堆空间

3.GetCommandLineA函数:获取命令行参数信息的首地址

4._crtGetEnvironmentStringA函数:获取环境变量信息的首地址

5._setargv函数:此函数根据GetCommandLineA获取命令行参数信息的首地址并进行参数分析

6._setenvp函数:此函数根据_crtGetEnvironmentStringA函数获取环境变量信息的首地址进行分析。

7._cinit函数:用于全局变量数据和浮点数寄存器的初始化。


main函数识别

在OllyDBG中加载一个程序进行分析,OllyDBG会自动识别GetCommandLineA函数,往下依次是_crtGetEnvironmentStringA,_setargv,_setenvp,_cinit

CPU Disasm
Address   Hex dump          Command                                  Comments
0040122B  |.  E8 502B0000   CALL 00403D80
00401230  |.  FF15 4CD14200 CALL DWORD PTR DS:[<&KERNEL32.GetCommand ; [KERNEL32.GetCommandLineA
00401236  |.  A3 24C64200   MOV DWORD PTR DS:[42C624],EAX
0040123B  |.  E8 20290000   CALL 00403B60                            ; [ACM05.00403B60
00401240  |.  A3 6CAC4200   MOV DWORD PTR DS:[42AC6C],EAX
00401245  |.  E8 06240000   CALL 00403650                            ; [ACM05.00403650
0040124A  |.  E8 B1220000   CALL 00403500                            ; [ACM05.00403500
0040124F  |.  E8 CC1E0000   CALL 00403120                            ; [ACM05.00403120
00401254  |.  8B0D A8AC4200 MOV ECX,DWORD PTR DS:[42ACA8]
0040125A  |.  890D ACAC4200 MOV DWORD PTR DS:[42ACAC],ECX
00401260  |.  8B15 A8AC4200 MOV EDX,DWORD PTR DS:[42ACA8]
00401266  |.  52            PUSH EDX
00401267  |.  A1 A0AC4200   MOV EAX,DWORD PTR DS:[42ACA0]
0040126C  |.  50            PUSH EAX
0040126D  |.  8B0D 9CAC4200 MOV ECX,DWORD PTR DS:[42AC9C]
00401273  |.  51            PUSH ECX
00401274  |.  E8 8CFDFFFF   CALL 00401005

IDA则会更清楚的反应调用情况


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值