Tuesday, July 21, 2015

Release版本中SetUnhandledExceptionFilter函数无效

使用SetUnhandledExceptionFilter函数获取dump文件,非常便于生产环境中的调试。但突然发现release版本竟然无法dump了。
经查,新版本的CRT 实现在异常处理中强制删除所有应用程序先前设置的捕获函数,如下所示:
  /* Make sure any filter already in place is deleted. */
  SetUnhandledExceptionFilter(NULL);
  UnhandledExceptionFilter(&ExceptionPointers);
解决方法是拦截CRT 调用SetUnhandledExceptionFilter 函数,使之无效。在X86 平台下,可以使用以下代码。
#ifndef _M_IX86
#error “The following code only works for x86!”
#endif

void DisableSetUnhandledExceptionFilter()
{
void *addr = (void*)GetProcAddress(LoadLibrary(_T(“kernel32.dll”)),
“SetUnhandledExceptionFilter”);
if (addr)
{
unsigned char code[16];
int size = 0;
code[size++] = 0×33;
code[size++] = 0xC0;
code[size++] = 0xC2;
code[size++] = 0×04;
code[size++] = 0×00;

DWORD dwOldFlag, dwTempFlag;
VirtualProtect(addr, size, PAGE_READWRITE, &dwOldFlag);
WriteProcessMemory(GetCurrentProcess(), addr, code, size, NULL);
VirtualProtect(addr, size, dwOldFlag, &dwTempFlag);
}
}
在设置自己的异常处理函数后,调用DisableSetUnhandledExceptionFilter 禁止CRT 设置即可。

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;
}

//首先要清掉SEH
  asm
   @Loop:
    mov eax,fs:[0]
    cmp dword ptr [eax],$FFFFFFFF
    je @SEHCleared
    mov eax,[eax]
    mov fs:[0],eax
    jmp @Loop
   @SEHCleared:


http://www.debuginfo.com/articles/debugfilters.html
http://blog.kalmbach-software.de/2013/05/23/improvedpreventsetunhandledexceptionfilter/

No comments:

Post a Comment