Initial implementation of LRU.
Initial implementation of MSDIA.
This commit is contained in:
parent
f64d01bcb1
commit
121486a137
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
|
@ -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_
|
||||
|
|
@ -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_
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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" />
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
Loading…
Reference in New Issue