1
0
Fork 0

Initial implementation of LRU.

Initial implementation of MSDIA.
This commit is contained in:
ZehMatt 2017-11-19 04:36:27 +01:00 committed by Duncan Ogilvie
parent f64d01bcb1
commit 121486a137
No known key found for this signature in database
GPG Key ID: FC89E0AAA0C1AAD8
16 changed files with 15713 additions and 82 deletions

View File

@ -35,6 +35,7 @@
#include "TraceRecord.h"
#include "recursiveanalysis.h"
#include "dbghelp_safe.h"
#include "symcache.h"
static bool bOnlyCipAutoComments = false;
static bool bNoSourceLineAutoComments = false;
@ -179,94 +180,103 @@ static char* demanglePE32ExternCFunc(char* SymbolName)
static bool getLabel(duint addr, char* label, bool noFuncOffset)
{
bool retval = false;
label[0] = 0;
if(LabelGet(addr, label))
return true;
else //no user labels
{
DWORD64 displacement = 0;
char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(char)];
PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
pSymbol->MaxNameLen = MAX_LABEL_SIZE;
if(SafeSymFromAddr(fdProcessInfo->hProcess, (DWORD64)addr, &displacement, pSymbol) &&
(!displacement || (!noFuncOffset && pSymbol->Flags != SYMFLAG_EXPORT))) //without PDB, SYMFLAG_EXPORT is reported with garbage displacements
{
pSymbol->Name[pSymbol->MaxNameLen - 1] = '\0';
auto name = demanglePE32ExternCFunc(pSymbol->Name);
if(!bUndecorateSymbolNames || !SafeUnDecorateSymbolName(name, label, MAX_LABEL_SIZE, UNDNAME_NAME_ONLY))
strcpy_s(label, MAX_LABEL_SIZE, name);
retval = !shouldFilterSymbol(label);
if(retval && displacement)
{
char temp[32];
sprintf_s(temp, "+%llX", displacement);
strncat_s(label, MAX_LABEL_SIZE, temp, _TRUNCATE);
}
}
if(!retval) //search for CALL <jmp.&user32.MessageBoxA>
{
BASIC_INSTRUCTION_INFO basicinfo;
memset(&basicinfo, 0, sizeof(BASIC_INSTRUCTION_INFO));
if(disasmfast(addr, &basicinfo, true) && basicinfo.branch && !basicinfo.call && basicinfo.memory.value) //thing is a JMP
{
duint val = 0;
if(MemRead(basicinfo.memory.value, &val, sizeof(val), nullptr, true))
{
if(SafeSymFromAddr(fdProcessInfo->hProcess, (DWORD64)val, &displacement, pSymbol) &&
(!displacement || (!noFuncOffset && pSymbol->Flags != SYMFLAG_EXPORT))) //without PDB, SYMFLAG_EXPORT is reported with garbage displacements
{
pSymbol->Name[pSymbol->MaxNameLen - 1] = '\0';
auto name = demanglePE32ExternCFunc(pSymbol->Name);
if(!bUndecorateSymbolNames || !SafeUnDecorateSymbolName(name, label, MAX_LABEL_SIZE, UNDNAME_NAME_ONLY))
sprintf_s(label, MAX_LABEL_SIZE, "JMP.&%s", name);
retval = !shouldFilterSymbol(label);
if(retval && displacement)
{
char temp[32];
sprintf_s(temp, "+%llX", displacement);
strncat_s(label, MAX_LABEL_SIZE, temp, _TRUNCATE);
}
}
}
}
}
if(!retval) //search for module entry
{
if(addr != 0 && ModEntryFromAddr(addr) == addr)
{
strcpy_s(label, MAX_LABEL_SIZE, "EntryPoint");
return true;
}
duint start;
if(FunctionGet(addr, &start, nullptr))
{
duint rva = addr - start;
if(rva == 0)
{
bool retval = false;
label[0] = 0;
if (LabelGet(addr, label))
return true;
else //no user labels
{
DWORD64 displacement = 0;
// char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(char)];
// PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
// pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
// pSymbol->MaxNameLen = MAX_LABEL_SIZE;
// if (SafeSymFromAddr(fdProcessInfo->hProcess, (DWORD64)addr, &displacement, pSymbol) &&
// (!displacement || (!noFuncOffset && pSymbol->Flags != SYMFLAG_EXPORT))) //without PDB, SYMFLAG_EXPORT is reported with garbage displacements
SymbolInfo symInfo;
if (SymbolFromAddrCached(fdProcessInfo->hProcess, addr, symInfo))
{
//auto name = demanglePE32ExternCFunc(symInfo.decoratedName.c_str());
if (!bUndecorateSymbolNames || !SafeUnDecorateSymbolName(symInfo.decoratedName.c_str(), label, MAX_LABEL_SIZE, UNDNAME_NAME_ONLY))
{
strcpy_s(label, MAX_LABEL_SIZE, symInfo.decoratedName.c_str());
}
retval = !shouldFilterSymbol(label);
if (retval && displacement)
{
char temp[32];
sprintf_s(temp, "+%llX", displacement);
strncat_s(label, MAX_LABEL_SIZE, temp, _TRUNCATE);
}
}
if (!retval) //search for CALL <jmp.&user32.MessageBoxA>
{
BASIC_INSTRUCTION_INFO basicinfo;
memset(&basicinfo, 0, sizeof(BASIC_INSTRUCTION_INFO));
if (disasmfast(addr, &basicinfo, true) && basicinfo.branch && !basicinfo.call && basicinfo.memory.value) //thing is a JMP
{
duint val = 0;
if (MemRead(basicinfo.memory.value, &val, sizeof(val), nullptr, true))
{
// if (SafeSymFromAddr(fdProcessInfo->hProcess, (DWORD64)val, &displacement, pSymbol) &&
// (!displacement || (!noFuncOffset && pSymbol->Flags != SYMFLAG_EXPORT))) //without PDB, SYMFLAG_EXPORT is reported with garbage displacements
if (SymbolFromAddrCached(fdProcessInfo->hProcess, addr, symInfo))
{
//pSymbol->Name[pSymbol->MaxNameLen - 1] = '\0';
//auto name = demanglePE32ExternCFunc(pSymbol->Name);
if (!bUndecorateSymbolNames || !SafeUnDecorateSymbolName(symInfo.undecoratedName.c_str(), label, MAX_LABEL_SIZE, UNDNAME_NAME_ONLY))
{
sprintf_s(label, MAX_LABEL_SIZE, "JMP.&%s", symInfo.undecoratedName.c_str());
}
retval = !shouldFilterSymbol(label);
if (retval && displacement)
{
char temp[32];
sprintf_s(temp, "+%llX", displacement);
strncat_s(label, MAX_LABEL_SIZE, temp, _TRUNCATE);
}
}
}
}
}
if (!retval) //search for module entry
{
if (addr != 0 && ModEntryFromAddr(addr) == addr)
{
strcpy_s(label, MAX_LABEL_SIZE, "EntryPoint");
return true;
}
duint start;
if (FunctionGet(addr, &start, nullptr))
{
duint rva = addr - start;
if (rva == 0)
{
#ifdef _WIN64
sprintf_s(label, MAX_LABEL_SIZE, "sub_%llX", start);
sprintf_s(label, MAX_LABEL_SIZE, "sub_%llX", start);
#else //x86
sprintf_s(label, MAX_LABEL_SIZE, "sub_%X", start);
sprintf_s(label, MAX_LABEL_SIZE, "sub_%X", start);
#endif //_WIN64
return true;
}
if(noFuncOffset)
return false;
getLabel(start, label, false);
char temp[32];
return true;
}
if (noFuncOffset)
return false;
getLabel(start, label, false);
char temp[32];
#ifdef _WIN64
sprintf_s(temp, "+%llX", rva);
sprintf_s(temp, "+%llX", rva);
#else //x86
sprintf_s(temp, "+%X", rva);
sprintf_s(temp, "+%X", rva);
#endif //_WIN64
strncat_s(label, MAX_LABEL_SIZE, temp, _TRUNCATE);
return true;
}
}
}
return retval;
strncat_s(label, MAX_LABEL_SIZE, temp, _TRUNCATE);
return true;
}
}
}
return retval;
}
extern "C" DLL_EXPORT bool _dbg_addrinfoget(duint addr, SEGMENTREG segment, BRIDGE_ADDRINFO* addrinfo)

