stacker/src/main.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;
}