1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
#include "HelperFuncs.h"
#include <string.h>
#include <windows.h>
#include <dbghelp.h>
#include <process.h>
#include <exception>
#include <locale.h>
#include <stdlib.h>
using namespace std;
#pragma comment(lib,"Dbghelp.lib")
std::string to_string(const char* cstr)
{
string s(cstr);
return s;
}
void _Exceptor()
{
throw exception();
}
//https://stackoverflow.com/questions/22467604/
const int MaxNameLen = 256;
void printStack(CONTEXT* ctx) //Prints stack trace based on context record
{
BOOL result;
HANDLE process;
HANDLE thread;
HMODULE hModule;
STACKFRAME64 stack;
ULONG frame;
DWORD64 displacement;
DWORD disp;
IMAGEHLP_LINE64 *line;
char buffer[sizeof(SYMBOL_INFO) + 2000 * sizeof(TCHAR)];
char name[MaxNameLen];
char module[MaxNameLen];
PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
memset(&stack, 0, sizeof(STACKFRAME64));
process = GetCurrentProcess();
thread = GetCurrentThread();
displacement = 0;
#if !defined(_M_AMD64)
stack.AddrPC.Offset = (*ctx).Eip;
stack.AddrPC.Mode = AddrModeFlat;
stack.AddrStack.Offset = (*ctx).Esp;
stack.AddrStack.Mode = AddrModeFlat;
stack.AddrFrame.Offset = (*ctx).Ebp;
stack.AddrFrame.Mode = AddrModeFlat;
#endif
SymInitialize(process, NULL, TRUE); //load symbols
for (frame = 0; ; frame++)
{
//get next call from stack
result = StackWalk64
(
#if defined(_M_AMD64)
IMAGE_FILE_MACHINE_AMD64
#else
IMAGE_FILE_MACHINE_I386
#endif
,
process,
thread,
&stack,
ctx,
NULL,
SymFunctionTableAccess64,
SymGetModuleBase64,
NULL
);
if (!result) break;
//get symbol name for address
pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
pSymbol->MaxNameLen = 2000;
SymFromAddr(process, (ULONG64)stack.AddrPC.Offset, &displacement, pSymbol);
line = (IMAGEHLP_LINE64 *)malloc(sizeof(IMAGEHLP_LINE64));
line->SizeOfStruct = sizeof(IMAGEHLP_LINE64);
//try to get line
if (SymGetLineFromAddr64(process, stack.AddrPC.Offset, &disp, line))
{
printf("\tat %s in %s: line: %lu: address: 0x%0X\n", pSymbol->Name, line->FileName, line->LineNumber, pSymbol->Address);
}
else
{
//failed to get line
printf("\tat %s, address 0x%0X.\n", pSymbol->Name, pSymbol->Address);
hModule = NULL;
lstrcpyA(module, "");
GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
(LPCTSTR)(stack.AddrPC.Offset), &hModule);
//at least print module name
if (hModule != NULL)GetModuleFileNameA(hModule, module, MaxNameLen);
printf("in %s\n", module);
}
free(line);
line = NULL;
}
}
int seh_filter(_EXCEPTION_POINTERS* ex)
{
printf("*** Exception 0x%x occured ***\n\n", ex->ExceptionRecord->ExceptionCode);
printStack(ex->ContextRecord);
return EXCEPTION_EXECUTE_HANDLER;
}
void PrintCallStack()
{
__try
{
_Exceptor();
}
__except (seh_filter(GetExceptionInformation()))
{
printf("Exception \n");
}
}
|