wip error SymGetModuleInfo64 mod nf
This commit is contained in:
parent
348e578ceb
commit
59e5e501b3
1 changed files with 347 additions and 1 deletions
348
src/main.c
348
src/main.c
|
|
@ -2,9 +2,352 @@
|
|||
#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);
|
||||
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue