Skip to content

Commit

Permalink
Crash handler integrated into SpecialK
Browse files Browse the repository at this point in the history
  • Loading branch information
Kaldaien committed Jun 13, 2016
1 parent 26c0662 commit 94621db
Show file tree
Hide file tree
Showing 4 changed files with 6 additions and 302 deletions.
4 changes: 3 additions & 1 deletion UnX/UnX.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<EnablePREfast>false</EnablePREfast>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<OmitDefaultLibName>false</OmitDefaultLibName>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
Expand All @@ -147,7 +148,8 @@
<MapExports>true</MapExports>
<SupportUnloadOfDelayLoadedDLL>true</SupportUnloadOfDelayLoadedDLL>
<SupportNobindOfDelayLoadedDLL>true</SupportNobindOfDelayLoadedDLL>
<FullProgramDatabaseFile>true</FullProgramDatabaseFile>
<FullProgramDatabaseFile>false</FullProgramDatabaseFile>
<AssemblyDebug>false</AssemblyDebug>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
Expand Down
300 changes: 1 addition & 299 deletions UnX/compatibility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,6 @@
#include "hook.h"
#include "log.h"

#define _NO_CVCONST_H
#include <dbghelp.h>

#pragma comment( lib, "dbghelp.lib" )

typedef HMODULE (WINAPI *LoadLibraryA_pfn)(LPCSTR lpFileName);
typedef HMODULE (WINAPI *LoadLibraryW_pfn)(LPCWSTR lpFileName);

Expand Down Expand Up @@ -190,302 +185,9 @@ LoadLibraryExW_Detour (
return hMod;
}

#include "window.h"

