diff --git a/src/main.c b/src/main.c index beeb791..16d4427 100644 --- a/src/main.c +++ b/src/main.c @@ -1,5 +1,6 @@ //clang -v -std=c11 -g -gcodeview -O0 main.c -o main.exe -LF:/carpincho/cositas/luar/src -ldlltest -Wl,--pdb= //clang -v -std=c11 -g -gcodeview -O0 src/main.c -o main.exe -ldbghelp -Wl,--pdb= +//clang -v -std=c11 -g -ginline-line-tables -gcodeview -O1 src/main.c -o main.exe -ldbghelp -Wl,--pdb=] #include #include #include @@ -10,6 +11,86 @@ #define OUT #define OPT + + +// Check whether input Address includes "inline stack". +extern DWORD +IMAGEAPI +SymAddrIncludeInlineTrace( + _In_ HANDLE hProcess, + _In_ DWORD64 Address + ); + +#define SYM_INLINE_COMP_ERROR 0 +#define SYM_INLINE_COMP_IDENTICAL 1 +#define SYM_INLINE_COMP_STEPIN 2 +#define SYM_INLINE_COMP_STEPOUT 3 +#define SYM_INLINE_COMP_STEPOVER 4 +#define SYM_INLINE_COMP_DIFFERENT 5 + +extern BOOL +IMAGEAPI +SymQueryInlineTrace( + _In_ HANDLE hProcess, + _In_ DWORD64 StartAddress, + _In_ DWORD StartContext, + _In_ DWORD64 StartRetAddress, + _In_ DWORD64 CurAddress, + _Out_ LPDWORD CurContext, + _Out_ LPDWORD CurFrameIndex + ); + +// flags for SymEnumSourceLines + +#define ESLFLAG_FULLPATH 0x00000001 +#define ESLFLAG_NEAREST 0x00000002 +#define ESLFLAG_PREV 0x00000004 +#define ESLFLAG_NEXT 0x00000008 +#define ESLFLAG_INLINE_SITE 0x00000010 + +extern BOOL +IMAGEAPI +SymFromInlineContext( + _In_ HANDLE hProcess, + _In_ DWORD64 Address, + _In_ ULONG InlineContext, + _Out_opt_ PDWORD64 Displacement, + _Inout_ PSYMBOL_INFO Symbol + ); + +BOOL +IMAGEAPI +SymFromInlineContextW( + _In_ HANDLE hProcess, + _In_ DWORD64 Address, + _In_ ULONG InlineContext, + _Out_opt_ PDWORD64 Displacement, + _Inout_ PSYMBOL_INFOW Symbol + ); + +extern BOOL +IMAGEAPI +SymGetLineFromInlineContext( + _In_ HANDLE hProcess, + _In_ DWORD64 qwAddr, + _In_ ULONG InlineContext, + _In_opt_ DWORD64 qwModuleBaseAddress, + _Out_ PDWORD pdwDisplacement, + _Out_ PIMAGEHLP_LINE64 Line64 + ); + +extern BOOL +IMAGEAPI +SymGetLineFromInlineContextW( + _In_ HANDLE hProcess, + _In_ DWORD64 dwAddr, + _In_ ULONG InlineContext, + _In_opt_ DWORD64 qwModuleBaseAddress, + _Out_ PDWORD pdwDisplacement, + _Out_ PIMAGEHLP_LINEW64 Line + ); + + BOOL __stdcall myReadProcMem(HANDLE hProcess, DWORD64 qwBaseAddress, PVOID lpBuffer, @@ -346,7 +427,7 @@ LONG WINAPI exception_handler(PEXCEPTION_POINTERS exception) symfo->SizeOfStruct = sizeof(SYMBOL_INFO); symfo->MaxNameLen = MAXNAMELEN; //if (SymGetSymFromAddr64(current_process, cs_entry.offset, &(cs_entry.offsetFromSymbol), symbol) != FALSE) - if (SymFromAddr(current_process, sf64.AddrPC.Offset, 0, symfo) != FALSE) + if (SymFromAddr(current_process, sf64.AddrPC.Offset, NULL, symfo) != FALSE) { //cs_entry.name = calloc(MAXNAMELEN, sizeof(char)); strncpy(cs_entry.name, symbol->Name, MAXNAMELEN - 1); @@ -389,7 +470,7 @@ LONG WINAPI exception_handler(PEXCEPTION_POINTERS exception) SetLastError(ERROR_SUCCESS); break; } - } + } //MsgBox--------------------------------------------------------------------------------------------------------------------------- @@ -453,18 +534,21 @@ LONG WINAPI exception_handler(PEXCEPTION_POINTERS exception) //FatalAppExitW //FatalAppExitW(0, L"bro"); - return EXCEPTION_CONTINUE_SEARCH; -} + return EXCEPTION_CONTINUE_SEARCH;} + +#define SR_MAXNAMELEN 1024 +#define SR_MAXRECURSIONCOUNT 1000 typedef struct StackFrameEntry { DWORD64 address; - char name[MAXNAMELEN]; - char module[MAXNAMELEN]; + char name[SR_MAXNAMELEN]; + char module[SR_MAXNAMELEN]; unsigned int line; - char file[MAXNAMELEN]; + char file[SR_MAXNAMELEN]; } StackFrameEntry; + LONG WINAPI second_try(PEXCEPTION_POINTERS exception) { //Debug attach window @@ -516,44 +600,181 @@ CONTEXT context = *(exception->ContextRecord); bool first = true; + int recursion_count = 0; + while (StackWalk(machine, process, thread, &frame, &context , NULL, SymFunctionTableAccess, SymGetModuleBase, NULL)) + { + StackFrameEntry f = {}; + /* //TODO: make sure the location of the calling function is reported, and not of the next statement */ + /* if (frameNum != 0 && csEntry.offset != 0) */ + /* csEntry.offset--; */ + + //Preventing infinite recursion from leaking + if (frame.AddrPC.Offset == frame.AddrReturn.Offset) + { + if ((SR_MAXRECURSIONCOUNT > 0) && (recursion_count > SR_MAXRECURSIONCOUNT)) + { + printf("StackWalk64 error: Infinite callstack offset %llu", frame.AddrPC.Offset); + break; + } + recursion_count++; + } + else + { + recursion_count = 0; + } + + f.address = frame.AddrPC.Offset; + // make sure the location of the calling function is reported, and not of the next statement + if (!first && f.address != 0) + f.address--; -/* Prev: used symfun y symget 32 std::vector frames; */ - while (StackWalk(machine, process, thread, &frame, &context , NULL, SymFunctionTableAccess64, SymGetModuleBase64, NULL)) - { - StackFrameEntry f = {}; - f.address = frame.AddrPC.Offset; - #if _WIN64 - DWORD64 moduleBase = 0; - #else - DWORD moduleBase = 0; - #endif - //Prev: used symgetmodulebase32 - moduleBase = SymGetModuleBase64(process, frame.AddrPC.Offset); + IMAGEHLP_MODULE64* module_info = (IMAGEHLP_MODULE64*)calloc(1, sizeof(IMAGEHLP_MODULE64)); + module_info->SizeOfStruct = sizeof(IMAGEHLP_MODULE64); + // show module info (SymGetModuleInfo64()) + if (SymGetModuleInfo64(process, f.address, module_info) != FALSE) + { // got module info OK + switch (module_info->SymType) + { + case SymNone: + printf("-nosymbols-"); + break; + case SymCoff: + printf("COFF"); + break; + case SymCv: + printf("CV"); + break; + case SymPdb: + printf("PDB"); + break; + case SymExport: + printf("-exported-"); + break; + case SymDeferred: + printf("-deferred-"); + break; + case SymSym: + printf("SYM"); + break; +#if API_VERSION_NUMBER >= 9 + case SymDia: + printf("DIA"); + break; +#endif + case 8: //SymVirtual: + printf("Virtual"); + break; + default: + printf("symtype=%ld", (long) module_info->SymType ); + //cs_entry.symTypeString = NULL; + break; + } + printf(" "); + strcpy(f.module, module_info->LoadedImageName); + //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(), f.address); + } - char moduleBuff[MAX_PATH]; - if (!(moduleBase && GetModuleFileNameA((HINSTANCE)moduleBase, &(f.module), MAXNAMELEN))) - /* { */ - /* f.module = basename(moduleBuff); */ - /* } */ - /* else */ - { - strcpy(f.module, "Unknown Module"); - } #if _WIN64 DWORD64 offset = 0; #else DWORD offset = 0; #endif - //Prev: imagehlp_symbol32 - char symbolBuffer[sizeof(IMAGEHLP_SYMBOL64) + MAXNAMELEN]; - PIMAGEHLP_SYMBOL64 symbol = (PIMAGEHLP_SYMBOL64)symbolBuffer; - symbol->SizeOfStruct = (sizeof(IMAGEHLP_SYMBOL64) + MAXNAMELEN); - symbol->MaxNameLength = MAXNAMELEN; - if (SymGetSymFromAddr64(process, frame.AddrPC.Offset, &offset, symbol)) + char stackmem[sizeof(SYMBOL_INFO) + SR_MAXNAMELEN]; + PSYMBOL_INFO symfo = (SYMBOL_INFO*)stackmem; + symfo->SizeOfStruct = sizeof(SYMBOL_INFO); + symfo->MaxNameLen = SR_MAXNAMELEN; + + IMAGEHLP_LINE line; + line.SizeOfStruct = sizeof(IMAGEHLP_LINE); + +//--------------------------------- Inline danger zone--------------------------------------------- + + /* pSAIIT = (tSAIIT)GetProcAddress(m_hDbhHelp, "SymAddrIncludeInlineTrace"); */ + /* pSQIT = (tSQIT)GetProcAddress(m_hDbhHelp, "SymQueryInlineTrace"); */ + /* pSFIC = (tSFIC)GetProcAddress(m_hDbhHelp, "SymFromInlineContext"); */ + /* pSGLFIC = (tSGLFIC)GetProcAddress(m_hDbhHelp, "SymGetLineFromInlineContext"); */ + + // show inline frames (SymAddrIncludeInlineTrace()) + /* if (dbghelp == NULL) // if not already loaded, try to load a default-one */ + /* dbghelp = LoadLibrary("C:\\Program Files (x86)\\Windows Kits\\10\\Debuggers\\x64\\dbghelp.dll"); */ + /* if (dbghelp == NULL) */ + /* FatalAppExitW(0, L"DbgHelp not loaded"); */ + /* unsigned long long saiit = (unsigned long long)GetProcAddress(dbghelp, "SymAddrIncludeInlineTrace"); */ + DWORD inline_frames = SymAddrIncludeInlineTrace(process, f.address); + if (inline_frames) + { + DWORD inlineContext, frameIndex; + if (SymQueryInlineTrace(process, f.address, 0, f.address, f.address, + &inlineContext, &frameIndex) != FALSE) + { + for (DWORD fi = 0; fi < inline_frames; fi++) + { + DWORD64 offset_inline = 0; + if (SymFromInlineContext(process, f.address, inlineContext, + &(offset_inline), symfo) != FALSE) + { + strcpy(f.name, symfo->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 + { + printf("SymFromInlineContext error: %lu offset %llu", GetLastError(), f.address); + } + + DWORD offset_inline_ln = 0; + if (SymGetLineFromInlineContext(process, f.address, inlineContext, 0, + &(offset_inline_ln), &line) != FALSE) + { + strcpy(f.file, line.FileName); + f.line = line.LineNumber; + } + else + { + printf("SymGetLineFromInlineContext error: %lu offset %llu", GetLastError(), f.address); + + } + + //last_entry_called = false; + //this->OnCallstackEntry(cs_entry_type, cs_entry); + //cs_entry_type = nextEntry; + + //ClearCSEntryInline(cs_entry); + inlineContext++; + } + } + else + { + printf("SymQueryInlinetrace error: %lu offset %llu", GetLastError(), f.address); + } + } + +//--------------------------------- End of inline zone-------------------------------------------- + + /* //Prev: imagehlp_symbol32 */ + /* char symbolBuffer[sizeof(IMAGEHLP_SYMBOL) + SR_MAXNAMELEN]; */ + /* PIMAGEHLP_SYMBOL symbol = (PIMAGEHLP_SYMBOL)symbolBuffer; */ + /* symbol->SizeOfStruct = (sizeof(IMAGEHLP_SYMBOL) + SR_MAXNAMELEN); */ + /* symbol->MaxNameLength = SR_MAXNAMELEN; */ + /* //SymGetSymFromAddr(process, f.address, &offset, symbol)) */ + + if (SymFromAddr(process, f.address, &offset, symfo)) { - strcpy(f.name, symbol->Name); + strcpy(f.name, symfo->Name); } else { @@ -562,12 +783,8 @@ CONTEXT context = *(exception->ContextRecord); strcpy(f.name, "Unknown Function"); } - //Prev: imagehlp line32 - IMAGEHLP_LINE64 line; - line.SizeOfStruct = sizeof(IMAGEHLP_LINE64); - DWORD offset_ln = 0; - if (SymGetLineFromAddr(process, frame.AddrPC.Offset, &offset_ln, &line)) + if (SymGetLineFromAddr(process, f.address, &offset_ln, &line)) { strcpy(f.file, line.FileName); f.line = line.LineNumber; @@ -583,8 +800,8 @@ CONTEXT context = *(exception->ContextRecord); /* { */ /* frames.push_back(f); */ /* } */ - printf("%p (%s): %s: %u\n", (LPVOID)f.address, f.module, - f.file, f.line); + printf("%p (%s): %s: %s: %u\n", (LPVOID)f.address, f.module, + f.file, f.name, f.line); first = false; } @@ -592,15 +809,30 @@ CONTEXT context = *(exception->ContextRecord); return EXCEPTION_CONTINUE_SEARCH; - } + } + +static inline int sumatorio(int a, int b) +{ + strcpy((void*)0, "a"); + return a + b; +} + +int truquis() { + int *cosa = NULL; + int b = 0; + //int c = sumatorio(1,2); + return 4 + *cosa; +} int main() { unsigned int em = SetErrorMode(0); LPTOP_LEVEL_EXCEPTION_FILTER filter = SetUnhandledExceptionFilter(second_try); printf("prints\n"); - int *cosa = NULL; - int b = 0; - int a = 4 + *cosa; + /* int *cosa = NULL; */ + /* int b = 0; */ + /* int a = 4 + *cosa; */ + truquis(); //printf("%d", numerito); return 0; } +