如何寻找main函数的入口点,先看下mainCRTStartup的启动代码
mainCRTStartup函数在VC++6.0中的代码;
//预编译宏
#else /*_WINMAIN_*/
#ifdef WPRFLAG
//宽字符版控制台启动函数
void wmainCRTStartup(
#else/*WPRFLAG*/
//多字节版控制台启动函数
void mainCRTStartup(
#endif /*WPRFLAG*/
#endif /*_WINMAIN_*/
void )
{
//获取系统版本信息
_osver=GetVersion();
_winminor=(_oserver>>8)&0x00FF;
_winmajor=_oserver & 0xFF; //主版本
_winver=(_winmajor<<8)+_winminor;
_osver=(_osver>>16) & 0x00FFFF;
//堆空间初始化过程,在这个函数里,指定了程序中堆空间的起始地址
//_MT是多线程标记
#ifdef _MT
if(!_heap_init(1))
#else /*_MT*/
if(!_heap_intit(0))
#endif /*_MT*/
fast_error_exit(_RT_HEAPINIT);
//初始化多线程环境
#ifdef _MT
if(!_mtinit())
fast_error_exit(_RT_THREAD);
#endif /*_MT*/
_try{
//宽字符处理代码略
//多字节版获取命令行
_acmdln=(char*)GetCommandLineA();
//多字节版获取环境变量信息
_aenvptr=(char*)_crtGetEnvironmentStringsA();
//多字节版获取命令行信息
_setargv();
//多字节版获取环境变量信息
_setenvp();
#endif /*WPRFLAG*/
//初始化全局数据和浮点寄存器
_cinit();
//窗口程序处理代码略
//宽字符串里代码略
//获取环境变量信息
_initenv=_environ;
//调用main函数,传递命令行参数信息
mainret=main(_argc,_argv,_environ);
#endif /*WPRFLAG*/
#endif/*_WINMAIN_*/
//检查main函数返回值执行析构函数或atexit注册函数指针,并结束程序
exit(mainret)
}
//退出结束代码略
}
可见调用的函数有:
GetVersion()
_heap_init()
GetCommandLineA()
_crtGetEnvironmentStringsA()
_setargv()
_setenvp()
_cinit()
一共七个函数之后开始调用main函数;
而且main函数有三个参数,会有压栈动作
比如3个push操作下的一个call就是main 了~
识别main函数入口点上OllyDBG似乎没有IDA做的好~
虽然OD也有那一个选项,但每次都停在了加载地址上,IDA直接识别main~