423 lines
15 KiB
C
423 lines
15 KiB
C
//clang -v -std=c11 -g -gcodeview -O0 main.c -o main.exe -LF:/carpincho/cositas/luar/src -ldlltest -Wl,--pdb=
|
|
#include <stdio.h>
|
|
#include <stdarg.h>
|
|
#include <Windows.h>
|
|
#include <dbghelp.h>
|
|
#include <stdbool.h>
|
|
|
|
#define IN
|
|
#define OUT
|
|
/* if ((m_hDbhHelp == NULL) && (GetEnvironmentVariable(_T("ProgramFiles"), szTemp, 4096) > 0)) */
|
|
/* { */
|
|
/* _tcscat_s(szTemp, _T("\\Debugging Tools for Windows (x64)\\dbghelp.dll")); */
|
|
/* // now check if the file exists: */
|
|
/* if (GetFileAttributes(szTemp) != INVALID_FILE_ATTRIBUTES) */
|
|
/* { */
|
|
/* m_hDbhHelp = LoadLibrary(szTemp); */
|
|
/* } */
|
|
/* } */
|
|
|
|
/* // SymFunctionTableAccess64() */
|
|
/* typedef PVOID(__stdcall* tSFTA)(HANDLE hProcess, DWORD64 AddrBase); */
|
|
/* tSFTA pSFTA; */
|
|
|
|
/* // SymGetModuleBase64() */
|
|
/* typedef DWORD64(__stdcall* tSGMB)(IN HANDLE hProcess, IN DWORD64 dwAddr); */
|
|
/* tSGMB pSGMB; */
|
|
|
|
/* // SymGetModuleInfo64() */
|
|
/* typedef BOOL(__stdcall* tSGMI)(IN HANDLE hProcess, */
|
|
/* IN DWORD64 dwAddr, */
|
|
/* OUT IMAGEHLP_MODULE64_V3* ModuleInfo); */
|
|
/* tSGMI pSGMI; */
|
|
|
|
#define MAXNAMELEN 1024
|
|
int max_recursion = 1000;
|
|
typedef struct CallstackEntry
|
|
{
|
|
DWORD64 offset; // if 0, we have no valid entry
|
|
CHAR name[MAXNAMELEN];
|
|
CHAR undName[MAXNAMELEN];
|
|
CHAR undFullName[MAXNAMELEN];
|
|
DWORD64 offsetFromSymbol;
|
|
DWORD offsetFromLine;
|
|
DWORD lineNumber;
|
|
CHAR lineFileName[MAXNAMELEN];
|
|
DWORD symType;
|
|
LPCSTR symTypeString;
|
|
CHAR moduleName[MAXNAMELEN];
|
|
DWORD64 baseOfImage;
|
|
CHAR loadedImageName[MAXNAMELEN];
|
|
} CallstackEntry;
|
|
|
|
void ClearCSEntryInline(CallstackEntry* csEntry)
|
|
{
|
|
csEntry->name[0] = 0;
|
|
csEntry->undName[0] = 0;
|
|
csEntry->undFullName[0] = 0;
|
|
csEntry->offsetFromSymbol = 0;
|
|
csEntry->offsetFromLine = 0;
|
|
csEntry->lineFileName[0] = 0;
|
|
csEntry->lineNumber = 0;
|
|
}
|
|
|
|
void ClearCSEntry(CallstackEntry* csEntry)
|
|
{
|
|
ClearCSEntryInline(csEntry);
|
|
csEntry->loadedImageName[0] = 0;
|
|
csEntry->moduleName[0] = 0;
|
|
csEntry->baseOfImage = 0;
|
|
}
|
|
|
|
typedef enum CallstackEntryType
|
|
{
|
|
firstEntry,
|
|
nextEntry,
|
|
lastEntry
|
|
} CallstackEntryType;
|
|
|
|
HMODULE dbghelp;
|
|
LONG WINAPI exception_handler(PEXCEPTION_POINTERS exception)
|
|
{
|
|
CallstackEntry cs_entry;
|
|
CallstackEntryType cs_entry_type = firstEntry;
|
|
int cur_recursion = 0;
|
|
//Debug attach window
|
|
MessageBoxExA(
|
|
NULL,
|
|
"time to attach debugger",
|
|
"debugging",
|
|
MB_ICONSTOP,
|
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL)
|
|
);
|
|
//Check if dbghelp is loaded
|
|
if (dbghelp == NULL) // if not already loaded, try to load a default-one
|
|
dbghelp = LoadLibrary("dbghelp.dll");
|
|
if (dbghelp == NULL)
|
|
FatalAppExitW(0, L"DbgHelp not loaded");
|
|
|
|
HANDLE current_process = GetCurrentProcess();
|
|
HANDLE current_thread = GetCurrentThread();
|
|
//CONTEXT hw_ctx = *(exception->ContextRecord);
|
|
CONTEXT hw_ctx; RtlCaptureContext(&hw_ctx);
|
|
unsigned long long frame_idx;
|
|
|
|
//SymInitialize To call the Unicode version of this function, define DBGHELP_TRANSLATE_TCHAR. SymCleanup
|
|
if (SymInitialize(current_process, NULL, FALSE) == FALSE)
|
|
printf("SymInitialize error: %lu", GetLastError());
|
|
|
|
//Stack frame64
|
|
STACKFRAME64 sf64;
|
|
memset(&sf64, 0, sizeof(sf64));
|
|
sf64.AddrPC.Mode = AddrModeFlat;
|
|
sf64.AddrFrame.Mode = AddrModeFlat;
|
|
sf64.AddrStack.Mode = AddrModeFlat;
|
|
sf64.AddrPC.Offset = exception->ContextRecord->Rip;
|
|
sf64.AddrStack.Offset = exception->ContextRecord->Rsp;
|
|
sf64.AddrFrame.Offset = exception->ContextRecord->Rsp;//Rbp,
|
|
|
|
//Image Help Symbol64 and SYMBOL_INFO
|
|
IMAGEHLP_SYMBOL64 *symbol = (IMAGEHLP_SYMBOL64*)calloc(1, sizeof(sizeof(IMAGEHLP_SYMBOL64) + MAXNAMELEN));
|
|
symbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);
|
|
symbol->MaxNameLength = MAXNAMELEN;
|
|
PSYMBOL_INFO symbol_info = (SYMBOL_INFO*)calloc(1, sizeof(SYMBOL_INFO) + MAXNAMELEN);
|
|
symbol_info->SizeOfStruct = sizeof(SYMBOL_INFO);
|
|
symbol_info->MaxNameLen = MAXNAMELEN;
|
|
|
|
//Image Help Source Line64
|
|
IMAGEHLP_LINE64 src_line;
|
|
memset(&src_line, 0, sizeof(IMAGEHLP_LINE64));
|
|
src_line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
|
|
|
|
/* BOOL stack_walked = StackWalk64( */
|
|
/* IMAGE_FILE_MACHINE_AMD64, */
|
|
/* current_process, */
|
|
/* current_thread, */
|
|
/* &sf64, */
|
|
/* &hw_ctx, */
|
|
/* NULL, */
|
|
/* SymFunctionTableAccess, */
|
|
/* SymGetModuleBase, */
|
|
/* NULL); */
|
|
bool last_entry_called = true;
|
|
for (frame_idx = 0;; ++frame_idx)
|
|
{
|
|
// get next stack frame (StackWalk64(), SymFunctionTableAccess64(), SymGetModuleBase64())
|
|
// if this returns ERROR_INVALID_ADDRESS (487) or ERROR_NOACCESS (998), you can
|
|
// assume that either you are done, or that the stack is so hosed that the next
|
|
// deeper frame could not be found.
|
|
// CONTEXT need not to be supplied if imageTyp is IMAGE_FILE_MACHINE_I386!
|
|
BOOL stack_walked = StackWalk64(
|
|
IMAGE_FILE_MACHINE_AMD64,
|
|
current_process,
|
|
current_thread,
|
|
&sf64,
|
|
&hw_ctx,
|
|
NULL,
|
|
SymFunctionTableAccess,
|
|
SymGetModuleBase,
|
|
NULL);
|
|
//if (!this->m_sw->pSW(imageType, this->m_hProcess, hThread, &s, &c, myReadProcMem,
|
|
//this->m_sw->pSFTA, this->m_sw->pSGMB, NULL))
|
|
if (!stack_walked)
|
|
{
|
|
// INFO: "StackWalk64" does not set "GetLastError"...
|
|
printf("StackWalk64 %llu", sf64.AddrPC.Offset);
|
|
break;
|
|
}
|
|
|
|
cs_entry.offset = sf64.AddrPC.Offset;
|
|
ClearCSEntry(&cs_entry);
|
|
|
|
// make sure the location of the calling function is reported, and not of the next statement
|
|
if (frame_idx != 0 && cs_entry.offset != 0)
|
|
cs_entry.offset--;
|
|
|
|
if (sf64.AddrPC.Offset == sf64.AddrReturn.Offset)
|
|
{
|
|
if ((max_recursion > 0) && (cur_recursion > max_recursion))
|
|
{
|
|
printf("StackWalk64-EndlessCallstack %llu", sf64.AddrPC.Offset);
|
|
break;
|
|
}
|
|
cur_recursion++;
|
|
}
|
|
else
|
|
cur_recursion = 0;
|
|
|
|
if (cs_entry.offset != 0)
|
|
{
|
|
// we seem to have a valid PC
|
|
IMAGEHLP_MODULE64* module_info = (IMAGEHLP_MODULE64*)calloc(1, sizeof(module_info));
|
|
module_info->SizeOfStruct = sizeof(IMAGEHLP_MODULE64);
|
|
// show module info (SymGetModuleInfo64())
|
|
if (SymGetModuleInfo64(current_process, cs_entry.offset, module_info) != FALSE)
|
|
{ // got module info OK
|
|
switch (module_info->SymType)
|
|
{
|
|
case SymNone:
|
|
cs_entry.symTypeString = "-nosymbols-";
|
|
break;
|
|
case SymCoff:
|
|
cs_entry.symTypeString = "COFF";
|
|
break;
|
|
case SymCv:
|
|
cs_entry.symTypeString = "CV";
|
|
break;
|
|
case SymPdb:
|
|
cs_entry.symTypeString = "PDB";
|
|
break;
|
|
case SymExport:
|
|
cs_entry.symTypeString = "-exported-";
|
|
break;
|
|
case SymDeferred:
|
|
cs_entry.symTypeString = "-deferred-";
|
|
break;
|
|
case SymSym:
|
|
cs_entry.symTypeString = "SYM";
|
|
break;
|
|
#if API_VERSION_NUMBER >= 9
|
|
case SymDia:
|
|
cs_entry.symTypeString = "DIA";
|
|
break;
|
|
#endif
|
|
case 8: //SymVirtual:
|
|
cs_entry.symTypeString = "Virtual";
|
|
break;
|
|
default:
|
|
//_snprintf( ty, sizeof(ty), "symtype=%ld", (long) Module.SymType );
|
|
cs_entry.symTypeString = NULL;
|
|
break;
|
|
}
|
|
//todo: calloc
|
|
//cs_entry.moduleName = calloc(MAXNAMELEN, sizeof(char));
|
|
//cs_entry.loadedImageName = calloc(MAXNAMELEN, sizeof(char));
|
|
strncpy(cs_entry.moduleName, module_info->ModuleName, MAXNAMELEN - 1);
|
|
strncpy(cs_entry.loadedImageName, module_info->LoadedImageName, MAXNAMELEN - 1);
|
|
cs_entry.baseOfImage = module_info->BaseOfImage;
|
|
} // got module info OK
|
|
else
|
|
{
|
|
printf("SymGetModuleInfo64 error: %lu offset %llu", GetLastError(), cs_entry.offset);
|
|
}
|
|
|
|
// show inline frames (SymAddrIncludeInlineTrace())
|
|
/* if (this->m_sw->pSAIIT != NULL) */
|
|
/* { */
|
|
/* if (DWORD inlineFrames = this->m_sw->pSAIIT(this->m_hProcess, cs_entry.offset)) */
|
|
/* { */
|
|
/* DWORD inlineContext, frameIndex; */
|
|
/* // SymQueryInlineTrace() */
|
|
/* if (this->m_sw->pSQIT(this->m_hProcess, cs_entry.offset, 0, cs_entry.offset, cs_entry.offset, */
|
|
/* &inlineContext, &frameIndex) != FALSE) */
|
|
/* { */
|
|
/* for (DWORD fi = 0; fi < inlineFrames; fi++) */
|
|
/* { */
|
|
/* // SymFromInlineContext() */
|
|
/* if (this->m_sw->pSFIC(this->m_hProcess, cs_entry.offset, inlineContext, */
|
|
/* &(cs_entry.offsetFromSymbol), pSymInfo) != FALSE) */
|
|
/* { */
|
|
/* MyStrCpy(cs_entry.name, MAXNAMELEN, pSymInfo->Name); */
|
|
/* // UnDecorateSymbolName() */
|
|
/* this->m_sw->pUDSN(pSymInfo->Name, cs_entry.undName, MAXNAMELEN, */
|
|
/* UNDNAME_NAME_ONLY); */
|
|
/* this->m_sw->pUDSN(pSymInfo->Name, cs_entry.undFullName, MAXNAMELEN, */
|
|
/* UNDNAME_COMPLETE); */
|
|
/* } */
|
|
/* else */
|
|
/* { */
|
|
/* this->OnDbgHelpErr("SymFromInlineContext", GetLastError(), cs_entry.offset); */
|
|
/* } */
|
|
|
|
/* // SymGetLineFromInlineContext() */
|
|
/* if (this->m_sw->pSGLFIC(this->m_hProcess, cs_entry.offset, inlineContext, 0, */
|
|
/* &(cs_entry.offsetFromLine), &Line) != FALSE) */
|
|
/* { */
|
|
/* cs_entry.lineNumber = Line.LineNumber; */
|
|
/* MyStrCpy(cs_entry.lineFileName, MAXNAMELEN, Line.FileName); */
|
|
/* } */
|
|
/* else */
|
|
/* { */
|
|
/* this->OnDbgHelpErr("SymGetLineFromInlineContext", GetLastError(), cs_entry.offset); */
|
|
/* } */
|
|
|
|
/* last_entry_called = false; */
|
|
/* this->OnCallstackEntry(cs_entry_type, cs_entry); */
|
|
/* cs_entry_type = nextEntry; */
|
|
|
|
/* ClearCSEntryInline(cs_entry); */
|
|
/* inlineContext++; */
|
|
/* } */
|
|
/* } */
|
|
/* else */
|
|
/* { */
|
|
/* this->OnDbgHelpErr("SymQueryInlineTrace", GetLastError(), cs_entry.offset); */
|
|
/* } */
|
|
/* } */
|
|
/* } */
|
|
|
|
// show procedure info (SymGetSymFromAddr64())
|
|
unsigned long long displacement = 0;
|
|
|
|
/* if (this->m_sw->pSGSFA(this->m_hProcess, cs_entry.offset, &displacement,//&(cs_entry.offsetFromSymbol), */
|
|
/* symbol) != FALSE) SymFromAddr*/
|
|
if (SymGetSymFromAddr64(current_process, cs_entry.offset, &displacement, symbol) != FALSE)
|
|
{
|
|
//cs_entry.name = calloc(MAXNAMELEN, sizeof(char));
|
|
strncpy(cs_entry.name, symbol->Name, MAXNAMELEN - 1);
|
|
// UnDecorateSymbolName()
|
|
UnDecorateSymbolName(symbol->Name, cs_entry.undName, MAXNAMELEN, UNDNAME_NAME_ONLY);
|
|
UnDecorateSymbolName(symbol->Name, cs_entry.undFullName, MAXNAMELEN, UNDNAME_COMPLETE);
|
|
}
|
|
else
|
|
{
|
|
printf("SymGetSymFromAddr64 error: %lu offset %llu", GetLastError(), cs_entry.offset);
|
|
}
|
|
|
|
// show line number info, NT5.0-method (SymGetLineFromAddr64())
|
|
|
|
// yes, we have SymGetLineFromAddr64()
|
|
/* if (this->m_sw->pSGLFA(this->m_hProcess, cs_entry.offset, &(cs_entry.offsetFromLine), */
|
|
/* &src_line) != FALSE) */
|
|
if (SymGetLineFromAddr64(current_process, cs_entry.offset, &(cs_entry.offsetFromLine), &src_line) != FALSE)
|
|
{
|
|
cs_entry.lineNumber = src_line.LineNumber;
|
|
//cs_entry.lineFileName = calloc(MAXNAMELEN, sizeof(char));
|
|
strncpy(cs_entry.lineFileName, symbol->Name, MAXNAMELEN - 1);
|
|
}
|
|
else
|
|
{
|
|
printf("SymGetLineFromAddr64 error: %lu offset %llu", GetLastError(), cs_entry.offset);
|
|
}
|
|
// yes, we have SymGetLineFromAddr64()
|
|
} // we seem to have a valid PC
|
|
|
|
last_entry_called = false;
|
|
//this->OnCallstackEntry(cs_entry_type, cs_entry);
|
|
cs_entry_type = nextEntry;
|
|
printf("%p (%s): %s: %s\n", (LPVOID)cs_entry.offset, cs_entry.moduleName,
|
|
cs_entry.lineFileName, cs_entry.name);
|
|
if (sf64.AddrReturn.Offset == 0)
|
|
{
|
|
last_entry_called = true;
|
|
printf("%s (%lu): %s\n", cs_entry.lineFileName, cs_entry.lineNumber, cs_entry.name);
|
|
SetLastError(ERROR_SUCCESS);
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
//MsgBox---------------------------------------------------------------------------------------------------------------------------
|
|
//System sounds sound
|
|
MessageBeep(MB_ICONERROR);
|
|
|
|
int bufsize = 4096;
|
|
char* message = calloc(bufsize, 1);
|
|
int consumed = 0;
|
|
consumed += snprintf(message, bufsize,
|
|
"Got an unhandled exception.\
|
|
Exception code: 0x%lx\nContinuable: %lu\nAddress: 0x%016llx\n",
|
|
exception->ExceptionRecord->ExceptionCode,
|
|
exception->ExceptionRecord->ExceptionFlags,
|
|
exception->ExceptionRecord->ExceptionAddress);
|
|
if(exception->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION && exception->ExceptionRecord->NumberParameters == 2)
|
|
{
|
|
printf("hey %d", consumed);
|
|
consumed += snprintf(message + consumed, bufsize - consumed,
|
|
"\tOperation type: %llu\tVirtualAddr: 0x%016llx",
|
|
exception->ExceptionRecord->ExceptionInformation[0],
|
|
exception->ExceptionRecord->ExceptionInformation[1]);
|
|
}
|
|
if(exception->ExceptionRecord->ExceptionCode == EXCEPTION_IN_PAGE_ERROR && exception->ExceptionRecord->NumberParameters == 3)
|
|
{
|
|
consumed += snprintf(message + consumed, bufsize - consumed,
|
|
"\tOperation type: %llu\tVirtualAddr: 0x%016llx\tNTSTATUS code:%llu",
|
|
exception->ExceptionRecord->ExceptionInformation[0],
|
|
exception->ExceptionRecord->ExceptionInformation[1],
|
|
exception->ExceptionRecord->ExceptionInformation[2]);
|
|
}
|
|
MessageBoxExA(
|
|
NULL,
|
|
message,
|
|
"Fatal Crash",
|
|
MB_ICONERROR,
|
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL)
|
|
);
|
|
|
|
//Console---------------------------------------------------------------------------------------------------------------------------
|
|
printf("Got an unhandled exception.\n");
|
|
printf("Exception code: 0x%lx\nContinuable: %lu\nAddress: 0x%016llx\n",
|
|
exception->ExceptionRecord->ExceptionCode,
|
|
exception->ExceptionRecord->ExceptionFlags,
|
|
exception->ExceptionRecord->ExceptionAddress);
|
|
if(exception->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION && exception->ExceptionRecord->NumberParameters == 2)
|
|
{
|
|
printf("\tOperation type: %llu\tVirtualAddr: 0x%016llx",
|
|
exception->ExceptionRecord->ExceptionInformation[0],
|
|
exception->ExceptionRecord->ExceptionInformation[1]);
|
|
}
|
|
if(exception->ExceptionRecord->ExceptionCode == EXCEPTION_IN_PAGE_ERROR && exception->ExceptionRecord->NumberParameters == 3)
|
|
{
|
|
printf("\tOperation type: %llu\tVirtualAddr: 0x%016llx\tNTSTATUS code:%llu",
|
|
exception->ExceptionRecord->ExceptionInformation[0],
|
|
exception->ExceptionRecord->ExceptionInformation[1],
|
|
exception->ExceptionRecord->ExceptionInformation[2]);
|
|
}
|
|
|
|
|
|
|
|
//FatalAppExitW
|
|
//FatalAppExitW(0, L"bro");
|
|
return EXCEPTION_CONTINUE_SEARCH;
|
|
}
|
|
|
|
int main() {
|
|
unsigned int em = SetErrorMode(0);
|
|
LPTOP_LEVEL_EXCEPTION_FILTER filter = SetUnhandledExceptionFilter(exception_handler);
|
|
printf("prints\n");
|
|
int *cosa = NULL;
|
|
int b = 0;
|
|
int a = 4 + *cosa;
|
|
//printf("%d", numerito);
|
|
return 0;
|
|
}
|