101 lines
3.2 KiB
C++
101 lines
3.2 KiB
C++
#pragma once
|
|
#include <windows.h>
|
|
#include <DbgHelp.h>
|
|
#include <stdlib.h>
|
|
|
|
namespace HBD {
|
|
|
|
void CreateDumpFile(LPCWSTR lpstrDumpFilePathName, EXCEPTION_POINTERS *pException) {
|
|
HANDLE hDumpFile = CreateFileW(lpstrDumpFilePathName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
MINIDUMP_EXCEPTION_INFORMATION dumpInfo;
|
|
dumpInfo.ExceptionPointers = pException;
|
|
dumpInfo.ThreadId = GetCurrentThreadId();
|
|
dumpInfo.ClientPointers = TRUE;
|
|
MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hDumpFile, MiniDumpNormal, &dumpInfo, NULL, NULL);
|
|
CloseHandle(hDumpFile);
|
|
}
|
|
|
|
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;
|
|
|
|
DWORD dwOldProtect = 0;
|
|
SIZE_T jmpSize = 5;
|
|
#ifdef _M_X64
|
|
jmpSize = 13;
|
|
#endif
|
|
BOOL bProt = VirtualProtect(pOrgEntry, jmpSize,
|
|
PAGE_EXECUTE_READWRITE, &dwOldProtect);
|
|
BYTE newJump[20];
|
|
void* pNewFunc = &MyDummySetUnhandledExceptionFilter;
|
|
#ifdef _M_IX86
|
|
DWORD dwOrgEntryAddr = (DWORD)pOrgEntry;
|
|
dwOrgEntryAddr += jmpSize; // add 5 for 5 op-codes for jmp rel32
|
|
DWORD dwNewEntryAddr = (DWORD)pNewFunc;
|
|
DWORD dwRelativeAddr = dwNewEntryAddr - dwOrgEntryAddr;
|
|
// JMP rel32: Jump near, relative, displacement relative to next instruction.
|
|
newJump[0] = 0xE9; // JMP rel32
|
|
memcpy(&newJump[1], &dwRelativeAddr, sizeof(pNewFunc));
|
|
#elif _M_X64
|
|
// We must use R10 or R11, because these are "scratch" registers
|
|
// which need not to be preserved accross function calls
|
|
// For more info see: Register Usage for x64 64-Bit
|
|
// http://msdn.microsoft.com/en-us/library/ms794547.aspx
|
|
// Thanks to Matthew Smith!!!
|
|
newJump[0] = 0x49; // MOV R11, ...
|
|
newJump[1] = 0xBB; // ...
|
|
memcpy(&newJump[2], &pNewFunc, sizeof(pNewFunc));
|
|
//pCur += sizeof (ULONG_PTR);
|
|
newJump[10] = 0x41; // JMP R11, ...
|
|
newJump[11] = 0xFF; // ...
|
|
newJump[12] = 0xE3; // ...
|
|
#endif
|
|
SIZE_T bytesWritten;
|
|
BOOL bRet = WriteProcessMemory(GetCurrentProcess(),
|
|
pOrgEntry, newJump, jmpSize, &bytesWritten);
|
|
|
|
if (bProt != FALSE)
|
|
{
|
|
DWORD dwBuf;
|
|
VirtualProtect(pOrgEntry, jmpSize, dwOldProtect, &dwBuf);
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
LONG WINAPI UnhandledExceptionFilterEx(struct _EXCEPTION_POINTERS *pException)
|
|
{
|
|
WCHAR szMbsFile[MAX_PATH] = { 0 };
|
|
::GetModuleFileNameW(NULL, szMbsFile, MAX_PATH);
|
|
WCHAR* pFind = wcsrchr(szMbsFile, '\\');
|
|
if (pFind)
|
|
{
|
|
*(pFind + 1) = 0;
|
|
SYSTEMTIME stLocalTime;
|
|
GetLocalTime(&stLocalTime);
|
|
WCHAR buffer[1024];
|
|
|
|
wsprintfW(buffer, L"%04d%02d%02d-%02d%02d%02d.dmp",
|
|
stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay,
|
|
stLocalTime.wHour, stLocalTime.wMinute, stLocalTime.wSecond);
|
|
wcscat(szMbsFile, buffer);
|
|
CreateDumpFile(szMbsFile, pException);
|
|
}
|
|
return EXCEPTION_CONTINUE_SEARCH;
|
|
}
|
|
|
|
void RunCrashHandler()
|
|
{
|
|
SetUnhandledExceptionFilter(UnhandledExceptionFilterEx);
|
|
PreventSetUnhandledExceptionFilter();
|
|
}
|
|
};
|