Last active
February 16, 2019 21:07
-
-
Save HoShiMin/d1661cc79a8033c7b5b9 to your computer and use it in GitHub Desktop.
Удобный парсер PDB-файлов с помощью DIA (входит в Windows Kits)
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 "DIAWrapper.h" | |
// Очистка ресурсов: | |
VOID DIAWrapper::Cleanup() { | |
if (pGlobalSymbol) pGlobalSymbol -> Release(); | |
if (pDiaSession) pDiaSession -> Release(); | |
if (pDiaDataSource) pDiaDataSource -> Release(); | |
pGlobalSymbol = NULL; | |
pDiaSession = NULL; | |
pDiaDataSource = NULL; | |
dwMachineType = CV_CFL_80386; | |
} | |
// Инициализация: | |
VOID DIAWrapper::Initialize() { | |
Cleanup(); | |
CoCreateInstance(__uuidof(DiaSource), NULL, CLSCTX_INPROC_SERVER, __uuidof(IDiaDataSource), (PVOID *)&pDiaDataSource); | |
} | |
// Конструктор: | |
DIAWrapper::DIAWrapper() { | |
CoInitialize(NULL); | |
} | |
// Деструктор: | |
DIAWrapper::~DIAWrapper() { | |
Cleanup(); | |
CoUninitialize(); | |
} | |
// Загрузка PDB: | |
DIAWRAPPER_STATUS DIAWrapper::LoadPDB(LPWSTR PDBPath) { | |
Initialize(); | |
if FAILED(pDiaDataSource->loadDataFromPdb(PDBPath)) return STATUS_FILE_NOT_FOUND; | |
if FAILED(pDiaDataSource->openSession(&pDiaSession)) return STATUS_OPEN_SESSION_ERROR; | |
if FAILED(pDiaSession->get_globalScope(&pGlobalSymbol)) return STATUS_GETTING_GLOBAL_SCOPE_ERROR; | |
if (pGlobalSymbol->get_machineType(&dwMachineType) == S_OK) { | |
switch (dwMachineType) { | |
case IMAGE_FILE_MACHINE_I386: dwMachineType = CV_CFL_80386 ; break; | |
case IMAGE_FILE_MACHINE_IA64: dwMachineType = CV_CFL_IA64 ; break; | |
case IMAGE_FILE_MACHINE_AMD64: dwMachineType = CV_CFL_AMD64 ; break; | |
} | |
} | |
return STATUS_SUCCESS; | |
} | |
// Получить корневой символ: | |
IDiaSymbol* DIAWrapper::GetGlobalSymbol() { | |
return pGlobalSymbol; | |
} | |
// Получить символ в родительском объекте: | |
BOOL DIAWrapper::GetSymbol(IDiaSymbol* WhereToFindSymbol, LPWSTR SymbolName, enum SymTagEnum SymbolType, enum NameSearchOptions SearchOptions, OUT IDiaSymbol** Symbol) { | |
BOOL Result = FALSE; | |
if (WhereToFindSymbol == NULL) return Result; | |
if (SymbolName == NULL) return Result; | |
if (Symbol == NULL) return Result; | |
// Ищем все символы, подпадающие под условие: | |
IDiaEnumSymbols *EnumSymbols; | |
if FAILED(WhereToFindSymbol->findChildren(SymbolType, SymbolName, SearchOptions, &EnumSymbols)) return Result; | |
// Делаем выборку одного символа: | |
const BYTE SymbolsCount = 1; | |
ULONG SymbolsFetched; | |
Result = SUCCEEDED(EnumSymbols->Next(SymbolsCount, Symbol, &SymbolsFetched)) && (SymbolsFetched == SymbolsCount); | |
EnumSymbols->Release(); | |
return Result; | |
} | |
// Получить смещение символа в родительском объекте: | |
BOOL DIAWrapper::GetSymbolOffset(IDiaSymbol* Symbol, OUT PLONG SymbolOffset) { | |
return Symbol->get_offset(SymbolOffset) == S_OK; | |
} | |
// Получить размер символа: | |
BOOL DIAWrapper::GetSymbolSize(IDiaSymbol* Symbol, OUT PULONGLONG SymbolSize) { | |
IDiaSymbol* Type; | |
HRESULT Status = Symbol->get_type(&Type); | |
if (Status != S_OK) return FALSE; | |
Status = Type->get_length(SymbolSize) == S_OK; | |
Type->Release(); | |
return Status; | |
} | |
// Освободить символ, полученный от GetSymbol: | |
VOID DIAWrapper::FreeSymbol(IDiaSymbol* Symbol) { | |
if (Symbol) Symbol->Release(); | |
} |
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 "dia2.h" | |
enum DIAWRAPPER_STATUS { | |
STATUS_SUCCESS, | |
STATUS_FILE_NOT_FOUND, | |
STATUS_OPEN_SESSION_ERROR, | |
STATUS_GETTING_GLOBAL_SCOPE_ERROR | |
}; | |
class DIAWrapper { | |
private: | |
IDiaDataSource *pDiaDataSource = NULL; | |
IDiaSession *pDiaSession = NULL; | |
IDiaSymbol *pGlobalSymbol = NULL; | |
DWORD dwMachineType = CV_CFL_80386; | |
VOID Initialize(); // Инициализация DIA2 | |
VOID Cleanup(); // Очистка ресурсов, освобождение символов | |
public: | |
DIAWrapper(); | |
~DIAWrapper(); | |
// Загрузка PDB: | |
DIAWRAPPER_STATUS LoadPDB(LPWSTR PDBPath); | |
// Получить корневой символ: | |
IDiaSymbol* GetGlobalSymbol(); | |
// Получить символ в родительском объекте: | |
BOOL GetSymbol(IDiaSymbol* WhereToFindSymbol, LPWSTR SymbolName, enum SymTagEnum SymbolType, enum NameSearchOptions SearchOptions, OUT IDiaSymbol** Symbol); | |
// Получить смещение символа в родительском объекте: | |
BOOL GetSymbolOffset(IDiaSymbol* Symbol, OUT PLONG SymbolOffset); | |
// Получить размер символа: | |
BOOL GetSymbolSize(IDiaSymbol* Symbol, OUT PULONGLONG SymbolSize); | |
// Освободить символ, полученный от GetSymbol: | |
VOID FreeSymbol(IDiaSymbol* Symbol); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment