SetUnhandledExceptionFilter catches all exceptions

question

Your program crashed, and you went to the place where SetUnhandledExceptionFilter wrote the MiniDump file, and found that it was empty, no crash log file was caught, and it didn’t work as you expected, what should you do?

SetUnhandledExceptionFilter is flawed, it doesn’t catch enough. If you make a memory write exception, it will intercept it for you, but if you encounter a stack overflow, there is no way. There is also a range exception, abort()....nothing down.

Solution

I have searched the entire network for these problems, including domestic and foreign ones, and found some solutions to aborts and a few crt-related exceptions such as stack overflow, but no one has any good solutions. As long as you do your own research, and finally share the method.

The principle is to tamper with several fastfail exception error functions of several crts, let them all run my new code directly (hook as the saying goes), and don't let them call the WER of the system anymore.

It supports X86 and X6, and it is no problem to test after getting it. It is now used in my program.

code reference

Refer to the code:

Define and call:

		extern __declspec(noinline) void __cdecl __report_securityfailure(ULONG failure_code);
		extern __declspec(noreturn) void __cdecl __report_rangecheckfailure();
		extern __declspec(noreturn) void __cdecl __report_gsfailure(uintptr_t stack_cookie);
		tprogresscrash::PreventFuncall(&__report_gsfailure, &my__report_gsfailure);
		tprogresscrash::PreventFuncall(&__report_rangecheckfailure, &my__report_rangecheckfailure);
		tprogresscrash::PreventFuncall(&__report_securityfailure, &my__report_securityfailure);

Key implementation functions:

static BOOL PreventFuncall(void *oldfun,void *newfun) {
		void* pOrgEntry = oldfun;
		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 = newfun;
#ifdef _M_IX86
		DWORD dwOrgEntryAddr = (DWORD)pOrgEntry;
		dwOrgEntryAddr += jmpSize;
		DWORD dwNewEntryAddr = (DWORD)pNewFunc;
		DWORD dwRelativeAddr = dwNewEntryAddr - dwOrgEntryAddr;
		newJump[0] = 0xE9;
		memcpy(&newJump[1], &dwRelativeAddr, sizeof(pNewFunc));
#elif _M_X64
		newJump[0] = 0x49;newJump[1] = 0xBB;
		memcpy(&newJump[2], &pNewFunc, sizeof(pNewFunc));
		newJump[10] = 0x41;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;
	}

Guess you like

Origin blog.csdn.net/henysugar/article/details/128879129