View File

@ -226,6 +226,7 @@ bool ModLoad(duint Base, duint Size, const char* FullPath)
info.loadedSize = 0;
info.fileMap = nullptr;
info.fileMapVA = 0;
info.invalidSymbols.resize(Size);
// Determine whether the module is located in system
wchar_t sysdir[MAX_PATH];
@ -271,6 +272,21 @@ bool ModLoad(duint Base, duint Size, const char* FullPath)
GetModuleInfo(info, (ULONG_PTR)data());
}
// Load PDB if available.
if (PDBDiaFile::initLibrary())
{
if (!info.pdb.open(info.path))
{
std::string msg = StringUtils::sprintf("Unable to load (MSDIA) PDB: %s\n", info.path);
GuiAddLogMessage(msg.c_str());
}
else
{
std::string msg = StringUtils::sprintf("Loaded (MSDIA) PDB: %s\n", info.path);
GuiAddLogMessage(msg.c_str());
}
}
// Add module to list
EXCLUSIVE_ACQUIRE(LockModules);
modinfo.insert(std::make_pair(Range(Base, Base + Size - 1), info));
@ -288,6 +304,8 @@ bool ModLoad(duint Base, duint Size, const char* FullPath)
});
}
SymUpdateModuleList();
return true;
}

View File

