Skip to content

Instantly share code, notes, and snippets.

@HoShiMin
Created March 7, 2016 20:30
Show Gist options
  • Save HoShiMin/8e3ca5dc57b93bccf809 to your computer and use it in GitHub Desktop.
Save HoShiMin/8e3ca5dc57b93bccf809 to your computer and use it in GitHub Desktop.
Ещё один простой парсер PDB на DbgHelp с возможностью загрузки отладочных символов
#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);
}
#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