LONG
WINAPI
UNX_TopLevelExceptionFilter ( _In_ struct _EXCEPTION_POINTERS *ExceptionInfo )
{
static bool last_chance = false;

static CONTEXT last_ctx = { 0 };
static EXCEPTION_RECORD last_exc = { 0 };

if (last_chance)
return 0;

// On second chance it's pretty clear that no exception handler exists,
// terminate the software.
if (! memcmp (&last_ctx, ExceptionInfo->ContextRecord, sizeof CONTEXT)) {
if (! memcmp (&last_exc, ExceptionInfo->ExceptionRecord, sizeof EXCEPTION_RECORD)) {
extern HMODULE hDLLMod;
extern HMODULE hInjectorDLL;
extern BOOL APIENTRY DllMain (HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID /* lpReserved */);

last_chance = true;

// Shutdown the module gracefully
DllMain (hDLLMod, DLL_PROCESS_DETACH, nullptr);

// Shutdown Special K
FreeLibrary (hInjectorDLL); FreeLibrary (hInjectorDLL); FreeLibrary (hInjectorDLL);

// Then the app
SendMessage (unx::window.hwnd, WM_QUIT, 0, 0);
}
}

last_ctx = *ExceptionInfo->ContextRecord;
last_exc = *ExceptionInfo->ExceptionRecord;

std::wstring desc;

switch (ExceptionInfo->ExceptionRecord->ExceptionCode)
{
case EXCEPTION_ACCESS_VIOLATION:
desc = L"\t<< EXCEPTION_ACCESS_VIOLATION >>";
//L"The thread tried to read from or write to a virtual address "
//L"for which it does not have the appropriate access.";
break;

case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
desc = L"\t<< EXCEPTION_ARRAY_BOUNDS_EXCEEDED >>";
//L"The thread tried to access an array element that is out of "
//L"bounds and the underlying hardware supports bounds checking.";
break;

case EXCEPTION_BREAKPOINT:
desc = L"\t<< EXCEPTION_BREAKPOINT >>";
//L"A breakpoint was encountered.";
break;

case EXCEPTION_DATATYPE_MISALIGNMENT:
desc = L"\t<< EXCEPTION_DATATYPE_MISALIGNMENT >>";
//L"The thread tried to read or write data that is misaligned on "
//L"hardware that does not provide alignment.";
break;

case EXCEPTION_FLT_DENORMAL_OPERAND:
desc = L"\t<< EXCEPTION_FLT_DENORMAL_OPERAND >>";
//L"One of the operands in a floating-point operation is denormal.";
break;

case EXCEPTION_FLT_DIVIDE_BY_ZERO:
desc = L"\t<< EXCEPTION_FLT_DIVIDE_BY_ZERO >>";
//L"The thread tried to divide a floating-point value by a "
//L"floating-point divisor of zero.";
break;

case EXCEPTION_FLT_INEXACT_RESULT:
desc = L"\t<< EXCEPTION_FLT_INEXACT_RESULT >>";
//L"The result of a floating-point operation cannot be represented "
//L"exactly as a decimal fraction.";
break;

case EXCEPTION_FLT_INVALID_OPERATION:
desc = L"\t<< EXCEPTION_FLT_INVALID_OPERATION >>";
break;

case EXCEPTION_FLT_OVERFLOW:
desc = L"\t<< EXCEPTION_FLT_OVERFLOW >>";
//L"The exponent of a floating-point operation is greater than the "
//L"magnitude allowed by the corresponding type.";
break;

case EXCEPTION_FLT_STACK_CHECK:
desc = L"\t<< EXCEPTION_FLT_STACK_CHECK >>";
//L"The stack overflowed or underflowed as the result of a "
//L"floating-point operation.";
break;

case EXCEPTION_FLT_UNDERFLOW:
desc = L"\t<< EXCEPTION_FLT_UNDERFLOW >>";
//L"The exponent of a floating-point operation is less than the "
//L"magnitude allowed by the corresponding type.";
break;

case EXCEPTION_ILLEGAL_INSTRUCTION:
desc = L"\t<< EXCEPTION_ILLEGAL_INSTRUCTION >>";
//L"The thread tried to execute an invalid instruction.";
break;

case EXCEPTION_IN_PAGE_ERROR:
desc = L"\t<< EXCEPTION_IN_PAGE_ERROR >>";
//L"The thread tried to access a page that was not present, "
//L"and the system was unable to load the page.";
break;

case EXCEPTION_INT_DIVIDE_BY_ZERO:
desc = L"\t<< EXCEPTION_INT_DIVIDE_BY_ZERO >>";
//L"The thread tried to divide an integer value by an integer "
//L"divisor of zero.";
break;

case EXCEPTION_INT_OVERFLOW:
desc = L"\t<< EXCEPTION_INT_OVERFLOW >>";
//L"The result of an integer operation caused a carry out of the "
//L"most significant bit of the result.";
break;

case EXCEPTION_INVALID_DISPOSITION:
desc = L"\t<< EXCEPTION_INVALID_DISPOSITION >>";
//L"An exception handler returned an invalid disposition to the "
//L"exception dispatcher.";
break;

case EXCEPTION_NONCONTINUABLE_EXCEPTION:
desc = L"\t<< EXCEPTION_NONCONTINUABLE_EXCEPTION >>";
//L"The thread tried to continue execution after a noncontinuable "
//L"exception occurred.";
break;

case EXCEPTION_PRIV_INSTRUCTION:
desc = L"\t<< EXCEPTION_PRIV_INSTRUCTION >>";
//L"The thread tried to execute an instruction whose operation is "
//L"not allowed in the current machine mode.";
break;

case EXCEPTION_SINGLE_STEP:
desc = L"\t<< EXCEPTION_SINGLE_STEP >>";
//L"A trace trap or other single-instruction mechanism signaled "
//L"that one instruction has been executed.";
break;

case EXCEPTION_STACK_OVERFLOW:
desc = L"\t<< EXCEPTION_STACK_OVERFLOW >>";
//L"The thread used up its stack.";
break;
}

HMODULE hModSource;
char szModName [MAX_PATH] = { '\0' };
DWORD64 eip = ExceptionInfo->ContextRecord->Eip;
HANDLE hProc = GetCurrentProcess ();

if (GetModuleHandleEx ( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
(LPCWSTR)eip,
&hModSource )) {
GetModuleFileNameA (hModSource, szModName, MAX_PATH);
}

DWORD BaseAddr =
SymGetModuleBase ( hProc, eip );

char* szDupName = strdup (szModName);
char* pszShortName = szDupName + lstrlenA (szDupName);

while ( pszShortName > szDupName &&
*(pszShortName - 1) != '\\')
--pszShortName;

dll_log.Log (L"-----------------------------------------------------------");
dll_log.Log (L"[! Except !] %s", desc.c_str ());
dll_log.Log (L"-----------------------------------------------------------");
dll_log.Log (L"[ FaultMod ] # File.....: '%hs'", szModName);
dll_log.Log (L"[ FaultMod ] * EIP Addr.: %hs+%ph", pszShortName, eip-BaseAddr);

dll_log.Log ( L"[StackFrame] <-> Eip=%08xh, Esp=%08xh, Ebp=%08xh",
eip,
ExceptionInfo->ContextRecord->Esp,
ExceptionInfo->ContextRecord->Ebp );
dll_log.Log ( L"[StackFrame] >-< Esi=%08xh, Edi=%08xh",
ExceptionInfo->ContextRecord->Esi,
ExceptionInfo->ContextRecord->Edi );

dll_log.Log ( L"[ GP Reg ] eax: 0x%08x",
ExceptionInfo->ContextRecord->Eax );
dll_log.Log ( L"[ GP Reg ] ebx: 0x%08x",
ExceptionInfo->ContextRecord->Ebx );
dll_log.Log ( L"[ GP Reg ] ecx: 0x%08x",
ExceptionInfo->ContextRecord->Ecx );
dll_log.Log ( L"[ GP Reg ] edx: 0x%08x",
ExceptionInfo->ContextRecord->Edx );
dll_log.Log ( L"[ GP Flags ] EFlags: 0x%08x",
ExceptionInfo->ContextRecord->EFlags );

SymLoadModule ( hProc,
nullptr,
szModName,
nullptr,
BaseAddr,
0 );

SYMBOL_INFO_PACKAGE sip;
sip.si.SizeOfStruct = sizeof SYMBOL_INFO;
sip.si.MaxNameLen = sizeof sip.name;

DWORD64 Displacement = 0;

if ( SymFromAddr ( hProc,
eip,
&Displacement,
&sip.si ) ) {
dll_log.Log (
L"-----------------------------------------------------------");

IMAGEHLP_LINE64 ihl64;
ihl64.SizeOfStruct = sizeof IMAGEHLP_LINE64;

DWORD Disp;
BOOL bFileAndLine =
SymGetLineFromAddr64 ( hProc, eip, &Disp, &ihl64 );

if (bFileAndLine) {
dll_log.Log ( L"[-(Source)-] [!] %hs <%hs:%lu>",
sip.si.Name,
ihl64.FileName,
ihl64.LineNumber );
} else {
dll_log.Log ( L"[--(Name)--] [!] %hs",
sip.si.Name );
}
}
dll_log.Log (L"-----------------------------------------------------------");

SymUnloadModule (GetCurrentProcess (), BaseAddr);

free (szDupName);

if (ExceptionInfo->ExceptionRecord->ExceptionFlags != EXCEPTION_NONCONTINUABLE)
return EXCEPTION_CONTINUE_EXECUTION;
else {
return UnhandledExceptionFilter (ExceptionInfo);
}
}