@ -3,6 +3,7 @@
#include "_global.h"
#include <functional>
#include "pdbdiafile.h"
struct MODSECTIONINFO
{
@ -42,6 +43,8 @@ struct MODINFO
std::vector<MODIMPORTINFO> imports;
std::vector<MODRELOCATIONINFO> relocations;
std::vector<duint> tlsCallbacks;
std::vector<bool> invalidSymbols;
PDBDiaFile pdb;
HANDLE fileHandle = nullptr;
DWORD loadedSize = 0;

3713
src/dbg/msdia/cvConst.h Normal file

File diff suppressed because it is too large Load Diff

10101
src/dbg/msdia/dia2.h Normal file

File diff suppressed because it is too large Load Diff

42
src/dbg/msdia/diaCreate.h Normal file
View File

@ -0,0 +1,42 @@
// diacreate.h - creation helper functions for DIA initialization
//-----------------------------------------------------------------
//
// Copyright Microsoft Corporation. All Rights Reserved.
//
//---------------------------------------------------------------
#ifndef _DIACREATE_H_
#define _DIACREATE_H_
//
// Create a dia data source object from the dia dll (by dll name - does not access the registry).
//
HRESULT STDMETHODCALLTYPE NoRegCoCreate( const __wchar_t *dllName,
REFCLSID rclsid,
REFIID riid,
void **ppv);
#ifndef _NATIVE_WCHAR_T_DEFINED
#ifdef __cplusplus
HRESULT STDMETHODCALLTYPE NoRegCoCreate( const wchar_t *dllName,
REFCLSID rclsid,
REFIID riid,
void **ppv)
{
return NoRegCoCreate( (const __wchar_t *)dllName, rclsid, riid, ppv );
}
#endif
#endif
//
// Create a dia data source object from the dia dll (looks up the class id in the registry).
//
HRESULT STDMETHODCALLTYPE NoOleCoCreate( REFCLSID rclsid,
REFIID riid,
void **ppv);
#endif

View File

@ -0,0 +1,36 @@
#include <windows.h>
#include "diacreate.h"
typedef HRESULT(__stdcall* pDllGetClassObject)(
_In_ REFCLSID rclsid,
_In_ REFIID riid,
_Out_ LPVOID* ppv
);
HRESULT STDMETHODCALLTYPE NoRegCoCreate(const __wchar_t* dllName,
REFCLSID rclsid,
REFIID riid,
void** ppv)
{
HRESULT hr;
HMODULE hModule = LoadLibraryExW(dllName, nullptr, LOAD_WITH_ALTERED_SEARCH_PATH);
pDllGetClassObject DllGetClassObject;
if(hModule && (DllGetClassObject = (pDllGetClassObject)GetProcAddress(hModule, "DllGetClassObject")))
{
IClassFactory* classFactory;
hr = DllGetClassObject(rclsid, IID_IClassFactory, (LPVOID*)&classFactory);
if(SUCCEEDED(hr))
{
hr = classFactory->CreateInstance(nullptr, riid, ppv);
classFactory->AddRef();
}
}
else
{
hr = GetLastError();
if(hr > 0)
hr |= REASON_LEGACY_API;
}
return hr;
}

1304
src/dbg/pdbdiafile.cpp Normal file

File diff suppressed because it is too large Load Diff

68
src/dbg/pdbdiafile.h Normal file
View File

@ -0,0 +1,68 @@
#pragma once
#include "PDBDiaTypes.h"
#include <vector>
#include <map>
#include <string>
#include <set>
#include <unordered_set>
#include <unordered_map>
struct IDiaDataSource;
struct IDiaSession;
struct IDiaSymbol;
class PDBDiaFile
{
private:
static volatile long m_sbInitialized;
private:
IDiaDataSource *m_dataSource;
IDiaSession *m_session;
std::vector<DiaSymbol_t> m_symbols;
public:
PDBDiaFile();
~PDBDiaFile();
static bool initLibrary();
static bool shutdownLibrary();
bool open(const char *file, DiaValidationData_t *validationData = nullptr);
bool open(const wchar_t *file, DiaValidationData_t *validationData = nullptr);
bool isOpen() const;
bool close();
bool collectSymbols();
const std::vector<DiaSymbol_t>& getSymbols();
bool getFunctionLineNumbers(DWORD sectionIndex, DWORD offset, ULONGLONG size, uint64_t imageBase, std::map<uint64_t, LineInfo_t>& lines);
bool enumerateLexicalHierarchy(std::function<void(DiaSymbol_t&)> callback, const bool collectUndecoratedNames);
bool findSymbolExactRVA(uint64_t address, DiaSymbol_t& sym, DiaSymbolType symType = DiaSymbolType::ANY);
private:
bool testError(HRESULT hr);
bool collectSymbols(IDiaSymbol *scope, std::deque<IDiaSymbol*>* scopes);
bool collectSymbolsByTag(IDiaSymbol *scope, enum SymTagEnum symTag, std::deque<IDiaSymbol*>* scopes);
bool collectSectionContribs();
std::string getSymbolNameString(IDiaSymbol *sym);
std::string getSymbolUndecoratedNameString(IDiaSymbol *sym);
// Container::String toString(BSTR str);
bool enumerateCompilandScope(IDiaSymbol *compiland, std::function<void(DiaSymbol_t&)>& callback, std::unordered_set<uint32_t>& visited, const bool collectUndecoratedNames);
bool processFunctionSymbol(IDiaSymbol *profilerFunction, std::function<void(DiaSymbol_t&)>& callback, std::unordered_set<uint32_t>& visited, const bool collectUndecoratedNames);
bool resolveSymbolSize(IDiaSymbol *symbol, uint64_t& size, uint32_t symTag);
bool convertSymbolInfo(IDiaSymbol *symbol, DiaSymbol_t& symbolInfo, const bool collectUndecoratedNames);
};

85
src/dbg/pdbdiatypes.h Normal file
View File

@ -0,0 +1,85 @@
#ifndef PDBDIATYPES_H_
#define PDBDIATYPES_H_
#pragma once
#include <string>
#include <stdint.h>
#include <set>
#include <vector>
#include <deque>
#include <map>
#include <windows.h>
#include <functional>
#include <string>
enum class DiaSymbolType
{
ANY = -1,
FUNCTION = 0,
CODE,
DATA,
LABEL,
THUNK,
BLOCK,
PUBLIC,
SECTIONCONTRIB,
};
enum class DiaReachableType
{
UNKNOWN,
REACHABLE,
NOTREACHABLE,
};
enum class DiaReturnableType
{
UNKNOWN,
RETURNABLE,
NOTRETURNABLE,
};
enum class DiaCallingConvention
{
UNKNOWN,
CALL_NEAR_C,
CALL_NEAR_FAST,
CALL_NEAR_STD,
CALL_NEAR_SYS,
CALL_THISCALL,
};
struct DiaValidationData_t
{
uint8_t guid[16];
uint32_t signature;
uint32_t age;
};
struct DiaSymbol_t
{
DiaSymbolType type;
uint64_t virtualAddress;
uint64_t size;
uint32_t offset;
uint32_t disp;
uint32_t segment;
DiaReachableType reachable;
DiaReturnableType returnable;
DiaCallingConvention convention;
bool perfectSize;
bool publicSymbol;
std::string name;
std::string undecoratedName;
};
struct LineInfo_t
{
std::string fileName;
DWORD lineNumber;
uint32_t offset;
uint32_t segment;
uint64_t virtualAddress;
};
#endif // PDBDIATYPES_H_

124
src/dbg/sortedlru.h Normal file
View File

@ -0,0 +1,124 @@
#ifndef _SORTEDLRU_H_
#define _SORTEDLRU_H_
#include <list>
#include <map>
#include <unordered_map>
#include <iterator>
template<typename _K, typename _V, typename _Pr = std::less<_K>, size_t _Max = 100000>
class SortedLRU
{
private:
struct EntryElem_t;
typedef std::map<_K, EntryElem_t, _Pr> Map_t;
typedef std::list<typename Map_t::iterator> List_t;
struct EntryElem_t
{
_V value;
typename List_t::iterator it;
};
List_t _list;
Map_t _map;
public:
class iterator
{
public:
typedef std::pair<_K, _V> val_type;
typedef std::pair<_K, _V>& ref_type;
typedef std::pair<_K, _V>* ptr_type;
typedef std::forward_iterator_tag iterator_category;
typedef size_t difference_type;
iterator(typename Map_t::iterator it) : _it(it) {}
iterator operator++()
{
auto temp = *this;
std::advance(_it, 1);
return temp;
}
iterator operator++(int)
{
std::advance(_it, 1);
return *this;
}
ref_type operator*()
{
return reinterpret_cast<ref_type>(*_it);
}
ptr_type operator->()
{
return reinterpret_cast<ref_type>(&(*_it));
}
bool operator==(const iterator& rhs) const { return _it == rhs._it; }
bool operator!=(const iterator& rhs) const { return _it != rhs._it; }
typename Map_t::iterator internal_iter() const { return _it; }
private:
typename Map_t::iterator _it;
};
public:
void insert(const _K& key, const _V& val)
{
// Do we require room?
if (_map.size() + 1 >= _Max)
{
auto itBack = std::prev(_list.end(), 1);
// Erase map element.
_map.erase(*itBack);
// Erase list element.
_list.erase(itBack);
}
_list.push_front(_map.end());
EntryElem_t elem;
elem.value = val;
elem.it = _list.begin();
auto itNew = _map.insert(std::make_pair(key, elem));
_list.front() = itNew.first;
}
iterator find(const _K& key)
{
auto itr = _map.find(key);
if (itr == _map.end())
{
return end();
}
const EntryElem_t& elem = itr->second;
return iterator(itr);
}
iterator end()
{
return iterator(_map.end());
}
bool acquire(const iterator& it)
{
if (it == end())
return false;
const EntryElem_t& elem = it.internal_iter()->second;
// Move to start.
_list.splice(_list.begin(), _list, elem.it);
return true;
}
};
#endif _SORTEDLRU_H_

View File

@ -3,6 +3,9 @@
#include "_global.h"
void InvalidateSymCache();
//bool SymFromAddrCached(HANDLE hProcess, DWORD64 Address, PDWORD64 Displacement, PSYMBOL_INFO Symbol);
void SymEnum(duint Base, CBSYMBOLENUM EnumCallback, void* UserData);
void SymEnumFromCache(duint Base, CBSYMBOLENUM EnumCallback, void* UserData);
bool SymGetModuleList(std::vector<SYMBOLMODULEINFO>* List);

View File

@ -1,6 +1,8 @@
#include "symcache.h"
#include "dbghelp_safe.h"
#include "addrinfo.h"
#include "threading.h"
#include "sortedlru.h"
template<typename T>
using RangeMap = std::map<Range, T, RangeCompare>;
@ -8,6 +10,90 @@ using RangeMap = std::map<Range, T, RangeCompare>;
static RangeMap<RangeMap<SymbolInfo>> symbolRange;
static std::unordered_map<duint, duint> symbolName;
static SortedLRU<duint, SymbolInfo> symbolCache;
bool SymbolFromAddrCached(HANDLE hProcess, duint address, SymbolInfo& symInfo)
{
if (address == 0)
return false;
MODINFO* modInfo = ModInfoFromAddr(address);
if (modInfo)
{
uint64_t rva = address - modInfo->base;
if (modInfo->invalidSymbols[rva] == true)
return false;
auto it = symbolCache.find(address);
if (symbolCache.acquire(it))
{
symInfo = (*it).second;
return symInfo.valid;
}
if (modInfo->pdb.isOpen())
{
DiaSymbol_t diaSym;
diaSym.disp = 0;
if (modInfo->pdb.findSymbolExactRVA(rva, diaSym) && diaSym.disp == 0)
{
symInfo.addr = diaSym.virtualAddress;
symInfo.decoratedName = diaSym.name;
symInfo.undecoratedName = diaSym.name;
symInfo.size = diaSym.size;
symInfo.valid = true;
symbolCache.insert(address, symInfo);
return symInfo.valid;
}
else
{
// Flag as invalid.
modInfo->invalidSymbols[rva] = true;
return false;
}
}
}
return false;
// Non-Module?
auto it = symbolCache.find(address);
if (symbolCache.acquire(it))
{
symInfo = (*it).second;
return symInfo.valid;
}
DWORD64 disp = 0;
char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(char)];
PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
pSymbol->MaxNameLen = MAX_LABEL_SIZE;
// For performance reasons we map invalid symbols as invalid, for now.
if (SafeSymFromAddr(hProcess, address, &disp, pSymbol) == TRUE && disp == 0)
{
symInfo.addr = pSymbol->Address;
symInfo.decoratedName = pSymbol->Name;
symInfo.undecoratedName = pSymbol->Name;
symInfo.size = pSymbol->Size;
symInfo.valid = true;
}
else
{
symInfo.valid = false;
}
symbolCache.insert(address, symInfo);
return symInfo.valid;
}
bool SymbolFromAddr(duint addr, SymbolInfo & symbol)
{
SHARED_ACQUIRE(LockSymbolCache);

View File

@ -8,6 +8,7 @@ struct SymbolInfo
duint size;
String decoratedName;
String undecoratedName;
bool valid;
};
struct LineInfo
@ -18,6 +19,8 @@ struct LineInfo
String sourceFile;
};
bool SymbolFromAddrCached(HANDLE hProcess, duint address, SymbolInfo& symInfo);
bool SymbolFromAddr(duint addr, SymbolInfo & symbol);
bool SymbolFromName(const char* name, SymbolInfo & symbol);
bool SymbolAdd(const SymbolInfo & symbol);

