MiniDump
#pragma once void RunCrashHandler();
#include "MiniDump.h" #include <windows.h> #include <imagehlp.h> #include <stdlib.h> #include <tchar.h> #pragma comment(lib, "dbghelp.lib") inline BOOL IsDataSectionNeeded(const WCHAR* pModuleName) { if (pModuleName == 0) { return FALSE; } WCHAR szFileName[_MAX_FNAME] = L""; //_wsplitpath(pModuleName, NULL, NULL, szFileName, NULL); _wsplitpath_s(pModuleName, NULL, 0, NULL, 0, szFileName, 0, NULL, 0); //if (wcsicmp(szFileName, L"ntdll") == 0) if (_wcsicmp(szFileName, L"ntdll") == 0) return TRUE; return FALSE; } inline BOOL CALLBACK MiniDumpCallback(PVOID pParam, const PMINIDUMP_CALLBACK_INPUT pInput, PMINIDUMP_CALLBACK_OUTPUT pOutput) { if (pInput == 0 || pOutput == 0) return FALSE; switch (pInput->CallbackType) { case ModuleCallback: if (pOutput->ModuleWriteFlags & ModuleWriteDataSeg) if (!IsDataSectionNeeded(pInput->Module.FullPath)) pOutput->ModuleWriteFlags &= (~ModuleWriteDataSeg); case IncludeModuleCallback: case IncludeThreadCallback: case ThreadCallback: case ThreadExCallback: return TRUE; default:; } return FALSE; } //创建Dump文件 inline void CreateMiniDump(EXCEPTION_POINTERS* pep, LPCTSTR strFileName) { HANDLE hFile = CreateFile(strFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if ((hFile != NULL) && (hFile != INVALID_HANDLE_VALUE)) { MINIDUMP_EXCEPTION_INFORMATION mdei; mdei.ThreadId = GetCurrentThreadId(); mdei.ExceptionPointers = pep; mdei.ClientPointers = FALSE; MINIDUMP_CALLBACK_INFORMATION mci; mci.CallbackRoutine = (MINIDUMP_CALLBACK_ROUTINE)MiniDumpCallback; mci.CallbackParam = 0; MINIDUMP_TYPE mdt = (MINIDUMP_TYPE)0x0000ffff; MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &mdei, NULL, &mci); CloseHandle(hFile); } } LPTOP_LEVEL_EXCEPTION_FILTER WINAPI MyDummySetUnhandledExceptionFilter(LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter) { return NULL; } BOOL PreventSetUnhandledExceptionFilter() { HMODULE hKernel32 = LoadLibrary(_T("kernel32.dll")); if (hKernel32 == NULL) return FALSE; void *pOrgEntry = GetProcAddress(hKernel32, "SetUnhandledExceptionFilter"); if (pOrgEntry == NULL) return FALSE; unsigned char newJump[100]; DWORD dwOrgEntryAddr = (DWORD)pOrgEntry; dwOrgEntryAddr += 5; // add 5 for 5 op-codes for jmp far void *pNewFunc = &MyDummySetUnhandledExceptionFilter; DWORD dwNewEntryAddr = (DWORD)pNewFunc; DWORD dwRelativeAddr = dwNewEntryAddr - dwOrgEntryAddr; newJump[0] = 0xE9; // JMP absolute memcpy(&newJump[1], &dwRelativeAddr, sizeof(pNewFunc)); SIZE_T bytesWritten; BOOL bRet = WriteProcessMemory(GetCurrentProcess(), pOrgEntry, newJump, sizeof(pNewFunc)+1, &bytesWritten); return bRet; } LONG WINAPI UnhandledExceptionFilterEx(struct _EXCEPTION_POINTERS *pException) { TCHAR szMbsFile[MAX_PATH] = { 0 }; ::GetModuleFileName(NULL, szMbsFile, MAX_PATH); TCHAR* pFind = _tcsrchr(szMbsFile, '\\'); if (pFind) { *(pFind + 1) = 0; //_tcscat(szMbsFile, _T("CreateMiniDump.dmp")); _tcscat_s(szMbsFile, _T("CreateMiniDump.dmp")); CreateMiniDump(pException, szMbsFile); } // TODO: MiniDumpWriteDump FatalAppExit(-1, _T("Fatal Error")); return EXCEPTION_CONTINUE_SEARCH; } //运行异常处理 void RunCrashHandler() { static bool bIni = false; if (!bIni) { SetUnhandledExceptionFilter(UnhandledExceptionFilterEx); PreventSetUnhandledExceptionFilter(); bIni = true; } }