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

📄 cmseh.cpp

📁 Soul的源代码,类似于劲舞团之类的游戏
💻 CPP
字号:
#include <windows.h>
#include <stdio.h>
#include <DbgHelp.h>
#include "CMSeh.h"

using namespace MatrixCore::System;

BOOL CMSeh::m_bMiniDump = TRUE;

CMSeh::CMSeh(int iID_ErrWindow,BOOL bMiniDump)
	:m_pFilter(0)
{
	m_bMiniDump = bMiniDump;
	SetErrorMode(iID_ErrWindow);
	SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)HandleDebugEvent);
}

CMSeh::~CMSeh()
{
}

BOOL CMSeh::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;

	PIMAGE_DOS_HEADER pDosHdr = (PIMAGE_DOS_HEADER)hMod;
	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

	for(unsigned i = 0; i < pNtHdr->FileHeader.NumberOfSections; i++, pSection++)
	{
		DWORD sectionStart = pSection->VirtualAddress;
		DWORD sectionEnd = sectionStart + max(pSection->SizeOfRawData, pSection->Misc.VirtualSize);
		if((rva >= sectionStart) && (rva <= sectionEnd))
		{
			section = i + 1;
			offset = rva - sectionStart;
			return TRUE;
		}
	}
	return FALSE;
}

void CMSeh::PrintStack(CONTEXT *pCtx)
{
    DWORD pc = pCtx->Eip;
    PDWORD pFrame, pPrevFrame;
	char WriteBuf[256];
	pFrame = (PDWORD)pCtx->Ebp;

	do
	{
		char szModule[MAX_PATH] = {0,};
		DWORD section = 0, offset = 0;
		GetLogicalAddress((PVOID)pc, szModule, sizeof(szModule), section, offset);
		sprintf(WriteBuf,"%08X %08X %04X:%08X %s\n", pc, pFrame, section, offset, szModule);
		WriteSeh(OUTPUTFILENAME,WriteBuf);
		pc = pFrame[1];
		pPrevFrame = pFrame;
		pFrame = (PDWORD)pFrame[0];
		if((DWORD)pFrame & 3) break;
		if(pFrame <= pPrevFrame) break;
		if(IsBadWritePtr(pFrame, sizeof(PVOID) * 2)) break;
	} while(TRUE);
};

BOOL CMSeh::WriteSeh(char *cFn,char* cBuf)
{
	FILE *pFile;
	char cBuffer[8096];
	char cTmpBuf[512];
	ZeroMemory(cBuffer, sizeof(cBuffer));

	pFile = fopen(cFn, "at");

	if (pFile == NULL) 
	{
		MessageBox(NULL,"FILE OPEN ERR!!!","WARNNING",MB_OK);
		return FALSE;
	}

	fwrite(cBuf, 1, strlen(cBuf), pFile);
	fclose(pFile);

	return TRUE;
}

BOOL CMSeh::CrashExceptionDump(PEXCEPTION_POINTERS ExceptionInfo, const char* szDumpFileName)
{
	HANDLE hFile = CreateFile(szDumpFileName,
		GENERIC_WRITE,
		0,
		NULL,
		CREATE_ALWAYS,
		FILE_ATTRIBUTE_NORMAL,
		NULL);

	if (hFile)
	{
		MINIDUMP_EXCEPTION_INFORMATION eInfo;
		eInfo.ThreadId = GetCurrentThreadId();
		eInfo.ExceptionPointers = ExceptionInfo;
		eInfo.ClientPointers = FALSE;

		MINIDUMP_CALLBACK_INFORMATION cbMiniDump;
		cbMiniDump.CallbackRoutine = NULL;
		cbMiniDump.CallbackParam = 0;

		MiniDumpWriteDump(
			GetCurrentProcess(),
			GetCurrentProcessId(),
			hFile,
			MiniDumpNormal,
			ExceptionInfo ? &eInfo : NULL,
			NULL,
			NULL);
	}

	CloseHandle(hFile);

	return EXCEPTION_EXECUTE_HANDLER;
}


