📄 excepthandler.cpp
字号:
/*****************************************************************************
* RelayFax Open Source Project
* Copyright 1996-2004 Alt-N Technologies, Ltd.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted only as authorized by the RelayFax Open
* Source License. A copy of this license is available in file LICENSE
* in the top-level directory of the distribution.
*
* RelayFax is a registered trademark of Alt-N Technologies, Ltd.
*
* Individual files and/or contributed packages may be copyright by
* other parties and subject to additional restrictions.
*****************************************************************************/
#include "stdafx.h"
#include "excepthandler.h"
//////////////////////////////// Externals /////////////////////////////////////
int g_nExceptionCount = 0;
//////////////////////////////////////////////////////////////////////
// Log it
//////////////////////////////////////////////////////////////////////
void ExceptionLog( LPCSTR szFormat, ... )
{
char Buffer[RFLOGGER_BUFSIZE+2];
va_list va;
int nRet;
va_start( va, szFormat );
nRet = _vsnprintf( Buffer, RFLOGGER_BUFSIZE, szFormat, va );
if( nRet < 0 )
{
Buffer[RFLOGGER_BUFSIZE-1] = '\n';
Buffer[RFLOGGER_BUFSIZE] = '\0';
}
else
{
Buffer[nRet] = '\n';
Buffer[nRet+1] = '\0';
}
#ifdef DEBUG
OutputDebugString( Buffer );
#endif
va_end(va);
}
//////////////////////////////////////////////////////////////////////
// Given an exception code, returns a pointer to a static string with a
// description of the exception
//////////////////////////////////////////////////////////////////////
LPTSTR GetExceptionString( DWORD dwCode )
{
#define EXCEPTION( x ) case EXCEPTION_##x: return _T(#x);
switch ( dwCode )
{
EXCEPTION( ACCESS_VIOLATION )
EXCEPTION( DATATYPE_MISALIGNMENT )
EXCEPTION( BREAKPOINT )
EXCEPTION( SINGLE_STEP )
EXCEPTION( ARRAY_BOUNDS_EXCEEDED )
EXCEPTION( FLT_DENORMAL_OPERAND )
EXCEPTION( FLT_DIVIDE_BY_ZERO )
EXCEPTION( FLT_INEXACT_RESULT )
EXCEPTION( FLT_INVALID_OPERATION )
EXCEPTION( FLT_OVERFLOW )
EXCEPTION( FLT_STACK_CHECK )
EXCEPTION( FLT_UNDERFLOW )
EXCEPTION( INT_DIVIDE_BY_ZERO )
EXCEPTION( INT_OVERFLOW )
EXCEPTION( PRIV_INSTRUCTION )
EXCEPTION( IN_PAGE_ERROR )
EXCEPTION( ILLEGAL_INSTRUCTION )
EXCEPTION( NONCONTINUABLE_EXCEPTION )
EXCEPTION( STACK_OVERFLOW )
EXCEPTION( INVALID_DISPOSITION )
EXCEPTION( GUARD_PAGE )
EXCEPTION( INVALID_HANDLE )
}
// If not one of the "known" exceptions, try to get the string
// from NTDLL.DLL's message table.
static TCHAR szBuffer[512] = { 0 };
FormatMessage( FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE,
GetModuleHandle( _T("NTDLL.DLL") ),
dwCode, 0, szBuffer, sizeof( szBuffer ), 0 );
return szBuffer;
}
//////////////////////////////////////////////////////////////////////
// Given a linear address, locates the module, section, and offset containing
// that address.
//
// Note: the szModule paramater buffer is an output buffer of length specified
// by the len parameter (in characters!)
//////////////////////////////////////////////////////////////////////
BOOL GetLogicalAddress( PVOID addr, PTSTR szModule, DWORD len, DWORD& section, DWORD& offset )
{
MEMORY_BASIC_INFORMATION mbi;
if ( !VirtualQuery( addr, &mbi, sizeof(mbi) ) )
return FALSE;
DWORD hMod = (DWORD)mbi.AllocationBase;
if ( !GetModuleFileName( (HMODULE)hMod, szModule, len ) )
return FALSE;
// Point to the DOS header in memory
PIMAGE_DOS_HEADER pDosHdr = (PIMAGE_DOS_HEADER)hMod;
// From the DOS header, find the NT (PE) header
PIMAGE_NT_HEADERS pNtHdr = (PIMAGE_NT_HEADERS)(hMod + pDosHdr->e_lfanew);
PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION( pNtHdr );
DWORD rva = (DWORD)addr - hMod; // RVA is offset from module load address
// Iterate through the section table, looking for the one that encompasses
// the linear address.
for ( unsigned i = 0;
i < pNtHdr->FileHeader.NumberOfSections;
i++, pSection++ )
{
DWORD sectionStart = pSection->VirtualAddress;
DWORD sectionEnd = sectionStart
+ max(pSection->SizeOfRawData, pSection->Misc.VirtualSize);
// Is the address in this section???
if ( (rva >= sectionStart) && (rva <= sectionEnd) )
{
// Yes, address is in the section. Calculate section and offset,
// and store in the "section" & "offset" params, which were
// passed by reference.
section = i+1;
offset = rva - sectionStart;
return TRUE;
}
}
return FALSE; // Should never get here!
}
//////////////////////////////////////////////////////////////////////
// Walks the stack, and writes the results to the report file
//////////////////////////////////////////////////////////////////////
void IntelStackWalk( PCONTEXT pContext )
{
DWORD pc = pContext->Eip;
PDWORD pFrame, pPrevFrame;
pFrame = (PDWORD)pContext->Ebp;
do
{
TCHAR szModule[MAX_PATH];
DWORD section = 0, offset = 0;
szModule[0] = '\0';
GetLogicalAddress((PVOID)pc, szModule,sizeof(szModule),section,offset );
szModule[MAX_PATH-1] = '\0';
ExceptionLog( "%08X %08X %04X:%08X %s", pc, pFrame, section, offset, szModule );
if ( IsBadWritePtr(pFrame+1, sizeof(PVOID) ) )
break;
pc = pFrame[1];
pPrevFrame = pFrame;
pFrame = (PDWORD)pFrame[0]; // precede to next higher frame on stack
if ( (DWORD)pFrame & 3 ) // Frame pointer must be aligned on a
break; // DWORD boundary. Bail if not so.
if ( pFrame <= pPrevFrame )
break;
// Can two DWORDs be read from the supposed frame address?
if ( IsBadWritePtr(pFrame, sizeof(PVOID)*2) )
break;
} while ( 1 );
}
//////////////////////////////////////////////////////////////////////
// ExceptionHandler
//////////////////////////////////////////////////////////////////////
DWORD ExceptionHandler( LPEXCEPTION_POINTERS pExceptionInfo,
LPCSTR szThreadName,
LPCSTR szWhere )
{
PEXCEPTION_RECORD pExceptionRecord = pExceptionInfo->ExceptionRecord;
// First print information about the type of fault
ExceptionLog( "%s: Exception %08X %s in %s",
szThreadName,
pExceptionRecord->ExceptionCode,
GetExceptionString(pExceptionRecord->ExceptionCode),
szWhere );
OSVERSIONINFO osv;
// What version of Windows are you running?
osv.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&osv);
ExceptionLog( "OS version: %d.%d Platform ID: %d Build: %d",
osv.dwMajorVersion, osv.dwMinorVersion, osv.dwPlatformId, osv.dwBuildNumber );
IntelStackWalk( pExceptionInfo->ContextRecord );
ExceptionLog( "----------" );
g_nExceptionCount++;
return EXCEPTION_EXECUTE_HANDLER ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -