Created
March 7, 2016 20:30
-
-
Save HoShiMin/8e3ca5dc57b93bccf809 to your computer and use it in GitHub Desktop.
Ещё один простой парсер PDB на DbgHelp с возможностью загрузки отладочных символов
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "stdafx.h" | |
#include "DbgHelpWrapper.h" | |
DbgHelpWrapper::DbgHelpWrapper() { | |
hProcess = GetCurrentProcess(); | |
} | |
DbgHelpWrapper::~DbgHelpWrapper() { | |
DeinitializeDbgHelp(); | |
} | |
BOOL DbgHelpWrapper::InitializeDbgHelp(LPSTR SymbolsPath) { | |
if (SymbolsPath == NULL) SymbolsPath = (LPSTR)DefaultSymbolsPath; | |
if (IsInitialized) DeinitializeDbgHelp(); | |
IsInitialized = SymInitialize(hProcess, SymbolsPath, FALSE); | |
return IsInitialized; | |
} | |
BOOL DbgHelpWrapper::DeinitializeDbgHelp() { | |
if (IsInitialized) { | |
if (SymCleanup(hProcess)) IsInitialized = FALSE; | |
} | |
return IsInitialized; | |
} | |
BOOL DbgHelpWrapper::LoadSymbols(LPSTR ModulePath) { | |
ModuleBase = SymLoadModuleEx(hProcess, NULL, ModulePath, NULL, 0, 0, NULL, 0); | |
return ModuleBase != 0; | |
} | |
BOOL DbgHelpWrapper::GetRootSymbol(LPSTR SymbolName, PULONG SymbolIndex) { | |
SYMBOL_INFO SymbolInfo; | |
SymbolInfo.SizeOfStruct = sizeof(SymbolInfo); | |
BOOL Status = SymGetTypeFromName(hProcess, ModuleBase, SymbolName, &SymbolInfo); | |
if (Status) *SymbolIndex = SymbolInfo.Index; | |
return Status; | |
} | |
BOOL DbgHelpWrapper::GetChildrenCount(ULONG SymbolIndex, OUT PULONG ChildrenCount) { | |
return SymGetTypeInfo(hProcess, ModuleBase, SymbolIndex, TI_GET_CHILDRENCOUNT, ChildrenCount); | |
} | |
BOOL DbgHelpWrapper::GetChildrenSymbols( | |
ULONG ParentSymbolIndex, | |
ULONG* IndicesBuffer, | |
ULONG MaxIndices, | |
OUT ULONG &ChildrenCount | |
) { | |
if ((IndicesBuffer == NULL) || (MaxIndices == 0)) return FALSE; | |
// Получаем количество внутренних элементов ("наследников"): | |
if (!GetChildrenCount(ParentSymbolIndex, &ChildrenCount)) return FALSE; | |
if (ChildrenCount == 0) return TRUE; | |
CONST ULONG FindChildrenSize = sizeof(TI_FINDCHILDREN_PARAMS) + ChildrenCount * sizeof(ULONG); | |
TI_FINDCHILDREN_PARAMS* FindChildrenParams = (TI_FINDCHILDREN_PARAMS*)malloc(FindChildrenSize); | |
memset(FindChildrenParams, 0, FindChildrenSize); | |
FindChildrenParams->Count = ChildrenCount; | |
// Получаем наследников: | |
if (!SymGetTypeInfo(hProcess, ModuleBase, ParentSymbolIndex, TI_FINDCHILDREN, FindChildrenParams)) { | |
free(FindChildrenParams); | |
return FALSE; | |
} | |
// Копируем индексы наследников в выходной массив: | |
ULONG IndicesToCopyCount = ChildrenCount > MaxIndices ? MaxIndices : ChildrenCount; | |
for (ULONG i = 0; i < IndicesToCopyCount; i++) { | |
IndicesBuffer[i] = FindChildrenParams->ChildId[i]; | |
} | |
free(FindChildrenParams); | |
return TRUE; | |
} | |
ULONG DbgHelpWrapper::GetSymbolIndex(LPWSTR SymbolName, ULONG* IndicesBuffer, ULONG IndicesCount) { | |
for (ULONG i = 0; i < IndicesCount; i++) { | |
LPWSTR CurrentSymbolName = NULL; | |
if (GetSymbolName(IndicesBuffer[i], &CurrentSymbolName)) { | |
if (wcscmp(CurrentSymbolName, SymbolName) == 0) { | |
FreeSymbolName(SymbolName); | |
return IndicesBuffer[i]; | |
} | |
FreeSymbolName(SymbolName); | |
} | |
} | |
return 0; | |
} | |
ULONG DbgHelpWrapper::GetSymbolIndex(ULONG ParentSymbolIndex, LPWSTR SymbolName) { | |
ULONG ChildrenIndex = 0; | |
ULONG ChildrenCount = 0; | |
if (!GetChildrenCount(ParentSymbolIndex, &ChildrenCount)) return 0; | |
if (ChildrenCount == 0) return 0; | |
PULONG ChildrenIndices = (PULONG)malloc(ChildrenCount * sizeof(ULONG)); | |
memset(ChildrenIndices, 0, ChildrenCount); | |
if (GetChildrenSymbols(ParentSymbolIndex, ChildrenIndices, ChildrenCount, ChildrenCount)) { | |
ChildrenIndex = GetSymbolIndex(SymbolName, ChildrenIndices, ChildrenCount); | |
} | |
free(ChildrenIndices); | |
return ChildrenIndex; | |
} | |
BOOL DbgHelpWrapper::GetSymbolName(ULONG SymbolIndex, OUT LPWSTR* SymbolName) { | |
return SymGetTypeInfo(hProcess, ModuleBase, SymbolIndex, TI_GET_SYMNAME, SymbolName); | |
} | |
VOID DbgHelpWrapper::FreeSymbolName(LPWSTR SymbolName) { | |
VirtualFree(SymbolName, 0, MEM_RELEASE); | |
} | |
BOOL DbgHelpWrapper::GetSymbolOffset(ULONG SymbolIndex, OUT PULONG Offset) { | |
return SymGetTypeInfo(hProcess, ModuleBase, SymbolIndex, TI_GET_OFFSET, Offset); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <windows.h> | |
#include <dbghelp.h> | |
#pragma comment(lib, "dbghelp.lib") | |
class DbgHelpWrapper { | |
private: | |
BOOL IsInitialized = FALSE; | |
HANDLE hProcess = 0; | |
DWORD64 ModuleBase = 0; | |
LPCSTR DefaultSymbolsPath = "srv*C:\\Symbols*http://msdl.microsoft.com/download/symbols"; | |
public: | |
DbgHelpWrapper(); | |
~DbgHelpWrapper(); | |
// Инициализация/деинициализация DbgHelp, вызывать перед использованием: | |
BOOL InitializeDbgHelp(LPSTR SymbolsPath = NULL); | |
BOOL DeinitializeDbgHelp(); | |
// Загрузить/скачать символы для указанного модуля (*.exe/*.dll/*.sys): | |
BOOL LoadSymbols(LPSTR ModulePath); | |
// Получение символов: | |
BOOL GetRootSymbol(LPSTR SymbolName, PULONG SymbolIndex); | |
BOOL GetChildrenCount(ULONG SymbolIndex, OUT PULONG ChildrenCount); | |
BOOL GetChildrenSymbols(ULONG ParentSymbolIndex, ULONG* IndicesBuffer, ULONG MaxIndices, OUT ULONG &ChildrenCount); | |
// Получение индекса нужного символа: | |
ULONG GetSymbolIndex(LPWSTR SymbolName, ULONG* IndicesBuffer, ULONG IndicesCount); | |
ULONG GetSymbolIndex(ULONG ParentSymbolIndex, LPWSTR SymbolName); | |
// Получение информации о символе: | |
BOOL GetSymbolName(ULONG SymbolIndex, OUT LPWSTR* SymbolName); | |
VOID FreeSymbolName(LPWSTR SymbolName); | |
BOOL GetSymbolOffset(ULONG SymbolIndex, OUT PULONG Offset); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment