⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 excepthandler.cpp

📁 fax engine 传真引擎 relay fax 的开源项目 商业软件使用 高质量 高可靠
💻 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 + -