Initial Commit

This commit is contained in:
Reece Wilson 2022-01-23 02:32:46 +00:00
commit 859c35d175
2 changed files with 150 additions and 0 deletions

30
a_1authrowhook.asm Normal file
View File

@ -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

120
demo.cpp Normal file
View File

@ -0,0 +1,120 @@
#include <Windows.h>
#include <iostream>
#include <ehdata.h>
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<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;
}
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";
}
}