commit 859c35d17559cc1825ded5c973a0a859dedb97a6 Author: Reece Date: Sun Jan 23 02:32:46 2022 +0000 Initial Commit diff --git a/a_1authrowhook.asm b/a_1authrowhook.asm new file mode 100644 index 0000000..f65f076 --- /dev/null +++ b/a_1authrowhook.asm @@ -0,0 +1,30 @@ +; crinkle the linkers load order +; a.obj < (anything else).obj +; A/B/C:\... < ntstc_msvcrt's d:\os\obj\... + +PUBLIC _CxxThrowException +EXTERN _CxxThrowExceptionHook : proc +EXTERN CXX_THROW_REFERENCE : qword + +.code + +_CxxThrowException PROC + MOV R8, [RSP] + + push RCX + push RDX + + SUB RSP, 24 ; yo wtf, we have [0, -8], [-8, -8], [-16, -8] writes in our stack?! stdcall compiler optimizer conflicting with the reality that stdcall does not exist under x64? + MOV RAX, [_CxxThrowExceptionHook] + CALL RAX + add rsp, 24 + pop RDX + pop RCX + + xor rax, rax + + jmp CXX_THROW_REFERENCE + ret +_CxxThrowException ENDP + +END \ No newline at end of file diff --git a/demo.cpp b/demo.cpp new file mode 100644 index 0000000..5ff217a --- /dev/null +++ b/demo.cpp @@ -0,0 +1,120 @@ +#include +#include +#include + +extern "C" size_t CXX_THROW_REFERENCE = 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) +static bool DoMagic(void *exception, const ThrowInfo *throwInfo, void *caller) +{ + if (!throwInfo) return false; + + 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; + } + + return true; +} + +extern "C" void __stdcall _CxxThrowExceptionHook( + void *pExceptionObject, + void * pThrowInfo, + void *caller +) +{ + DoMagic(pExceptionObject, (ThrowInfo *)pThrowInfo, caller); +} + +int main() +{ + CXX_THROW_REFERENCE = (size_t)GetProcAddress(LoadLibraryW(L"ucrtbase.dll"), "_CxxThrowException"); + try + { + throw std::exception("hello"); + std::cout << "cont?!!\n"; + + } + catch (...) + { + std::cout << "caught!\n"; + } +} \ No newline at end of file