From 59e5e501b3cf7d6797e012c714ec49a5f0f7cee4 Mon Sep 17 00:00:00 2001 From: Hane Date: Tue, 16 Sep 2025 21:50:35 +0200 Subject: [PATCH] wip error SymGetModuleInfo64 mod nf --- src/main.c | 348 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 347 insertions(+), 1 deletion(-) diff --git a/src/main.c b/src/main.c index f73d17e..ae8c935 100644 --- a/src/main.c +++ b/src/main.c @@ -2,9 +2,352 @@ #include #include #include +#include +#include +#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); @@ -40,7 +383,8 @@ LONG WINAPI exception_handler(PEXCEPTION_POINTERS exception) 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, @@ -60,6 +404,8 @@ LONG WINAPI exception_handler(PEXCEPTION_POINTERS exception) exception->ExceptionRecord->ExceptionInformation[2]); } + + //FatalAppExitW //FatalAppExitW(0, L"bro"); return EXCEPTION_CONTINUE_SEARCH;