View File

@ -87,10 +87,12 @@
<ClCompile Include="memory.cpp" />
<ClCompile Include="mnemonichelp.cpp" />
<ClCompile Include="module.cpp" />
<ClCompile Include="msdia\diacreate.cpp" />
<ClCompile Include="msgqueue.cpp" />
<ClCompile Include="murmurhash.cpp" />
<ClCompile Include="patches.cpp" />
<ClCompile Include="patternfind.cpp" />
<ClCompile Include="pdbdiafile.cpp" />
<ClCompile Include="plugin_loader.cpp" />
<ClCompile Include="reference.cpp" />
<ClCompile Include="simplescript.cpp" />
@ -219,13 +221,19 @@
<ClInclude Include="memory.h" />
<ClInclude Include="mnemonichelp.h" />
<ClInclude Include="module.h" />
<ClInclude Include="msdia\cvConst.h" />
<ClInclude Include="msdia\dia2.h" />
<ClInclude Include="msdia\diaCreate.h" />
<ClInclude Include="msgqueue.h" />
<ClInclude Include="murmurhash.h" />
<ClInclude Include="patches.h" />
<ClInclude Include="patternfind.h" />
<ClInclude Include="pdbdiafile.h" />
<ClInclude Include="pdbdiatypes.h" />
<ClInclude Include="plugin_loader.h" />
<ClInclude Include="reference.h" />
<ClInclude Include="serializablemap.h" />
<ClInclude Include="sortedlru.h" />
<ClInclude Include="symcache.h" />
<ClInclude Include="taskthread.h" />
<ClInclude Include="tcpconnections.h" />

