diff --git a/src/main.c b/src/main.c index ae8c935..beeb791 100644 --- a/src/main.c +++ b/src/main.c @@ -1,4 +1,5 @@ //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= #include #include #include @@ -7,6 +8,21 @@ #define IN #define OUT +#define OPT + +BOOL __stdcall myReadProcMem(HANDLE hProcess, + DWORD64 qwBaseAddress, + PVOID lpBuffer, + DWORD nSize, + LPDWORD lpNumberOfBytesRead) +{ + + SIZE_T st; + BOOL bRet = ReadProcessMemory(hProcess, (LPVOID)qwBaseAddress, lpBuffer, nSize, &st); + *lpNumberOfBytesRead = (DWORD)st; + //printf("ReadMemory: hProcess: %p, baseAddr: %p, buffer: %p, size: %d, read: %d, result: %d\n", hProcess, (LPVOID) qwBaseAddress, lpBuffer, nSize, (DWORD) st, (DWORD) bRet); + return bRet; +} /* if ((m_hDbhHelp == NULL) && (GetEnvironmentVariable(_T("ProgramFiles"), szTemp, 4096) > 0)) */ /* { */ /* _tcscat_s(szTemp, _T("\\Debugging Tools for Windows (x64)\\dbghelp.dll")); */ @@ -25,11 +41,28 @@ /* typedef DWORD64(__stdcall* tSGMB)(IN HANDLE hProcess, IN DWORD64 dwAddr); */ /* tSGMB pSGMB; */ +/* StackWalk64() */ +typedef BOOL(__stdcall* tSW)(DWORD MachineType, + HANDLE hProcess, + HANDLE hThread, + LPSTACKFRAME64 StackFrame, + PVOID ContextRecord, + PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine, + PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine, + PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine, + PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress); +tSW pSW; + +/* // SymInitialize() */ +typedef BOOL(__stdcall* tSI)(IN HANDLE hProcess, + IN OPT PCSTR dwAddr, + OUT BOOL fInvadeProcess); +tSI pSI; /* // SymGetModuleInfo64() */ -/* typedef BOOL(__stdcall* tSGMI)(IN HANDLE hProcess, */ -/* IN DWORD64 dwAddr, */ -/* OUT IMAGEHLP_MODULE64_V3* ModuleInfo); */ -/* tSGMI pSGMI; */ +typedef BOOL(__stdcall* tSGMI)(IN HANDLE hProcess, + IN DWORD64 dwAddr, + OUT IMAGEHLP_MODULE64* ModuleInfo); +tSGMI pSGMI; #define MAXNAMELEN 1024 int max_recursion = 1000; @@ -90,20 +123,27 @@ LONG WINAPI exception_handler(PEXCEPTION_POINTERS exception) 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"); + dbghelp = LoadLibrary("C:\\Program Files (x86)\\Windows Kits\\10\\Debuggers\\x64\\dbghelp.dll"); if (dbghelp == NULL) FatalAppExitW(0, L"DbgHelp not loaded"); - + + pSW = (tSW)GetProcAddress(dbghelp, "StackWalk64"); + pSI = (tSI)GetProcAddress(dbghelp, "SymInitialize"); + pSGMI = (tSGMI)GetProcAddress(dbghelp, "SymGetModuleInfo64"); + if(!pSGMI) + printf("Error loading function: %lu", GetLastError()); HANDLE current_process = GetCurrentProcess(); HANDLE current_thread = GetCurrentThread(); - //CONTEXT hw_ctx = *(exception->ContextRecord); - CONTEXT hw_ctx; RtlCaptureContext(&hw_ctx); + 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) + //if (pSI(current_process, NULL, TRUE) == FALSE) + if (SymInitialize(current_process, NULL, TRUE) == FALSE) printf("SymInitialize error: %lu", GetLastError()); //Stack frame64 @@ -147,16 +187,16 @@ LONG WINAPI exception_handler(PEXCEPTION_POINTERS exception) // 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); + BOOL stack_walked = StackWalk64( //pSW + IMAGE_FILE_MACHINE_AMD64, + current_process, + current_thread, + &sf64, + &hw_ctx, + myReadProcMem, + SymFunctionTableAccess64, + SymGetModuleBase64, + 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) @@ -192,6 +232,7 @@ LONG WINAPI exception_handler(PEXCEPTION_POINTERS exception) module_info->SizeOfStruct = sizeof(IMAGEHLP_MODULE64); // show module info (SymGetModuleInfo64()) if (SymGetModuleInfo64(current_process, cs_entry.offset, module_info) != FALSE) + //if (pSGMI(current_process, cs_entry.offset, module_info) != FALSE) { // got module info OK switch (module_info->SymType) { @@ -242,66 +283,70 @@ LONG WINAPI exception_handler(PEXCEPTION_POINTERS exception) } // 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); */ - /* } */ + /* 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); */ - /* } */ + /* // 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; */ + /* 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); */ - /* } */ - /* } */ + /* 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) + //symbol_info->Address = symbol->Address; + char stackmem[sizeof(SYMBOL_INFO) + MAXNAMELEN]; + PSYMBOL_INFO symfo = (SYMBOL_INFO*)stackmem; + 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) { //cs_entry.name = calloc(MAXNAMELEN, sizeof(char)); strncpy(cs_entry.name, symbol->Name, MAXNAMELEN - 1); @@ -411,9 +456,147 @@ LONG WINAPI exception_handler(PEXCEPTION_POINTERS exception) return EXCEPTION_CONTINUE_SEARCH; } +typedef struct StackFrameEntry +{ + DWORD64 address; + char name[MAXNAMELEN]; + char module[MAXNAMELEN]; + unsigned int line; + char file[MAXNAMELEN]; +} StackFrameEntry; + +LONG WINAPI second_try(PEXCEPTION_POINTERS exception) +{ + //Debug attach window + MessageBoxExA( + NULL, + "time to attach debugger", + "debugging", + MB_ICONSTOP, + MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL) + ); +#if _WIN64 + DWORD machine = IMAGE_FILE_MACHINE_AMD64; +#else + DWORD machine = IMAGE_FILE_MACHINE_I386; +#endif + HANDLE process = GetCurrentProcess(); + HANDLE thread = GetCurrentThread(); + + if (SymInitialize(process, NULL, TRUE) == FALSE) + { + printf("SymInitialize error: %lu", GetLastError()); + return EXCEPTION_CONTINUE_SEARCH; + } + +SymSetOptions(SYMOPT_LOAD_LINES); + +CONTEXT context = *(exception->ContextRecord); +//context.ContextFlags = CONTEXT_FULL; +//RtlCaptureContext(&context); + +#if _WIN64 + //Prev: Used stackframe64 + STACKFRAME64 frame = {}; + frame.AddrPC.Offset = context.Rip; + frame.AddrPC.Mode = AddrModeFlat; + frame.AddrFrame.Offset = context.Rbp; + frame.AddrFrame.Mode = AddrModeFlat; + frame.AddrStack.Offset = context.Rsp; + frame.AddrStack.Mode = AddrModeFlat; +#else + STACKFRAME frame = {}; + frame.AddrPC.Offset = context.Eip; + frame.AddrPC.Mode = AddrModeFlat; + frame.AddrFrame.Offset = context.Ebp; + frame.AddrFrame.Mode = AddrModeFlat; + frame.AddrStack.Offset = context.Esp; + frame.AddrStack.Mode = AddrModeFlat; +#endif + + + bool first = true; + +/* 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); + + 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)) + { + strcpy(f.name, symbol->Name); + } + else + { + //DWORD error = GetLastError(); + printf("SymGetSymFromAddr64 error: %lu offset %llu", GetLastError(), offset); + 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)) + { + strcpy(f.file, line.FileName); + f.line = line.LineNumber; + } + else + { + //DWORD error = GetLastError(); + printf("SymGetLineFromAddr64 error: %lu offset %llu", GetLastError(), offset); + f.line = 0; + } + + /* if (!first) */ + /* { */ + /* frames.push_back(f); */ + /* } */ + printf("%p (%s): %s: %u\n", (LPVOID)f.address, f.module, + f.file, f.line); + first = false; + } + + SymCleanup(process); + + return EXCEPTION_CONTINUE_SEARCH; + + } + int main() { unsigned int em = SetErrorMode(0); - LPTOP_LEVEL_EXCEPTION_FILTER filter = SetUnhandledExceptionFilter(exception_handler); + LPTOP_LEVEL_EXCEPTION_FILTER filter = SetUnhandledExceptionFilter(second_try); printf("prints\n"); int *cosa = NULL; int b = 0;