extern LONG WINAPI
UNX_TopLevelExceptionFilter ( _In_ struct _EXCEPTION_POINTERS *ExceptionInfo );


typedef LPTOP_LEVEL_EXCEPTION_FILTER (WINAPI *SetUnhandledExceptionFilter_pfn)(
_In_opt_ LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter
);
SetUnhandledExceptionFilter_pfn SetUnhandledExceptionFilter_Original = nullptr;


LPTOP_LEVEL_EXCEPTION_FILTER
WINAPI
SetUnhandledExceptionFilter_Detour (
_In_opt_ LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter
)
{
//if (lpTopLevelExceptionFilter != 0)
//return SetUnhandledExceptionFilter_Original (UNX_TopLevelExceptionFilter);

return SetUnhandledExceptionFilter_Original (lpTopLevelExceptionFilter);
}



void
UNX_InitCompatBlacklist (void)
{
SymInitialize (
GetCurrentProcess (),
NULL,
TRUE );

SymRefreshModuleList (GetCurrentProcess ());

SetErrorMode (SEM_NOGPFAULTERRORBOX | SEM_FAILCRITICALERRORS);
SetUnhandledExceptionFilter (UNX_TopLevelExceptionFilter);

UNX_CreateDLLHook ( L"kernel32.dll", "SetUnhandledExceptionFilter",
SetUnhandledExceptionFilter_Detour,
(LPVOID *)&SetUnhandledExceptionFilter_Original );

{
UNX_CreateDLLHook ( L"kernel32.dll", "LoadLibraryA",
LoadLibraryA_Detour,
(LPVOID*)&LoadLibraryA_Original );
Expand Down
2 changes: 1 addition & 1 deletion UnX/dllmain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ DllMain (HMODULE hModule,
UNX_VER_STR.c_str () );
dll_log.LogEx ( true, L"End unx.dll\n" );
dll_log.LogEx ( false, L"--------------- [Untitled X] "
L"---------------\n" );
L"---------------" );

dll_log.close ();
} break;
Expand Down
2 changes: 1 addition & 1 deletion UnX/parameter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ unx::ParameterInt64::set_value (int64_t val)
void
unx::ParameterInt64::set_value_str (std::wstring str)
{
value = _wtol (str.c_str ());
value = _wtoll (str.c_str ());
}


Expand Down

0 comments on commit 94621db

Please sign in to comment.