2022-01-23 02:32:46 +00:00
|
|
|
#include <Windows.h>
|
|
|
|
#include <iostream>
|
|
|
|
#include <ehdata.h>
|
|
|
|
|
2022-01-23 02:39:33 +00:00
|
|
|
extern "C" size_t gGxxThrowRefDll = 0xDEADBEEF;
|
2022-01-23 02:32:46 +00:00
|
|
|
|
|
|
|
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)
|
2022-01-23 02:39:33 +00:00
|
|
|
extern "C" void __stdcall _SEHReport(void *exception, const ThrowInfo *throwInfo, void *caller)
|
2022-01-23 02:32:46 +00:00
|
|
|
{
|
2022-01-23 02:39:33 +00:00
|
|
|
if (!throwInfo) return;
|
|
|
|
if (!exception) return;
|
2022-01-23 02:32:46 +00:00
|
|
|
|
|
|
|
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<const CatchableTypeArray *>(reinterpret_cast<size_t>(handle) + static_cast<size_t>(throwInfo->pCatchableTypeArray));
|
|
|
|
|
|
|
|
std::string suffix;
|
|
|
|
std::string message;
|
|
|
|
|
|
|
|
for (int i = 0; i < catchableTypeArray->nCatchableTypes; i++)
|
|
|
|
{
|
|
|
|
const auto type = reinterpret_cast<CatchableType *> (reinterpret_cast<size_t>(handle) + static_cast<size_t>(catchableTypeArray->arrayOfCatchableTypes[i]));
|
|
|
|
const auto descriptor = reinterpret_cast<std::type_info *> (reinterpret_cast<size_t>(handle) + static_cast<size_t>(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<std::exception *>(exception);
|
|
|
|
auto wptr = exception2->what();
|
|
|
|
if (wptr)
|
|
|
|
{
|
|
|
|
suffix = wptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (_strnicmp(descriptor->raw_name(), ".PEAD", 5) == 0)
|
|
|
|
{
|
|
|
|
auto possibleStringPointer = reinterpret_cast<const char **>(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<std::string *>(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()
|
|
|
|
{
|
2022-01-23 02:39:33 +00:00
|
|
|
gGxxThrowRefDll = (size_t)GetProcAddress(LoadLibraryW(L"ucrtbase.dll"), "_CxxThrowException");
|
2022-01-23 02:32:46 +00:00
|
|
|
try
|
|
|
|
{
|
|
|
|
throw std::exception("hello");
|
|
|
|
std::cout << "cont?!!\n";
|
|
|
|
}
|
|
|
|
catch (...)
|
|
|
|
{
|
|
|
|
std::cout << "caught!\n";
|
|
|
|
}
|
|
|
|
}
|