View File

@ -93,6 +93,9 @@
<Filter Include="Header Files\btparser">
<UniqueIdentifier>{d20554d2-b3de-4e73-ac55-217da06783ba}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\Third Party\msdia">
<UniqueIdentifier>{638ee3a0-ab1a-4bb2-bb14-59461ddf86b2}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.cpp">
@ -428,6 +431,12 @@
<ClCompile Include="formatfunctions.cpp">
<Filter>Source Files\Core</Filter>
</ClCompile>
<ClCompile Include="pdbdiafile.cpp">
<Filter>Source Files\Information</Filter>
</ClCompile>
<ClCompile Include="msdia\diacreate.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="dbghelp\dbghelp.h">
@ -937,5 +946,23 @@
<ClInclude Include="debugger_tracing.h">
<Filter>Header Files\Debugger Core</Filter>
</ClInclude>
<ClInclude Include="sortedlru.h">
<Filter>Header Files\Core</Filter>
</ClInclude>
<ClInclude Include="msdia\cvConst.h">
<Filter>Header Files\Third Party\msdia</Filter>
</ClInclude>
<ClInclude Include="msdia\dia2.h">
<Filter>Header Files\Third Party\msdia</Filter>
</ClInclude>
<ClInclude Include="msdia\diaCreate.h">
<Filter>Header Files\Third Party\msdia</Filter>
</ClInclude>
<ClInclude Include="pdbdiatypes.h">
<Filter>Header Files\Information</Filter>
</ClInclude>
<ClInclude Include="pdbdiafile.h">
<Filter>Header Files\Information</Filter>
</ClInclude>
</ItemGroup>
</Project>