#include #include #include extern "C" size_t gGxxThrowRefDll = 0xDEADBEEF; static std::string kStringRawName = typeid(std::string).raw_name(); static bool IsReadable(const void *address) { MEMORY_BASIC_INFORMATION info; if (!VirtualQuery(address, &info, sizeof(info))) { return false; } if (!info.BaseAddress) { return false; } return (info.Protect & (PAGE_READONLY | PAGE_READWRITE)) != 0; } #pragma warning(suppress : 4996) extern "C" void __stdcall _SEHReport(void *exception, const ThrowInfo *throwInfo, void *caller) { if (!throwInfo) return; if (!exception) return; auto attribs = throwInfo->attributes; HMODULE handle = 0; if (_EH_RELATIVE_TYPEINFO) { GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCSTR)caller, (HMODULE *)&handle); } const auto catchableTypeArray = reinterpret_cast(reinterpret_cast(handle) + static_cast(throwInfo->pCatchableTypeArray)); std::string suffix; std::string message; for (int i = 0; i < catchableTypeArray->nCatchableTypes; i++) { const auto type = reinterpret_cast (reinterpret_cast(handle) + static_cast(catchableTypeArray->arrayOfCatchableTypes[i])); const auto descriptor = reinterpret_cast (reinterpret_cast(handle) + static_cast(type->pType)); message += (i == 0 ? "" : std::string(", ")) + descriptor->name(); // __std_type_info_name if (_strnicmp(descriptor->raw_name(), ".?AVException@", 15 - 1) == 0) { auto exception2 = reinterpret_cast(exception); auto wptr = exception2->what(); if (wptr) { suffix = wptr; } } else if (_strnicmp(descriptor->raw_name(), ".PEAD", 5) == 0) { auto possibleStringPointer = reinterpret_cast(exception); if (IsReadable(possibleStringPointer)) { auto string = *possibleStringPointer; if (IsReadable(string) && (strnlen(string, 4096) < 1024)) { suffix = string; } } } else if (_strnicmp(descriptor->raw_name(), kStringRawName.data(), kStringRawName.size()) == 0) { auto possibleStdStringPointer = reinterpret_cast(exception); if (IsReadable(possibleStdStringPointer)) { auto string = *possibleStdStringPointer; suffix = string; } } } if (suffix.size()) { message += std::string("\r\n ") + suffix; } if (message.size()) { std::cout << message << std::endl; } } int main() { gGxxThrowRefDll = (size_t)GetProcAddress(LoadLibraryW(L"ucrtbase.dll"), "_CxxThrowException"); try { throw std::exception("hello"); std::cout << "cont?!!\n"; } catch (...) { std::cout << "caught!\n"; } }