96 #pragma comment(lib, "version.lib") // for "VerQueryValue"
103 #pragma warning(push)
104 #pragma warning(disable: 4091)
204 LPDWORD lpNumberOfBytesRead
223 #define SYMOPT_CASE_INSENSITIVE 0x00000001
224 #define SYMOPT_UNDNAME 0x00000002
225 #define SYMOPT_DEFERRED_LOADS 0x00000004
226 #define SYMOPT_NO_CPP 0x00000008
227 #define SYMOPT_LOAD_LINES 0x00000010
228 #define SYMOPT_OMAP_FIND_NEAREST 0x00000020
229 #define SYMOPT_LOAD_ANYTHING 0x00000040
230 #define SYMOPT_IGNORE_CVREC 0x00000080
231 #define SYMOPT_NO_UNQUALIFIED_LOADS 0x00000100
232 #define SYMOPT_FAIL_CRITICAL_ERRORS 0x00000200
233 #define SYMOPT_EXACT_SYMBOLS 0x00000400
234 #define SYMOPT_ALLOW_ABSOLUTE_SYMBOLS 0x00000800
235 #define SYMOPT_IGNORE_NT_SYMPATH 0x00001000
236 #define SYMOPT_INCLUDE_32BIT_MODULES 0x00002000
237 #define SYMOPT_PUBLICS_ONLY 0x00004000
238 #define SYMOPT_NO_PUBLICS 0x00008000
239 #define SYMOPT_AUTO_PUBLICS 0x00010000
240 #define SYMOPT_NO_IMAGE_SEARCH 0x00020000
241 #define SYMOPT_SECURE 0x00040000
242 #define SYMOPT_DEBUG 0x80000000
243 #define UNDNAME_COMPLETE (0x0000) // Enable full undecoration
244 #define UNDNAME_NAME_ONLY (0x1000) // Crack only the name for primary declaration;
245 #endif // _MSC_VER < 1300
248 #ifndef INVALID_FILE_ATTRIBUTES
249 #define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
254 #define strcpy_s strcpy
255 #define strcat_s(dst, len, src) strcat(dst, src)
256 #define _snprintf_s _snprintf
257 #define _tcscat_s _tcscat
261 #define USED_CONTEXT_FLAGS CONTEXT_FULL
308 if (GetModuleFileName(NULL, szTemp, 4096) > 0)
314 if (GetEnvironmentVariable(_T(
"ProgramFiles"), szTemp, 4096) > 0)
316 _tcscat_s(szTemp, _T(
"\\Debugging Tools for Windows\\dbghelp.dll"));
322 if ((
m_hDbhHelp == NULL) && (GetEnvironmentVariable(_T(
"ProgramFiles"), szTemp, 4096) > 0))
324 _tcscat_s(szTemp, _T(
"\\Debugging Tools for Windows 64-Bit\\dbghelp.dll"));
362 if (szSymPath != NULL)
367 DWORD symOptions =
pSGO();
372 symOptions =
pSSO(symOptions);
380 char szUserName[1024] = {0};
382 GetUserNameA(szUserName, &dwSize);
438 typedef BOOL (__stdcall*
tSC)(IN HANDLE hProcess);
463 typedef DWORD (__stdcall*
tSGO)(VOID);
472 typedef BOOL (__stdcall*
tSI)(IN HANDLE hProcess, IN PSTR UserSearchPath, IN
BOOL fInvadeProcess);
476 typedef DWORD64(__stdcall*
tSLM)(IN HANDLE hProcess, IN HANDLE hFile,
477 IN PSTR ImageName, IN PSTR ModuleName, IN
DWORD64 BaseOfDll, IN DWORD SizeOfDll);
481 typedef DWORD (__stdcall*
tSSO)(IN DWORD SymOptions);
498 typedef DWORD (__stdcall*
tUDSN)(PCSTR DecoratedName, PSTR UnDecoratedName,
499 DWORD UndecoratedLength, DWORD Flags);
502 typedef BOOL (__stdcall*
tSGSP)(HANDLE hProcess, PSTR SearchPath, DWORD SearchPathLength);
508 #define MAX_MODULE_NAME32 255
509 #define TH32CS_SNAPMODULE 0x00000008
510 #pragma pack( push, 8 )
532 typedef HANDLE(__stdcall * tCT32S)(DWORD dwFlags, DWORD th32ProcessID);
539 const TCHAR* dllname[] = { _T(
"kernel32.dll"), _T(
"tlhelp32.dll") };
540 HINSTANCE hToolhelp = NULL;
541 tCT32S pCT32S = NULL;
551 for (i = 0; i < (
sizeof(dllname) /
sizeof(dllname[0])); i++)
553 hToolhelp = LoadLibrary(dllname[i]);
554 if (hToolhelp == NULL)
556 pCT32S = (tCT32S) GetProcAddress(hToolhelp,
"CreateToolhelp32Snapshot");
557 pM32F = (tM32F) GetProcAddress(hToolhelp,
"Module32First");
558 pM32N = (tM32N) GetProcAddress(hToolhelp,
"Module32Next");
559 if ((pCT32S != NULL) && (pM32F != NULL) && (pM32N != NULL))
561 FreeLibrary(hToolhelp);
565 if (hToolhelp == NULL)
569 if (hSnap == (HANDLE) - 1)
572 keepGoing = !!pM32F(hSnap, &me);
578 keepGoing = !!pM32N(hSnap, &me);
581 FreeLibrary(hToolhelp);
598 typedef BOOL (__stdcall * tEPM)(HANDLE hProcess, HMODULE * lphModule, DWORD cb, LPDWORD lpcbNeeded);
600 typedef DWORD (__stdcall * tGMFNE)(HANDLE hProcess, HMODULE hModule, LPSTR lpFilename, DWORD nSize);
602 typedef DWORD (__stdcall * tGMBN)(HANDLE hProcess, HMODULE hModule, LPSTR lpFilename, DWORD nSize);
604 typedef BOOL (__stdcall * tGMI)(HANDLE hProcess, HMODULE hModule,
LPMODULEINFO pmi, DWORD nSize);
619 const SIZE_T TTBUFLEN = 8096;
622 hPsapi = LoadLibrary(_T(
"psapi.dll"));
626 pEPM = (tEPM) GetProcAddress(hPsapi,
"EnumProcessModules");
627 pGMFNE = (tGMFNE) GetProcAddress(hPsapi,
"GetModuleFileNameExA");
628 pGMBN = (tGMFNE) GetProcAddress(hPsapi,
"GetModuleBaseNameA");
629 pGMI = (tGMI) GetProcAddress(hPsapi,
"GetModuleInformation");
630 if ((pEPM == NULL) || (pGMFNE == NULL) || (pGMBN == NULL) || (pGMI == NULL))
637 hMods = (HMODULE*) malloc(
sizeof(HMODULE) * (TTBUFLEN /
sizeof(HMODULE)));
638 tt = (
char*) malloc(
sizeof(
char) * TTBUFLEN);
639 tt2 = (
char*) malloc(
sizeof(
char) * TTBUFLEN);
640 if ((hMods == NULL) || (tt == NULL) || (tt2 == NULL))
643 if (! pEPM(hProcess, hMods, TTBUFLEN, &cbNeeded))
649 if (cbNeeded > TTBUFLEN)
655 for (i = 0; i < cbNeeded /
sizeof hMods[0]; i++)
658 pGMI(hProcess, hMods[i], &mi,
sizeof mi);
661 pGMFNE(hProcess, hMods[i], tt, TTBUFLEN);
664 pGMBN(hProcess, hMods[i], tt2, TTBUFLEN);
667 if (dwRes != ERROR_SUCCESS)
681 return (cnt != 0) ? TRUE : FALSE;
686 CHAR* szImg = _strdup(img);
687 CHAR* szMod = _strdup(mod);
688 DWORD result = ERROR_SUCCESS;
689 if ((szImg == NULL) || (szMod == NULL))
690 result = ERROR_NOT_ENOUGH_MEMORY;
691 else if (
pSLM(hProcess, 0, szImg, szMod, baseAddr, size) == 0)
692 result = GetLastError();
693 ULONGLONG fileVersion = 0;
694 if ((
m_parent != NULL) && (szImg != NULL))
699 VS_FIXEDFILEINFO* fInfo = NULL;
701 DWORD dwSize = GetFileVersionInfoSizeA(szImg, &dwHandle);
704 LPVOID vData = malloc(dwSize);
707 if (GetFileVersionInfoA(szImg, dwHandle, dwSize, vData) != 0)
710 TCHAR szSubBlock[] = _T(
"\\");
711 if (VerQueryValue(vData, szSubBlock, (LPVOID*) &fInfo, &len) != 0)
712 fileVersion = ((ULONGLONG)fInfo->dwFileVersionLS) + ((ULONGLONG)fInfo->dwFileVersionMS << 32);
721 const char* szSymType =
"-unknown-";
722 if (this->
GetModuleInfo(hProcess, baseAddr, &Module) != FALSE)
727 szSymType =
"-nosymbols-";
739 szSymType =
"-exported-";
742 szSymType =
"-deferred-";
748 szSymType =
"Virtual";
778 SetLastError(ERROR_DLL_INIT_FAILED);
794 void* pData = malloc(4096);
797 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
810 SetLastError(ERROR_DLL_INIT_FAILED);
832 if (szSymPath != NULL)
855 SetLastError(ERROR_DLL_INIT_FAILED);
862 char* szSymPath = NULL;
865 const size_t nSymPathLen = 4096;
866 szSymPath = (
char*) malloc(nSymPathLen);
867 if (szSymPath == NULL)
869 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
877 strcat_s(szSymPath, nSymPathLen,
";");
880 strcat_s(szSymPath, nSymPathLen,
".;");
882 const size_t nTempLen = 1024;
883 char szTemp[nTempLen];
885 if (GetCurrentDirectoryA(nTempLen, szTemp) > 0)
887 szTemp[nTempLen - 1] = 0;
888 strcat_s(szSymPath, nSymPathLen, szTemp);
889 strcat_s(szSymPath, nSymPathLen,
";");
893 if (GetModuleFileNameA(NULL, szTemp, nTempLen) > 0)
895 szTemp[nTempLen - 1] = 0;
896 for (
char* p = (szTemp + strlen(szTemp) - 1); p >= szTemp; --p)
899 if ((*p ==
'\\') || (*p ==
'/') || (*p ==
':'))
905 if (strlen(szTemp) > 0)
907 strcat_s(szSymPath, nSymPathLen, szTemp);
908 strcat_s(szSymPath, nSymPathLen,
";");
911 if (GetEnvironmentVariableA(
"_NT_SYMBOL_PATH", szTemp, nTempLen) > 0)
913 szTemp[nTempLen - 1] = 0;
914 strcat_s(szSymPath, nSymPathLen, szTemp);
915 strcat_s(szSymPath, nSymPathLen,
";");
917 if (GetEnvironmentVariableA(
"_NT_ALTERNATE_SYMBOL_PATH", szTemp, nTempLen) > 0)
919 szTemp[nTempLen - 1] = 0;
920 strcat_s(szSymPath, nSymPathLen, szTemp);
921 strcat_s(szSymPath, nSymPathLen,
";");
923 if (GetEnvironmentVariableA(
"SYSTEMROOT", szTemp, nTempLen) > 0)
925 szTemp[nTempLen - 1] = 0;
926 strcat_s(szSymPath, nSymPathLen, szTemp);
927 strcat_s(szSymPath, nSymPathLen,
";");
929 strcat_s(szTemp, nTempLen,
"\\system32");
930 strcat_s(szSymPath, nSymPathLen, szTemp);
931 strcat_s(szSymPath, nSymPathLen,
";");
936 if (GetEnvironmentVariableA(
"SYSTEMDRIVE", szTemp, nTempLen) > 0)
938 szTemp[nTempLen - 1] = 0;
939 strcat_s(szSymPath, nSymPathLen,
"SRV*");
940 strcat_s(szSymPath, nSymPathLen, szTemp);
941 strcat_s(szSymPath, nSymPathLen,
"\\websymbols");
942 strcat_s(szSymPath, nSymPathLen,
"*http://msdl.microsoft.com/download/symbols;");
945 strcat_s(szSymPath, nSymPathLen,
"SRV*c:\\websymbols*http://msdl.microsoft.com/download/symbols;");
951 if (szSymPath != NULL)
958 this->
OnDbgHelpErr(
"Error while initializing dbghelp.dll", 0, 0);
959 SetLastError(ERROR_DLL_INIT_FAILED);
978 #pragma warning(disable : 4748)
992 OnOutput(
"************* Loaded Modules *************");
994 OnOutput(
"************* Callstack *************");
999 SetLastError(ERROR_DLL_INIT_FAILED);
1006 if (context == NULL)
1009 if (hThread == GetCurrentThread())
1013 SuspendThread(hThread);
1014 memset(&c, 0,
sizeof(CONTEXT));
1016 if (GetThreadContext(hThread, &c) == FALSE)
1018 ResumeThread(hThread);
1028 memset(&
s, 0,
sizeof(
s));
1030 #if defined(_M_IX86)
1032 imageType = IMAGE_FILE_MACHINE_I386;
1033 s.AddrPC.Offset = c.Eip;
1035 s.AddrFrame.Offset = c.Ebp;
1037 s.AddrStack.Offset = c.Esp;
1039 #elif defined(_M_X64)
1040 imageType = IMAGE_FILE_MACHINE_AMD64;
1041 s.AddrPC.Offset = c.Rip;
1043 s.AddrFrame.Offset = c.Rsp;
1045 s.AddrStack.Offset = c.Rsp;
1047 #elif defined(_M_IA64)
1048 imageType = IMAGE_FILE_MACHINE_IA64;
1049 s.AddrPC.Offset = c.StIIP;
1051 s.AddrFrame.Offset = c.IntSp;
1053 s.AddrBStore.Offset = c.RsBSP;
1055 s.AddrStack.Offset = c.IntSp;
1058 #error "Platform not supported!"
1068 memset(&Line, 0,
sizeof(Line));
1071 memset(&Module, 0,
sizeof(Module));
1074 for (frameNum = 0; ; ++frameNum)
1083 this->
OnDbgHelpErr(
"StackWalk64", GetLastError(),
s.AddrPC.Offset);
1087 csEntry.
offset =
s.AddrPC.Offset;
1088 csEntry.
name[0] = 0;
1097 if (
s.AddrPC.Offset ==
s.AddrReturn.Offset)
1102 if (
s.AddrPC.Offset != 0)
1114 this->
OnDbgHelpErr(
"SymGetSymFromAddr64", GetLastError(),
s.AddrPC.Offset);
1126 this->
OnDbgHelpErr(
"SymGetLineFromAddr64", GetLastError(),
s.AddrPC.Offset);
1156 #if API_VERSION_NUMBER >= 9
1175 this->
OnDbgHelpErr(
"SymGetModuleInfo64", GetLastError(),
s.AddrPC.Offset);
1183 if (
s.AddrReturn.Offset == 0)
1186 SetLastError(ERROR_SUCCESS);
1195 if (context == NULL)
1196 ResumeThread(hThread);
1206 LPDWORD lpNumberOfBytesRead
1212 BOOL bRet = ReadProcessMemory(hProcess, (LPVOID) qwBaseAddress, lpBuffer, nSize, &st);
1213 *lpNumberOfBytesRead = (DWORD) st;
1224 if (fileVersion == 0)
1225 _snprintf_s(buffer,
STACKWALK_MAX_NAMELEN,
"%s:%s (%p), size: %d (result: %d), SymType: '%s', PDB: '%s'", img, mod, (LPVOID) baseAddr, size, result, symType, pdbName);
1228 DWORD v4 = (DWORD) fileVersion & 0xFFFF;
1229 DWORD v3 = (DWORD)(fileVersion >> 16) & 0xFFFF;
1230 DWORD v2 = (DWORD)(fileVersion >> 32) & 0xFFFF;
1231 DWORD v1 = (DWORD)(fileVersion >> 48) & 0xFFFF;
1232 _snprintf_s(buffer,
STACKWALK_MAX_NAMELEN,
"%s:%s (%p), size: %d (result: %d), SymType: '%s', PDB: '%s', fileVersion: %d.%d.%d.%d", img, mod, (LPVOID) baseAddr, size, result, symType, pdbName, v1, v2, v3, v4);
1242 if (entry.
name[0] == 0)
1274 #if _MSC_VER <= 1200
1276 ZeroMemory(&ver,
sizeof(OSVERSIONINFOA));
1277 ver.dwOSVersionInfoSize =
sizeof(ver);
1278 if (GetVersionExA(&ver) != FALSE)
1281 ver.dwMajorVersion, ver.dwMinorVersion, ver.dwBuildNumber,
1286 OSVERSIONINFOEXA ver;
1287 ZeroMemory(&ver,
sizeof(OSVERSIONINFOEXA));
1288 ver.dwOSVersionInfoSize =
sizeof(ver);
1289 #pragma warning(suppress: 4996)
1290 if (GetVersionExA((OSVERSIONINFOA*) &ver) != FALSE)
1293 ver.dwMajorVersion, ver.dwMinorVersion, ver.dwBuildNumber,
1294 ver.szCSDVersion, ver.wSuiteMask, ver.wProductType);