LONG _stdcall CMSeh::HandleDebugEvent(LPEXCEPTION_POINTERS lpEP)
{
	PVOID exceptionAddress = lpEP->ExceptionRecord->ExceptionAddress;
	DWORD exceptionCode    = lpEP->ExceptionRecord->ExceptionCode;
	char  sStatus[256];
	char  writebuf[256];
	SYSTEMTIME SysTime;

	switch (exceptionCode)
	{
	case STATUS_WAIT_0:
		strcpy(sStatus,"Wait 0");
		break;
	case STATUS_ABANDONED_WAIT_0:
		strcpy(sStatus,"Abandoned Wait 0");
		break;
	case STATUS_USER_APC:
		strcpy(sStatus,"User APC");
		break;
	case STATUS_TIMEOUT:
		strcpy(sStatus,"Timeout");
		break;
	case STATUS_PENDING:
		strcpy(sStatus,"Pending");
		break;
	case STATUS_SEGMENT_NOTIFICATION:
		return DBG_EXCEPTION_NOT_HANDLED;
	case STATUS_GUARD_PAGE_VIOLATION:
		strcpy(sStatus,"Guard Page Violation");
		break;
	case STATUS_DATATYPE_MISALIGNMENT:
		strcpy(sStatus,"Data Type Misalignment");
		break;
	case STATUS_BREAKPOINT:
		return DBG_EXCEPTION_NOT_HANDLED;
	case STATUS_SINGLE_STEP:
		return DBG_EXCEPTION_NOT_HANDLED;
	case STATUS_ACCESS_VIOLATION:
		strcpy(sStatus,"Access Violation");
		break;
	case STATUS_IN_PAGE_ERROR:
		strcpy(sStatus,"In Page Error");
		break;
	case STATUS_NO_MEMORY:
		strcpy(sStatus,"No Memory");
		break;
	case STATUS_ILLEGAL_INSTRUCTION:
		strcpy(sStatus,"Illegal Instruction");
		break;
	case STATUS_NONCONTINUABLE_EXCEPTION:
		strcpy(sStatus,"Noncontinuable Exception");
		break;
	case STATUS_INVALID_DISPOSITION:
		strcpy(sStatus,"Invalid Disposition");
		break;
	case STATUS_ARRAY_BOUNDS_EXCEEDED:
		strcpy(sStatus,"Array Bounds Exceeded");
		break;
	case STATUS_FLOAT_DENORMAL_OPERAND:
		strcpy(sStatus,"Float Denormal Operand");
		break;
	case STATUS_FLOAT_DIVIDE_BY_ZERO:
		strcpy(sStatus,"Divide by Zero");
		break;
	case STATUS_FLOAT_INEXACT_RESULT:
		strcpy(sStatus,"Float Inexact Result");
		break;
	case STATUS_FLOAT_INVALID_OPERATION:
		strcpy(sStatus,"Float Invalid Operation");
		break;
	case STATUS_FLOAT_OVERFLOW:
		strcpy(sStatus,"Float Overflow");
		break;
	case STATUS_FLOAT_STACK_CHECK:
		strcpy(sStatus,"Float Stack Check");
		break;
	case STATUS_FLOAT_UNDERFLOW:
		strcpy(sStatus,"Float Uderflow");
		break;
	case STATUS_INTEGER_DIVIDE_BY_ZERO:
		strcpy(sStatus,"Integer Divide by Zero");
		break;
	case STATUS_INTEGER_OVERFLOW:
		strcpy(sStatus,"Integer Overflow");
		break;
	case STATUS_PRIVILEGED_INSTRUCTION:
		strcpy(sStatus,"Privileged Instruction");
		break;
	case STATUS_STACK_OVERFLOW:
		strcpy(sStatus,"Stack Overflow");
		break;
	case STATUS_CONTROL_C_EXIT:
		strcpy(sStatus,"Ctrl+C Exit");
		break;
	default:
		strcpy(sStatus,"C++ Exception");
		break;
	}//switch       

	GetLocalTime(&SysTime);
	sprintf(writebuf, "\n%04d:%02d:%02d:%02d:%02d:%02d\t",SysTime.wYear,SysTime.wMonth,SysTime.wDay,SysTime.wHour,SysTime.wMinute, SysTime.wSecond);
	WriteSeh(OUTPUTFILENAME,writebuf);
	WriteSeh(OUTPUTFILENAME,"***UNHANDLED EXCEPTION****\n");
	


	sprintf(writebuf,"Reason: %s At Address %p\n\n",sStatus,exceptionAddress);
	WriteSeh(OUTPUTFILENAME,writebuf);
	PrintStack(lpEP->ContextRecord);

	char cDumpFileNmae[MAX_PATH];

	sprintf(cDumpFileNmae, "%02d_%02d_%02d_%02d_%02d",SysTime.wMonth,SysTime.wDay,SysTime.wHour,SysTime.wMinute, SysTime.wSecond);
	strcat(cDumpFileNmae,".dmp");
	// 固聪 待橇
	if(m_bMiniDump == TRUE)
		CrashExceptionDump(lpEP,cDumpFileNmae);


	//if (m_pFilter)
	//  m_pFilter(lpEP);
	::MessageBox(NULL,"Seh!!!!!!!!!",cDumpFileNmae,MB_OK);
	return EXCEPTION_CONTINUE_SEARCH;
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -