main 함수의 앞차례 실행 과정에 대한 간단한 소개
7041 단어 안전 관련
main 함수는 사실 우리가 제어할 수 있는 프로그램 입구이지만 프로그램이 컴파일된 후에 실행하는 것은main 함수로부터 시작되는 것이 아니다. 여기서 주로 VC6를 설명한다.0++에서 컴파일된 프로그램이main 함수를 실행하기 전의 절차는main 함수를 실행하기 전에 환경 변수와 매개 변수 개수, 매개 변수의 해석을 한 다음에 전역 변수, 더미,io 등의 내용을 초기화하기 위한 것이다.
/***
*crt0.c - C runtime initialization routine
*
* Copyright (c) 1989-1997, Microsoft Corporation. All rights reserved.
*
*Purpose:
* This the actual startup routine for apps. It calls the user's main
* routine [w]main() or [w]WinMain after performing C Run-Time Library
* initialization.
*
* (With ifdef's, this source file also provides the source code for
* wcrt0.c, the startup routine for console apps with wide characters,
* wincrt0.c, the startup routine for Windows apps, and wwincrt0.c,
* the startup routine for Windows apps with wide characters.)
*
*******************************************************************************/
#ifdef _WIN32
#ifndef CRTDLL
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
/*
* wWinMain is not yet defined in winbase.h. When it is, this should be
* removed.
*/
int
WINAPI
wWinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPWSTR lpCmdLine,
int nShowCmd
);
#ifdef WPRFLAG
_TUCHAR * __cdecl _wwincmdln(void);
#else /* WPRFLAG */
_TUCHAR * __cdecl _wincmdln(void);
#endif /* WPRFLAG */
/*
* command line, environment, and a few other globals
*/
#ifdef WPRFLAG
wchar_t *_wcmdln; /* points to wide command line */
#else /* WPRFLAG */
char *_acmdln; /* points to command line */
#endif /* WPRFLAG */
char *_aenvptr = NULL; /* points to environment block */
wchar_t *_wenvptr = NULL; /* points to wide environment block */
void (__cdecl * _aexit_rtn)(int) = _exit; /* RT message return procedure */
static void __cdecl fast_error_exit(int); /* Error exit via ExitProcess */
/*
* _error_mode and _apptype, together, determine how error messages are
* written out.
*/
int __error_mode = _OUT_TO_DEFAULT;
#ifdef _WINMAIN_
int __app_type = _GUI_APP;
#else /* _WINMAIN_ */
int __app_type = _CONSOLE_APP;
#endif /* _WINMAIN_ */
/***
*BaseProcessStartup(PVOID Peb)
*
*Purpose:
* This routine does the C runtime initialization, calls main(), and
* then exits. It never returns.
*
*Entry:
* PVOID Peb - pointer to Win32 Process Environment Block (not used)
*
*Exit:
* This function never returns.
*
*******************************************************************************/
#ifdef _WINMAIN_
#ifdef WPRFLAG
void wWinMainCRTStartup(
#else /* WPRFLAG */
// main
void WinMainCRTStartup(
#endif /* WPRFLAG */
#else /* _WINMAIN_ */
#ifdef WPRFLAG
void wmainCRTStartup(
#else /* WPRFLAG */
void mainCRTStartup(
#endif /* WPRFLAG */
#endif /* _WINMAIN_ */
void
)
{
int mainret;
#ifdef _WINMAIN_
_TUCHAR *lpszCommandLine;
STARTUPINFO StartupInfo;
#endif /* _WINMAIN_ */
/*
* Get the full Win32 version
*/
//
_osver = GetVersion();
//
_winminor = (_osver >> 8) & 0x00FF ;
_winmajor = _osver & 0x00FF ;
_winver = (_winmajor << 8) + _winminor;
_osver = (_osver >> 16) & 0x00FFFF ;
#ifdef _MT
//
if ( !_heap_init(1) ) /* initialize heap */
#else /* _MT */
if ( !_heap_init(0) ) /* initialize heap */
#endif /* _MT */
fast_error_exit(_RT_HEAPINIT); /* write message and die */
#ifdef _MT
//
if( !_mtinit() ) /* initialize multi-thread */
fast_error_exit(_RT_THREAD); /* write message and die */
#endif /* _MT */
/*
* Guard the remainder of the initialization code and the call
* to user's main, or WinMain, function in a __try/__except
* statement.
*/
__try {
// IO
_ioinit(); /* initialize lowio */
#ifdef WPRFLAG
/* get wide cmd line info */
// ,
_wcmdln = (wchar_t *)__crtGetCommandLineW();
/* get wide environ info */
// ,
_wenvptr = (wchar_t *)__crtGetEnvironmentStringsW();
// main argv
_wsetargv();
//
_wsetenvp();
#else /* WPRFLAG */
//
/* get cmd line info */
_acmdln = (char *)GetCommandLineA();
/* get environ info */
_aenvptr = (char *)__crtGetEnvironmentStringsA();
_setargv();
_setenvp();
#endif /* WPRFLAG */
// ,
_cinit(); /* do C data initialize */
// WINMAIN GUI
#ifdef _WINMAIN_
StartupInfo.dwFlags = 0;
//
GetStartupInfo( &StartupInfo );
#ifdef WPRFLAG
// Unicode Unicode
lpszCommandLine = _wwincmdln();
mainret = wWinMain(
#else /* WPRFLAG */
lpszCommandLine = _wincmdln();
mainret = WinMain(
#endif /* WPRFLAG */
GetModuleHandleA(NULL),
NULL,
lpszCommandLine,
StartupInfo.dwFlags & STARTF_USESHOWWINDOW
? StartupInfo.wShowWindow
: SW_SHOWDEFAULT
);
#else /* _WINMAIN_ */
#ifdef WPRFLAG
// main
__winitenv = _wenviron;
mainret = wmain(__argc, __wargv, _wenviron);
#else /* WPRFLAG */
__initenv = _environ;
mainret = main(__argc, __argv, _environ);
#endif /* WPRFLAG */
#endif /* _WINMAIN_ */
// main
exit(mainret);
}
// windows (SEH), _XcptFilter , ,
//GetExceptionCode
// SEH (exception code)。 GetExceptionCode() 。 GetExceptionInformation()
__except ( _XcptFilter(GetExceptionCode(), GetExceptionInformation()) )
{
/*
* Should never reach here
*/
//
_exit( GetExceptionCode() );
} /* end of try - except */
}
정보XcptFilter 함수는 사실 이상을 식별하고 관련 조작을 하는 것이다
int __cdecl _XcptFilter( unsigned long xcptnum, PEXCEPTION_POINTERS pxcptinfoptrs ); [in] xcptnum 이상 식별자입니다.[in] pxcptinfoptrs가 비정상적인 정보를 가리키는 바늘입니다.