|
|
/***
*seclocf.c - Report /GS security check failure, local system CRT version * * Copyright (c) 2000-2001, Microsoft Corporation. All rights reserved. * *Purpose: * Define function used to report a security check failure. This * version is only used when linking against the system CRT DLL, * msvcrt.dll (or msvcrtd.dll). If that DLL does not export the global * failure handler __security_error_handler, then a default local * handler is used instead. * * This version does not use any other CRT functions, so it can be used * to compile code /GS which does not want to use the CRT. * * Entrypoints: * __local_security_error_handler * *Revision History: * 01-24-00 PML Created. * 08-30-00 PML Rename handlers, add extra parameters. Extensively * rework, moving the GetProcAddress of * __security_error_handler from seccook.c to here. * 03-28-01 PML Protect against GetModuleFileName overflow (vs7#231284) * *******************************************************************************/
#if defined(_SYSCRT) && defined(CRTDLL)
#include <windows.h>
#include <stdlib.h>
/*
* Default messagebox string components */
#define PROGINTRO "Program: "
#define DOTDOTDOT "..."
#define BOXINTRO_0 "Unknown security failure detected!"
#define MSGTEXT_0 \
"A security error of unknown cause has been detected which has\n" \ "corrupted the program's internal state. The program cannot safely\n" \ "continue execution and must now be terminated.\n"
#define BOXINTRO_1 "Buffer overrun detected!"
#define MSGTEXT_1 \
"A buffer overrun has been detected which has corrupted the program's\n" \ "internal state. The program cannot safely continue execution and must\n"\ "now be terminated.\n"
#define MAXLINELEN 60 /* max length for line in message box */
/***
*__local_security_error_handler() - Report security error * *Purpose: * A /GS security error has been detected, and the global failure handler * is not available from msvcrt.dll. Pop up a message box and terminate * the program. * *Entry: * int code - security failure code * void *data - code-specific data * *Exit: * Calls ExitProcess. * *Exceptions: * *******************************************************************************/
void __cdecl __local_security_error_handler( int code, void *data) { char progname[MAX_PATH + 1]; char * pch; char * outmsg; char * boxintro; char * msgtext; size_t subtextlen;
HANDLE hCRT; _secerr_handler_func pfnSecErrorHandler; HANDLE hUser32; int (APIENTRY *pfnMessageBoxA)(HWND, LPCSTR, LPCSTR, UINT);
/*
* Check if the system CRT DLL implements the process-wide security * failure handler, and use it instead if available. */ #ifdef _DEBUG
hCRT = GetModuleHandle("msvcrtd.dll"); #else
hCRT = GetModuleHandle("msvcrt.dll"); #endif
if (hCRT != NULL) { pfnSecErrorHandler = (_secerr_handler_func) GetProcAddress(hCRT, "__security_error_handler"); if (pfnSecErrorHandler != NULL) { pfnSecErrorHandler(code, data); ExitProcess(3); } }
/*
* DLL-resident handler not available. Use a local version that just * pops up a message box. */
switch (code) { default: /*
* Unknown failure code, which probably means an older CRT is * being used with a newer compiler. */ boxintro = BOXINTRO_0; msgtext = MSGTEXT_0; subtextlen = sizeof(BOXINTRO_0) + sizeof(MSGTEXT_0); break; case _SECERR_BUFFER_OVERRUN: /*
* Buffer overrun detected which may have overwritten a return * address. */ boxintro = BOXINTRO_1; msgtext = MSGTEXT_1; subtextlen = sizeof(BOXINTRO_1) + sizeof(MSGTEXT_1); break; }
progname[MAX_PATH] = '\0'; if (!GetModuleFileName(NULL, progname, MAX_PATH)) lstrcpy(progname, "<program name unknown>");
pch = progname;
/* sizeof(PROGINTRO) includes the NULL terminator */ if (sizeof(PROGINTRO) + lstrlen(progname) + 1 > MAXLINELEN) { pch += (sizeof(PROGINTRO) + lstrlen(progname) + 1) - MAXLINELEN; CopyMemory(pch, DOTDOTDOT, sizeof(DOTDOTDOT) - 1); }
outmsg = (char *)_alloca(subtextlen - 1 + 2 + sizeof(PROGINTRO) - 1 + lstrlen(pch) + 2);
lstrcpy(outmsg, boxintro); lstrcat(outmsg, "\n\n"); lstrcat(outmsg, PROGINTRO); lstrcat(outmsg, pch); lstrcat(outmsg, "\n\n"); lstrcat(outmsg, msgtext);
hUser32 = LoadLibrary("user32.dll");
if (hUser32 != NULL) {
pfnMessageBoxA = (int (APIENTRY *)(HWND, LPCSTR, LPCSTR, UINT)) GetProcAddress(hUser32, "MessageBoxA");
if (pfnMessageBoxA != NULL) { pfnMessageBoxA( NULL, outmsg, "Microsoft Visual C++ Runtime Library", MB_OK|MB_ICONHAND|MB_SETFOREGROUND|MB_TASKMODAL); }
FreeLibrary(hUser32); }
ExitProcess(3); }
#endif /* defined(_SYSCRT) && defined(CRTDLL) */
|