Monthly Archives: May 2013

Improved “PreventSetUnhandledExceptionFilter”

Starting with VS2005(VC8) it was not possible to handle all exceptions in process. I have discussed this in “SetUnhandledExceptionFilter” and VC8 and in Unhandled exceptions in VC8 and above… for x86 and x64.

It seemms that the code I posted had been used in many Projects to handle all exceptions and to write a minidump in that case. Also someone has used it in a VB6 application and for this he needed to implement this function in a separate “CrashHandler.dll”. But now he got errors during the shutdown of the VB6 application. It seems that VB6 unloads the DLL before other DLLs and it seems that some other DLL is calling “SetUnhandledExceptionFilter” during shutown. This now leads to trouble, because the DLL is already unloaded.

Now I created a better and cleaner implementation for the “PreventSetUnhandledExceptionFilter” function, which also works in any situation, even if the DLL was unloaded 😉

static BOOL PreventSetUnhandledExceptionFilter()
{
  HMODULE hKernel32 = LoadLibrary(_T("kernel32.dll"));
  if (hKernel32 == NULL) return FALSE;
  void *pOrgEntry = GetProcAddress(hKernel32, "SetUnhandledExceptionFilter");
  if (pOrgEntry == NULL) return FALSE;

#ifdef _M_IX86
  // Code for x86:
  // 33 C0                xor         eax,eax  
  // C2 04 00             ret         4 
  unsigned char szExecute[] = { 0x33, 0xC0, 0xC2, 0x04, 0x00 };
#elif _M_X64
  // 33 C0                xor         eax,eax 
  // C3                   ret  
  unsigned char szExecute[] = { 0x33, 0xC0, 0xC3 };
#else
#error "The following code only works for x86 and x64!"
#endif

  SIZE_T bytesWritten = 0;
  BOOL bRet = WriteProcessMemory(GetCurrentProcess(),
    pOrgEntry, szExecute, sizeof(szExecute), &bytesWritten);
  return bRet;
}