[0.2.x] added facade for retrieving symbol information

git-svn-id: https://pykd.svn.codeplex.com/svn@78409 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
SND\kernelnet_cp 2012-07-31 13:40:05 +00:00 committed by Mikhail I. Izmestev
parent 73478dc355
commit 9cbbbb7ea6
19 changed files with 3078 additions and 2211 deletions

View File

@ -13,9 +13,12 @@ void debugGo();
ULONG64 findModuleBase( const std::string &moduleName );
ULONG64 findModuleBase( ULONG64 offset );
std::string getModuleName( ULONG64 baseOffset );
std::string getModuleSymbolFileName( ULONG64 baseOffset );
//manage access to target memory
ULONG64 addr64( ULONG64 offset );
void readMemory( ULONG64 offset, PVOID buffer, ULONG length, bool phyAddr = FALSE );
};

View File

@ -1,6 +1,6 @@
#include "stdafx.h"
#include "dbgexcept.h"
#include "diawrapper.h"
//#include "diawrapper.h"
namespace pykd {
@ -11,7 +11,7 @@ python::handle<> exceptPyType<DbgException>::pyExceptType;
python::handle<> exceptPyType<MemoryException>::pyExceptType;
python::handle<> exceptPyType<WaitEventException>::pyExceptType;
python::handle<> exceptPyType<SymbolException>::pyExceptType;
python::handle<> exceptPyType<pyDia::Exception>::pyExceptType;
//python::handle<> exceptPyType<pyDia::Exception>::pyExceptType;
python::handle<> exceptPyType<TypeException>::pyExceptType;
python::handle<> exceptPyType<AddSyntheticSymbolException>::pyExceptType;
python::handle<> exceptPyType<ImplementException>::pyExceptType;

View File

@ -7,19 +7,14 @@
namespace pykd {
template< class TExcept >
struct exceptPyType{
static python::handle<> pyExceptType;
static python::handle<> pyExceptType;
};
template< class TExcept, class TBaseExcept = python::detail::not_specified >
class exception {
public:
exception( const std::string& className, const std::string& classDesc )

File diff suppressed because it is too large Load Diff

View File

@ -4,104 +4,154 @@ namespace pykd {
///////////////////////////////////////////////////////////////////////////////////
ULONG64
addr64( ULONG64 addr );
bool
isVaValid( ULONG64 addr );
///////////////////////////////////////////////////////////////////////////////////
HRESULT readVirtual(
IDebugDataSpaces4 *dbgDataSpace,
ULONG64 address,
PVOID buffer,
ULONG length,
PULONG readed
);
///////////////////////////////////////////////////////////////////////////////////
void
readMemory( IDebugDataSpaces4* dbgDataSpace, ULONG64 address, PVOID buffer, ULONG length, bool phyAddr = FALSE );
void
readMemoryPtr( IDebugDataSpaces4* dbgDataSpace, ULONG64 address, PULONG64 ptrValue );
void
writeMemory( IDebugDataSpaces4* dbgDataSpace, ULONG64 address, PVOID buffer, ULONG length, bool phyAddr = FALSE );
bool
compareMemoryRange( IDebugDataSpaces4* dbgDataSpace, ULONG64 addr1, ULONG64 addr2, ULONG length, bool phyAddr = FALSE );
///////////////////////////////////////////////////////////////////////////////////
std::string loadChars( ULONG64 address, ULONG number, bool phyAddr = FALSE );
std::wstring loadWChars( ULONG64 address, ULONG number, bool phyAddr = FALSE );
std::string loadCStr( ULONG64 offset );
std::wstring loadWStr( ULONG64 offset );
python::list loadBytes( ULONG64 offset, ULONG count, bool phyAddr = FALSE );
python::list loadWords( ULONG64 offset, ULONG count, bool phyAddr = FALSE );
python::list loadDWords( ULONG64 offset, ULONG count, bool phyAddr = FALSE );
python::list loadQWords( ULONG64 offset, ULONG count, bool phyAddr = FALSE );
python::list loadSignBytes( ULONG64 offset, ULONG count, bool phyAddr = FALSE );
python::list loadSignWords( ULONG64 offset, ULONG count, bool phyAddr = FALSE );
python::list loadSignDWords( ULONG64 offset, ULONG count, bool phyAddr = FALSE );
python::list loadSignQWords( ULONG64 offset, ULONG count, bool phyAddr = FALSE );
ULONG64 ptrByte( ULONG64 offset );
ULONG64 ptrWord( ULONG64 offset );
ULONG64 ptrDWord( ULONG64 offset );
ULONG64 ptrDWord( ULONG64 offset, IDebugDataSpaces4* dbgDataSpace );
ULONG64 ptrQWord( ULONG64 offset );
ULONG64 ptrQWord( ULONG64 offset, IDebugDataSpaces4* dbgDataSpace );
ULONG64 ptrMWord( ULONG64 offset );
ULONG64 ptrMWord( ULONG64 offset, IDebugDataSpaces4* dbgDataSpace );
LONG64 ptrSignByte( ULONG64 offset );
LONG64 ptrSignWord( ULONG64 offset );
LONG64 ptrSignDWord( ULONG64 offset );
LONG64 ptrSignQWord( ULONG64 offset );
LONG64 ptrSignMWord( ULONG64 offset );
ULONG64 ptrPtr( ULONG64 offset );
ULONG64 ptrPtr( ULONG64 offset, IDebugDataSpaces4* dbgDataSpace );
bool
compareMemory( ULONG64 addr1, ULONG64 addr2, ULONG length, bool phyAddr = FALSE );
std::wstring loadUnicodeStr( ULONG64 address );
std::string loadAnsiStr( ULONG64 address );
python::list loadPtrList( ULONG64 address );
python::list loadPtrArray( ULONG64 address, ULONG number );
///////////////////////////////////////////////////////////////////////////////////
};
}; // end pykd namespace
//namespace pykd {
//
/////////////////////////////////////////////////////////////////////////////////////
//
//ULONG64
//addr64( ULONG64 addr );
//
//bool
//isVaValid( ULONG64 addr );
//
/////////////////////////////////////////////////////////////////////////////////////
//
//HRESULT readVirtual(
// IDebugDataSpaces4 *dbgDataSpace,
// ULONG64 address,
// PVOID buffer,
// ULONG length,
// PULONG readed
//);
//
/////////////////////////////////////////////////////////////////////////////////////
//
//void
//readMemory( IDebugDataSpaces4* dbgDataSpace, ULONG64 address, PVOID buffer, ULONG length, bool phyAddr = FALSE );
//
//void
//readMemoryPtr( IDebugDataSpaces4* dbgDataSpace, ULONG64 address, PULONG64 ptrValue );
//
//void
//writeMemory( IDebugDataSpaces4* dbgDataSpace, ULONG64 address, PVOID buffer, ULONG length, bool phyAddr = FALSE );
//
//bool
//compareMemoryRange( IDebugDataSpaces4* dbgDataSpace, ULONG64 addr1, ULONG64 addr2, ULONG length, bool phyAddr = FALSE );
//
/////////////////////////////////////////////////////////////////////////////////////
//
//std::string loadChars( ULONG64 address, ULONG number, bool phyAddr = FALSE );
//
//std::wstring loadWChars( ULONG64 address, ULONG number, bool phyAddr = FALSE );
//
//std::string loadCStr( ULONG64 offset );
//
//std::wstring loadWStr( ULONG64 offset );
//
//python::list loadBytes( ULONG64 offset, ULONG count, bool phyAddr = FALSE );
//
//python::list loadWords( ULONG64 offset, ULONG count, bool phyAddr = FALSE );
//
//python::list loadDWords( ULONG64 offset, ULONG count, bool phyAddr = FALSE );
//
//python::list loadQWords( ULONG64 offset, ULONG count, bool phyAddr = FALSE );
//
//python::list loadSignBytes( ULONG64 offset, ULONG count, bool phyAddr = FALSE );
//
//python::list loadSignWords( ULONG64 offset, ULONG count, bool phyAddr = FALSE );
//
//python::list loadSignDWords( ULONG64 offset, ULONG count, bool phyAddr = FALSE );
//
//python::list loadSignQWords( ULONG64 offset, ULONG count, bool phyAddr = FALSE );
//
//ULONG64 ptrByte( ULONG64 offset );
//
//ULONG64 ptrWord( ULONG64 offset );
//
//ULONG64 ptrDWord( ULONG64 offset );
//
//ULONG64 ptrDWord( ULONG64 offset, IDebugDataSpaces4* dbgDataSpace );
//
//ULONG64 ptrQWord( ULONG64 offset );
//
//ULONG64 ptrQWord( ULONG64 offset, IDebugDataSpaces4* dbgDataSpace );
//
//ULONG64 ptrMWord( ULONG64 offset );
//
//ULONG64 ptrMWord( ULONG64 offset, IDebugDataSpaces4* dbgDataSpace );
//
//LONG64 ptrSignByte( ULONG64 offset );
//
//LONG64 ptrSignWord( ULONG64 offset );
//
//LONG64 ptrSignDWord( ULONG64 offset );
//
//LONG64 ptrSignQWord( ULONG64 offset );
//
//LONG64 ptrSignMWord( ULONG64 offset );
//
//ULONG64 ptrPtr( ULONG64 offset );
//
//ULONG64 ptrPtr( ULONG64 offset, IDebugDataSpaces4* dbgDataSpace );
//
//bool
//compareMemory( ULONG64 addr1, ULONG64 addr2, ULONG length, bool phyAddr = FALSE );
//
//std::wstring loadUnicodeStr( ULONG64 address );
//
//std::string loadAnsiStr( ULONG64 address );
//
//python::list loadPtrList( ULONG64 address );
//
//python::list loadPtrArray( ULONG64 address, ULONG number );
//
/////////////////////////////////////////////////////////////////////////////////////
//
//};

714
pykd/dia/diawrapper.cpp Normal file
View File

@ -0,0 +1,714 @@
#include "stdafx.h"
#include "dia/diawrapper.h"
#include "win/utils.h"
namespace pykd {
////////////////////////////////////////////////////////////////////////////////
const std::string DiaException::descPrefix("pyDia: ");
std::string DiaException::makeFullDesc(const std::string &desc, HRESULT hres)
{
std::stringstream sstream;
sstream << descPrefix << desc << " failed" << std::endl;
sstream << "Return value is 0x" << std::hex << hres;
PCHAR errMessage = NULL;
FormatMessageA(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
hres,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(PCHAR)&errMessage,
0,
NULL);
if (errMessage)
{
sstream << ": " << std::endl;
sstream << errMessage;
LocalFree(errMessage);
}
else
{
sstream << std::endl;
}
return sstream.str();
}
////////////////////////////////////////////////////////////////////////////////
#define callSymbol(method) \
callSymbolT( &IDiaSymbol::##method, #method)
////////////////////////////////////////////////////////////////////////////////
SymbolPtr loadSymbolFile(const std::string &filePath)
{
HRESULT hres;
DiaDataSourcePtr dataSource;
hres = dataSource.CoCreateInstance(__uuidof(DiaSource), NULL, CLSCTX_INPROC_SERVER);
if ( S_OK != hres )
throw DiaException("Call ::CoCreateInstance", hres);
hres = dataSource->loadDataFromPdb( toWStr(filePath) );
if ( S_OK != hres )
throw DiaException("Call IDiaDataSource::loadDataFromPdb", hres);
DiaSessionPtr _session;
hres = dataSource->openSession(&_session);
if ( S_OK != hres )
throw DiaException("Call IDiaDataSource::openSession", hres);
DiaSymbolPtr _globalScope;
hres = _session->get_globalScope(&_globalScope);
if ( S_OK != hres )
throw DiaException("Call IDiaSymbol::get_globalScope", hres);
return SymbolPtr( new DiaSymbol( _globalScope ) );
}
////////////////////////////////////////////////////////////////////////////////
DiaSymbol::DiaSymbol(__inout DiaSymbolPtr &_symbol )
{
m_symbol = _symbol;
m_symbol->get_machineType(&m_machineType);
}
////////////////////////////////////////////////////////////////////////////////
SymbolPtr DiaSymbol::getChildByName(const std::string &_name)
{
DiaEnumSymbolsPtr symbols;
HRESULT hres =
m_symbol->findChildren(
SymTagNull,
toWStr(_name),
nsCaseSensitive,
&symbols);
if (S_OK != hres)
throw DiaException("Call IDiaSymbol::findChildren", hres);
LONG count;
hres = symbols->get_Count(&count);
if (S_OK != hres)
throw DiaException("Call IDiaEnumSymbols::get_Count", hres);
if (!count)
throw DiaException(_name + " not found");
if (count != 1)
throw DiaException(_name + " is not unique");
DiaSymbolPtr child;
hres = symbols->Item(0, &child);
if (S_OK != hres)
throw DiaException("Call IDiaEnumSymbols::Item", hres);
return SymbolPtr( new DiaSymbol(child) );
}
////////////////////////////////////////////////////////////////////////////////
ULONG DiaSymbol::getRva()
{
return callSymbol(get_relativeVirtualAddress);
}
////////////////////////////////////////////////////////////////////////////////
}; // pykd nemaspace end
//
//#include "diawrapper.h"
//#include "diacallback.h"
//#include "utils.h"
//
//namespace pyDia {
//
//////////////////////////////////////////////////////////////////////////////////
//
////PyObject *Exception::diaExceptTypeObject = NULL;
//
//const std::string Exception::descPrefix("pyDia: ");
//
//////////////////////////////////////////////////////////////////////////////////
//
//#define callSymbol(method) \
// callSymbolT( &IDiaSymbol::##method, #method)
//
//////////////////////////////////////////////////////////////////////////////////
//
//std::string Exception::makeFullDesc(const std::string &desc, HRESULT hres)
//{
// std::stringstream sstream;
// sstream << descPrefix << desc << " failed" << std::endl;
// sstream << "Return value is 0x" << std::hex << hres;
//
// PCHAR errMessage = NULL;
// FormatMessageA(
// FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
// NULL,
// hres,
// MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
// (PCHAR)&errMessage,
// 0,
// NULL);
// if (errMessage)
// {
// sstream << ": " << std::endl;
// sstream << errMessage;
// LocalFree(errMessage);
// }
// else
// {
// sstream << std::endl;
// }
//
// return sstream.str();
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//SymbolPtrList Symbol::findChildrenImpl(
// ULONG symTag,
// const std::string &name,
// DWORD nameCmpFlags
//)
//{
// DiaEnumSymbolsPtr symbols;
// HRESULT hres;
//
// if ( name.empty() )
// {
// hres = m_symbol->findChildren(
// static_cast<enum SymTagEnum>(symTag),
// NULL,
// nameCmpFlags,
// &symbols);
//
// }
// else
// {
// hres = m_symbol->findChildren(
// static_cast<enum SymTagEnum>(symTag),
// toWStr(name),
// nameCmpFlags,
// &symbols);
// }
//
// if (S_OK != hres)
// throw Exception("Call IDiaSymbol::findChildren", hres);
//
// SymbolPtrList childList;
//
// DiaSymbolPtr child;
// ULONG celt;
// while ( SUCCEEDED(symbols->Next(1, &child, &celt)) && (celt == 1) )
// childList.push_back( SymbolPtr( new Symbol(child, m_machineType) ) );
//
// return childList;
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//ULONGLONG Symbol::getSize()
//{
// return callSymbol(get_length);
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//std::string Symbol::getName()
//{
// autoBstr retValue( callSymbol(get_name) );
// return retValue.asStr();
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//std::string Symbol::getUndecoratedName()
//{
// autoBstr retValue( callSymbol(get_undecoratedName) );
// return retValue.asStr();
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//SymbolPtr Symbol::getType()
//{
// return SymbolPtr( new Symbol(callSymbol(get_type), m_machineType) );
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//SymbolPtr Symbol::getIndexType()
//{
// return SymbolPtr( new Symbol(callSymbol(get_arrayIndexType), m_machineType) );
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//ULONG Symbol::getSymTag()
//{
// return callSymbol(get_symTag);
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//ULONG Symbol::getRva()
//{
// return callSymbol(get_relativeVirtualAddress);
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//ULONGLONG Symbol::getVa()
//{
// return callSymbol(get_virtualAddress);
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//ULONG Symbol::getLocType()
//{
// return callSymbol(get_locationType);
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//LONG Symbol::getOffset()
//{
// return callSymbol(get_offset);
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//ULONG Symbol::getCount()
//{
// return callSymbol(get_count);
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//int Symbol::getVirtualBasePointerOffset()
//{
// return callSymbol(get_virtualBasePointerOffset);
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//ULONG Symbol::getVirtualBaseDispIndex()
//{
// return callSymbol(get_virtualBaseDispIndex);
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//ULONG Symbol::getVirtualBaseDispSize()
//{
// SymbolPtr baseTableType = SymbolPtr( new Symbol( callSymbol(get_virtualBaseTableType), m_machineType ) );
//
// return (ULONG)baseTableType->getType()->getSize();
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//ULONG Symbol::getSection()
//{
// return callSymbol(get_targetSection);
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//void Symbol::getValueImpl(IDiaSymbol *_symbol, VARIANT &vtValue)
//{
// HRESULT hres = _symbol->get_value(&vtValue);
// if (S_OK != hres)
// throw Exception("Call IDiaSymbol::get_value", hres);
//}
//
//void Symbol::getValue( VARIANT &vtValue)
//{
// HRESULT hres = m_symbol->get_value(&vtValue);
// if (S_OK != hres)
// throw Exception("Call IDiaSymbol::get_value", hres);
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//python::object Symbol::getValue()
//{
// VARIANT vtValue = { VT_EMPTY };
// getValueImpl(m_symbol, vtValue);
// switch (vtValue.vt)
// {
// case VT_I1:
// case VT_UI1:
// return python::object( static_cast<ULONG>(vtValue.bVal) );
//
// case VT_BOOL:
// return python::object( static_cast<bool>(!!vtValue.iVal) );
//
// case VT_I2:
// case VT_UI2:
// return python::object( static_cast<ULONG>(vtValue.iVal) );
//
// case VT_I4:
// case VT_UI4:
// case VT_INT:
// case VT_UINT:
// case VT_ERROR:
// case VT_HRESULT:
// return python::object( vtValue.lVal );
//
// case VT_I8:
// case VT_UI8:
// return python::object( vtValue.llVal );
//
// case VT_R4:
// return python::object( double(vtValue.fltVal) );
//
// case VT_R8:
// return python::object( vtValue.dblVal );
//
// case VT_BSTR:
// return python::object( autoBstr::asStr(vtValue.bstrVal).c_str() );
//
// }
// throw Exception("Unknown value type");
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//bool Symbol::isBasicType()
//{
// DWORD baseType = btNoType;
// return
// SUCCEEDED( m_symbol->get_baseType(&baseType) ) &&
// (btNoType != baseType);
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//bool Symbol::isVirtualBaseClass()
//{
// return !!callSymbol(get_virtualBaseClass);
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//bool Symbol::isIndirectVirtualBaseClass()
//{
// return !!callSymbol(get_indirectVirtualBaseClass);
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//ULONG Symbol::getBaseType()
//{
// return callSymbol(get_baseType);
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//ULONG Symbol::getBitPosition()
//{
// return callSymbol(get_bitPosition);
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//ULONG Symbol::getIndexId()
//{
// return callSymbol(get_symIndexId);
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//ULONG Symbol::getUdtKind()
//{
// return callSymbol(get_udtKind);
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//ULONG Symbol::getDataKind()
//{
// return callSymbol(get_dataKind);
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//ULONG Symbol::getRegisterId()
//{
// return callSymbol(get_registerId);
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//bool Symbol::isConstant()
//{
// return !!callSymbol(get_constType);
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//SymbolPtr Symbol::getChildByName(const std::string &_name)
//{
// DiaEnumSymbolsPtr symbols;
// HRESULT hres =
// m_symbol->findChildren(
// SymTagNull,
// toWStr(_name),
// nsCaseSensitive,
// &symbols);
// if (S_OK != hres)
// throw Exception("Call IDiaSymbol::findChildren", hres);
//
// LONG count;
// hres = symbols->get_Count(&count);
// if (S_OK != hres)
// throw Exception("Call IDiaEnumSymbols::get_Count", hres);
//
// if (!count)
// throw Exception(_name + " not found");
//
// if (count != 1)
// throw Exception(_name + " is not unique");
//
// DiaSymbolPtr child;
// hres = symbols->Item(0, &child);
// if (S_OK != hres)
// throw Exception("Call IDiaEnumSymbols::Item", hres);
//
// return SymbolPtr( new Symbol(child, m_machineType) );
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//std::string Symbol::print()
//{
// return printImpl(m_symbol, m_machineType);
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//bool Symbol::eq(Symbol &rhs)
//{
// return getIndexId() == rhs.getIndexId();
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//GlobalScope::GlobalScope(
// __inout DiaDataSourcePtr &dataSource,
// __inout DiaSessionPtr &_session,
// __inout DiaSymbolPtr &_globalScope
//) : Symbol(_globalScope, CV_CFL_80386)
// , m_dataSource( dataSource.Detach() )
// , m_session( _session.Detach() )
//{
// m_symbol->get_machineType(&m_machineType);
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//GlobalScopePtr GlobalScope::loadPdb(const std::string &filePath)
//{
// class CLoaderFromPdb : public IScopeDataLoader {
// public:
// CLoaderFromPdb(const std::string &filePath) : m_filePath(filePath) {}
//
// virtual void loadData(IDiaDataSource *dataSource) override {
// HRESULT hres = dataSource->loadDataFromPdb( toWStr(m_filePath) );
// if ( S_OK != hres )
// throw Exception("Call IDiaDataSource::loadDataFromPdb", hres);
// }
//
// private:
// const std::string &m_filePath;
// } loaderFromPdb(filePath);
//
// return loadImpl(loaderFromPdb);
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//GlobalScopePtr GlobalScope::loadExe(const std::string &filePath, PCSTR searchPath /*= NULL*/)
//{
// if (!searchPath)
// searchPath = "SRV**\\\\symbols\\symbols";
//
// class CLoaderForExe : public IScopeDataLoader {
// public:
// CLoaderForExe(const std::string &filePath, PCSTR searchPath)
// : m_filePath(filePath), m_searchPath(searchPath)
// {
// }
//
// virtual void loadData(IDiaDataSource *dataSource) override {
// LoadCallback loadCallback;
// HRESULT hres =
// dataSource->loadDataForExe( toWStr(m_filePath), toWStr(m_searchPath), &loadCallback );
// if ( S_OK != hres )
// throw Exception("Call IDiaDataSource::loadDataForExe", hres);
// }
//
// private:
// const std::string &m_filePath;
// const std::string m_searchPath;
// } loaderForExe(filePath, searchPath);
//
// return loadImpl(loaderForExe);
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//GlobalScopePtr GlobalScope::loadImpl(IScopeDataLoader &ScopeDataLoader)
//{
// DiaDataSourcePtr dataSource;
//
// HRESULT hres =
// dataSource.CoCreateInstance(__uuidof(DiaSource), NULL, CLSCTX_INPROC_SERVER);
// if ( S_OK != hres )
// throw Exception("Call ::CoCreateInstance", hres);
//
// ScopeDataLoader.loadData(dataSource);
//
// DiaSessionPtr _session;
// hres = dataSource->openSession(&_session);
// if ( S_OK != hres )
// throw Exception("Call IDiaDataSource::openSession", hres);
//
// DiaSymbolPtr _globalScope;
// hres = _session->get_globalScope(&_globalScope);
// if ( S_OK != hres )
// throw Exception("Call IDiaSymbol::get_globalScope", hres);
//
// return GlobalScopePtr( new GlobalScope(dataSource, _session, _globalScope) );
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//SymbolPtr GlobalScope::findByRvaImpl(
// __in ULONG rva,
// __in ULONG symTag,
// __out LONG &displacement
//)
//{
// DiaSymbolPtr child;
// HRESULT hres =
// m_session->findSymbolByRVAEx(
// rva,
// static_cast<enum SymTagEnum>(symTag),
// &child,
// &displacement);
// if (S_OK != hres)
// throw Exception("Call IDiaSession::findSymbolByRVAEx", hres);
// if (!child)
// throw Exception("Call IDiaSession::findSymbolByRVAEx", E_UNEXPECTED);
//
// return SymbolPtr( new Symbol(child, m_machineType) );
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//SymbolPtr GlobalScope::findByVaImpl(
// __in ULONGLONG va,
// __in ULONG symTag,
// __out LONG &displacement
//)
//{
// DiaSymbolPtr child;
// HRESULT hres =
// m_session->findSymbolByVAEx(
// va,
// static_cast<enum SymTagEnum>(symTag),
// &child,
// &displacement);
// if (S_OK != hres)
// throw Exception("Call IDiaSession::findSymbolByVAEx", hres);
// if (!child)
// throw Exception("Call IDiaSession::findSymbolByVAEx", E_UNEXPECTED);
//
// return SymbolPtr( new Symbol(child, m_machineType) );
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//SymbolPtr GlobalScope::getSymbolById(ULONG symId)
//{
// DiaSymbolPtr _symbol;
// HRESULT hres = m_session->symbolById(symId, &_symbol);
// if (S_OK != hres)
// throw Exception("Call IDiaSession::findSymbolByRVAEx", hres);
// if (!_symbol)
// throw Exception("Call IDiaSession::findSymbolByRVAEx", E_UNEXPECTED);
//
// return SymbolPtr( new Symbol(_symbol, m_machineType) );
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//ULONGLONG GlobalScope::getLoadAddress()
//{
// ULONGLONG loadAddress;
// HRESULT hres = m_session->get_loadAddress(&loadAddress);
// if (S_OK != hres)
// throw Exception("Call IDiaSession::get_loadAddress", hres);
// return loadAddress;
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//void GlobalScope::setLoadAddress(ULONGLONG loadAddress)
//{
// HRESULT hres = m_session->put_loadAddress(loadAddress);
// if (S_OK != hres)
// throw Exception("Call IDiaSession::put_loadAddress", hres);
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//}

635
pykd/dia/diawrapper.h Normal file
View File

@ -0,0 +1,635 @@
#pragma once
#include "symengine.h"
#include "dbgexcept.h"
namespace pykd {
//////////////////////////////////////////////////////////////////////////////
typedef CComPtr< IDiaSymbol > DiaSymbolPtr;
typedef CComPtr< IDiaEnumSymbols > DiaEnumSymbolsPtr;
typedef CComPtr< IDiaDataSource > DiaDataSourcePtr;
typedef CComPtr< IDiaSession > DiaSessionPtr;
//////////////////////////////////////////////////////////////////////////////
class DiaException : public SymbolException {
public:
DiaException(const std::string &desc, HRESULT hres)
: SymbolException( makeFullDesc(desc, hres) )
, m_hres(hres)
{
}
DiaException(const std::string &desc)
: SymbolException(descPrefix + desc)
, m_hres(S_FALSE)
{
}
HRESULT getRes() const {
return m_hres;
}
private:
static const std::string descPrefix;
static std::string makeFullDesc(const std::string &desc, HRESULT hres);
HRESULT m_hres;
};
////////////////////////////////////////////////////////////////////////////
class DiaSymbol : public Symbol {
public:
DiaSymbol(__inout DiaSymbolPtr &_symbol );
SymbolPtr getChildByName(const std::string &_name);
ULONG getRva();
//SymbolPtrList findChildrenImpl(
// ULONG symTag,
// const std::string &name = "",
// DWORD nameCmpFlags = 0
//);
//python::list findChildrenEx(
// ULONG symTag,
// const std::string &name = "",
// DWORD nameCmpFlags = 0
//)
//{
// return toPyList( findChildrenImpl(symTag, name, nameCmpFlags) );
//}
//python::list findChildren(
// const std::string &name
//)
//{
// return toPyList( findChildrenImpl(SymTagNull, name, nsfCaseSensitive) );
//}
//ULONGLONG getSize();
//std::string getName();
//std::string getUndecoratedName();
//SymbolPtr getType();
//SymbolPtr getIndexType();
//ULONG getSymTag();
//ULONG getRva();
//ULONGLONG getVa();
//ULONG getLocType();
//LONG getOffset();
//ULONG getCount();
//static void getValueImpl(IDiaSymbol *_symbol, VARIANT &vtValue);
//python::object getValue();
//void getValue( VARIANT &vtValue);
//bool isBasicType();
//bool isVirtualBaseClass();
//bool isIndirectVirtualBaseClass();
//ULONG getBaseType();
//ULONG getBitPosition();
//ULONG getIndexId();
//ULONG getUdtKind();
//ULONG getDataKind();
//ULONG getRegisterId();
//ULONG getMachineType() const {
// return m_machineType;
//}
//SymbolPtr getChildByName(const std::string &_name);
//template<ULONG symTag>
//ULONG getChildCount();
//ULONG getChildCount() {
// return getChildCount<SymTagNull>();
//}
//template<ULONG symTag>
//SymbolPtr getChildByIndex(ULONG _index );
//SymbolPtr getChildByIndex(ULONG _index ) {
// return getChildByIndex<SymTagNull>( _index );
//}
//
//bool isConstant();
//std::string print();
//bool eq(Symbol &rhs);
//int getVirtualBasePointerOffset();
//ULONG getVirtualBaseDispIndex();
//ULONG getVirtualBaseDispSize();
//ULONG getSection();
public:
//typedef std::pair<ULONG, const char *> ValueNameEntry;
//static const ValueNameEntry dataKindName[DataIsConstant + 1];
//static const ValueNameEntry symTagName[SymTagMax];
//static const ValueNameEntry locTypeName[LocTypeMax];
//static const ValueNameEntry basicTypeName[];
//static const size_t cntBasicTypeName;
//static const ValueNameEntry udtKindName[];
//static const size_t cntUdtKindName;
//static const ValueNameEntry i386RegName[];
//static const size_t cntI386RegName;
//static const ValueNameEntry amd64RegName[];
//static const size_t cntAmd64RegName;
//static std::string getBasicTypeName( ULONG basicType );
protected:
//// Check symbols loop
//class checkSymLoop
//{
//public:
// checkSymLoop(checkSymLoop *prev)
// : m_symSetPtr( prev ? prev->m_symSetPtr : symSetPtr(new symSet) )
// {
// }
// bool check(IDiaSymbol *_symbol)
// {
// DWORD symIndexId = 0;
// _symbol->get_symIndexId(&symIndexId);
// return !m_symSetPtr->insert(symIndexId).second;
// }
//private:
// typedef std::set<DWORD> symSet;
// typedef boost::shared_ptr<symSet> symSetPtr;
// symSetPtr m_symSetPtr;
//};
//static std::string printImpl(
// IDiaSymbol *_symbol,
// DWORD machineType,
// ULONG indent = 0,
// checkSymLoop *checkLoopPrev = NULL,
// const char *prefix = NULL
//);
template <typename TRet>
TRet callSymbolT(
HRESULT(STDMETHODCALLTYPE IDiaSymbol::*method)(TRet *),
const char *methodName
)
{
TRet retValue;
HRESULT hres = (m_symbol->*method)(&retValue);
if (S_OK != hres)
throw DiaException(std::string("Call IDiaSymbol::") + methodName, hres);
return retValue;
}
DiaSymbolPtr m_symbol;
DWORD m_machineType;
};
////////////////////////////////////////////////////////////////////////////
} // end pykd namespace
//#include <set>
//
//#include <boost\smart_ptr\scoped_ptr.hpp>
//
//#include <cvconst.h>
//
//#include "utils.h"
//#include "dbgexcept.h"
//
//namespace pyDia {
//
//typedef CComPtr< IDiaSymbol > DiaSymbolPtr;
//typedef CComPtr< IDiaEnumSymbols > DiaEnumSymbolsPtr;
//typedef CComPtr< IDiaDataSource > DiaDataSourcePtr;
//typedef CComPtr< IDiaSession > DiaSessionPtr;
//
//////////////////////////////////////////////////////////////////////////////////
//// DIA Exceptions
//////////////////////////////////////////////////////////////////////////////////
//class Exception : public pykd::SymbolException {
//public:
// Exception(const std::string &desc, HRESULT hres)
// : SymbolException( makeFullDesc(desc, hres) )
// , m_hres(hres)
// {
// }
//
// Exception(const std::string &desc)
// : SymbolException(descPrefix + desc)
// , m_hres(S_FALSE)
// {
// }
//
// HRESULT getRes() const {
// return m_hres;
// }
//private:
//
// static const std::string descPrefix;
//
// static std::string makeFullDesc(const std::string &desc, HRESULT hres);
//
// HRESULT m_hres;
//};
//
//class Symbol;
//typedef boost::shared_ptr< Symbol > SymbolPtr;
//typedef std::list< SymbolPtr > SymbolPtrList;
//
//////////////////////////////////////////////////////////////////////////////////
//// Symbol
//////////////////////////////////////////////////////////////////////////////////
//class Symbol {
//public:
// Symbol()
// {
// throw Exception("DiaSymbol must be created over factory from DiaScope::...");
// }
// Symbol(__inout DiaSymbolPtr &_symbol, DWORD machineType)
// : m_machineType(machineType)
// {
// m_symbol = _symbol.Detach();
// }
// Symbol(__in IDiaSymbol *_symbol, DWORD machineType)
// : m_machineType(machineType)
// {
// m_symbol = _symbol;
// }
//
//
// SymbolPtrList findChildrenImpl(
// ULONG symTag,
// const std::string &name = "",
// DWORD nameCmpFlags = 0
// );
//
// python::list findChildrenEx(
// ULONG symTag,
// const std::string &name = "",
// DWORD nameCmpFlags = 0
// )
// {
// return toPyList( findChildrenImpl(symTag, name, nameCmpFlags) );
// }
//
// python::list findChildren(
// const std::string &name
// )
// {
// return toPyList( findChildrenImpl(SymTagNull, name, nsfCaseSensitive) );
// }
//
// ULONGLONG getSize();
//
// std::string getName();
// std::string getUndecoratedName();
//
// SymbolPtr getType();
//
// SymbolPtr getIndexType();
//
// ULONG getSymTag();
//
// ULONG getRva();
// ULONGLONG getVa();
//
// ULONG getLocType();
//
// LONG getOffset();
//
// ULONG getCount();
//
// static void getValueImpl(IDiaSymbol *_symbol, VARIANT &vtValue);
// python::object getValue();
// void getValue( VARIANT &vtValue);
//
// bool isBasicType();
//
// bool isVirtualBaseClass();
//
// bool isIndirectVirtualBaseClass();
//
// ULONG getBaseType();
//
// ULONG getBitPosition();
//
// ULONG getIndexId();
//
// ULONG getUdtKind();
//
// ULONG getDataKind();
//
// ULONG getRegisterId();
//
// ULONG getMachineType() const {
// return m_machineType;
// }
//
// SymbolPtr getChildByName(const std::string &_name);
//
// template<ULONG symTag>
// ULONG getChildCount();
//
// ULONG getChildCount() {
// return getChildCount<SymTagNull>();
// }
//
// template<ULONG symTag>
// SymbolPtr getChildByIndex(ULONG _index );
//
// SymbolPtr getChildByIndex(ULONG _index ) {
// return getChildByIndex<SymTagNull>( _index );
// }
//
// bool isConstant();
//
// std::string print();
//
// bool eq(Symbol &rhs);
//
// int getVirtualBasePointerOffset();
//
// ULONG getVirtualBaseDispIndex();
//
// ULONG getVirtualBaseDispSize();
//
// ULONG getSection();
//
//public:
// typedef std::pair<ULONG, const char *> ValueNameEntry;
//
// static const ValueNameEntry dataKindName[DataIsConstant + 1];
//
// static const ValueNameEntry symTagName[SymTagMax];
//
// static const ValueNameEntry locTypeName[LocTypeMax];
//
// static const ValueNameEntry basicTypeName[];
// static const size_t cntBasicTypeName;
//
// static const ValueNameEntry udtKindName[];
// static const size_t cntUdtKindName;
//
// static const ValueNameEntry i386RegName[];
// static const size_t cntI386RegName;
//
// static const ValueNameEntry amd64RegName[];
// static const size_t cntAmd64RegName;
//
// static std::string getBasicTypeName( ULONG basicType );
//
//protected:
//
// // Check symbols loop
// class checkSymLoop
// {
// public:
// checkSymLoop(checkSymLoop *prev)
// : m_symSetPtr( prev ? prev->m_symSetPtr : symSetPtr(new symSet) )
// {
// }
//
// bool check(IDiaSymbol *_symbol)
// {
// DWORD symIndexId = 0;
// _symbol->get_symIndexId(&symIndexId);
// return !m_symSetPtr->insert(symIndexId).second;
// }
//
// private:
// typedef std::set<DWORD> symSet;
// typedef boost::shared_ptr<symSet> symSetPtr;
// symSetPtr m_symSetPtr;
// };
//
// static std::string printImpl(
// IDiaSymbol *_symbol,
// DWORD machineType,
// ULONG indent = 0,
// checkSymLoop *checkLoopPrev = NULL,
// const char *prefix = NULL
// );
//
// template <typename TRet>
// TRet callSymbolT(
// HRESULT(STDMETHODCALLTYPE IDiaSymbol::*method)(TRet *),
// const char *methodName
// )
// {
// TRet retValue;
// HRESULT hres = (m_symbol->*method)(&retValue);
// if (S_OK != hres)
// throw Exception(std::string("Call IDiaSymbol::") + methodName, hres);
//
// return retValue;
// }
//
// DiaSymbolPtr m_symbol;
// DWORD m_machineType;
//};
//
//class GlobalScope;
//typedef boost::shared_ptr< GlobalScope > GlobalScopePtr;
//
//////////////////////////////////////////////////////////////////////////////////
//// Global scope: source + sessions
//////////////////////////////////////////////////////////////////////////////////
//class GlobalScope : public Symbol {
//public:
// GlobalScope() {}
//
// // GlobalScope factory
// static GlobalScopePtr loadPdb(const std::string &filePath);
// static GlobalScopePtr loadExe(const std::string &filePath, PCSTR searchPath = NULL);
//
// // RVA -> Symbol
// python::tuple findByRva(
// ULONG rva,
// ULONG symTag
// )
// {
// LONG displacement;
// SymbolPtr child = findByRvaImpl(rva, symTag, displacement);
// return python::make_tuple(child, displacement);
// }
// SymbolPtr findByRvaImpl(
// __in ULONG rva,
// __in ULONG symTag,
// __out LONG &displacement
// );
//
// // VA -> Symbol
// python::tuple findByVa(
// ULONG va,
// ULONG symTag
// )
// {
// LONG displacement;
// SymbolPtr child = findByVaImpl(va, symTag, displacement);
// return python::make_tuple(child, displacement);
// }
// SymbolPtr findByVaImpl(
// __in ULONGLONG va,
// __in ULONG symTag,
// __out LONG &displacement
// );
//
// // get symbol by unique index
// SymbolPtr getSymbolById(ULONG symId);
//
// // get/set load address
// ULONGLONG getLoadAddress();
// void setLoadAddress(ULONGLONG loadAddress);
//
//private:
// interface IScopeDataLoader {
// virtual ~IScopeDataLoader() {}
// virtual void loadData(IDiaDataSource *dataSource) = 0;
// };
// static GlobalScopePtr loadImpl(IScopeDataLoader &ScopeDataLoader);
//
// GlobalScope(
// __inout DiaDataSourcePtr &dataSource,
// __inout DiaSessionPtr &_session,
// __inout DiaSymbolPtr &_globalScope
// );
//
// DiaDataSourcePtr m_dataSource;
// DiaSessionPtr m_session;
//};
//
//////////////////////////////////////////////////////////////////////////////////
//
//template<ULONG symTag>
//ULONG Symbol::getChildCount()
//{
// DiaEnumSymbolsPtr symbols;
// HRESULT hres =
// m_symbol->findChildren(
// static_cast<enum SymTagEnum>(symTag),
// NULL,
// nsCaseSensitive,
// &symbols);
// if (S_OK != hres)
// throw Exception("Call IDiaSymbol::findChildren", hres);
//
// LONG count;
// hres = symbols->get_Count(&count);
// if (S_OK != hres)
// throw Exception("Call IDiaEnumSymbols::get_Count", hres);
//
// return count;
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//template<ULONG symTag>
//SymbolPtr Symbol::getChildByIndex(ULONG _index )
//{
// DiaEnumSymbolsPtr symbols;
// HRESULT hres =
// m_symbol->findChildren(
// static_cast<enum SymTagEnum>(symTag),
// NULL,
// nsCaseSensitive,
// &symbols);
// if (S_OK != hres)
// throw Exception("Call IDiaSymbol::findChildren", hres);
//
// LONG count;
// hres = symbols->get_Count(&count);
// if (S_OK != hres)
// throw Exception("Call IDiaEnumSymbols::get_Count", hres);
//
// if (LONG(_index) >= count)
// {
// PyErr_SetString(PyExc_IndexError, "Index out of range");
// boost::python::throw_error_already_set();
// }
//
// DiaSymbolPtr child;
// hres = symbols->Item(_index, &child);
// if (S_OK != hres)
// throw Exception("Call IDiaEnumSymbols::Item", hres);
//
// return SymbolPtr( new Symbol(child, m_machineType) );
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//};

View File

@ -1,555 +0,0 @@
#include "stdafx.h"
#include "diawrapper.h"
#include "diacallback.h"
#include "utils.h"
namespace pyDia {
////////////////////////////////////////////////////////////////////////////////
//PyObject *Exception::diaExceptTypeObject = NULL;
const std::string Exception::descPrefix("pyDia: ");
////////////////////////////////////////////////////////////////////////////////
#define callSymbol(method) \
callSymbolT( &IDiaSymbol::##method, #method)
////////////////////////////////////////////////////////////////////////////////
std::string Exception::makeFullDesc(const std::string &desc, HRESULT hres)
{
std::stringstream sstream;
sstream << descPrefix << desc << " failed" << std::endl;
sstream << "Return value is 0x" << std::hex << hres;
PCHAR errMessage = NULL;
FormatMessageA(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
hres,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(PCHAR)&errMessage,
0,
NULL);
if (errMessage)
{
sstream << ": " << std::endl;
sstream << errMessage;
LocalFree(errMessage);
}
else
{
sstream << std::endl;
}
return sstream.str();
}
////////////////////////////////////////////////////////////////////////////////
SymbolPtrList Symbol::findChildrenImpl(
ULONG symTag,
const std::string &name,
DWORD nameCmpFlags
)
{
DiaEnumSymbolsPtr symbols;
HRESULT hres;
if ( name.empty() )
{
hres = m_symbol->findChildren(
static_cast<enum SymTagEnum>(symTag),
NULL,
nameCmpFlags,
&symbols);
}
else
{
hres = m_symbol->findChildren(
static_cast<enum SymTagEnum>(symTag),
toWStr(name),
nameCmpFlags,
&symbols);
}
if (S_OK != hres)
throw Exception("Call IDiaSymbol::findChildren", hres);
SymbolPtrList childList;
DiaSymbolPtr child;
ULONG celt;
while ( SUCCEEDED(symbols->Next(1, &child, &celt)) && (celt == 1) )
childList.push_back( SymbolPtr( new Symbol(child, m_machineType) ) );
return childList;
}
////////////////////////////////////////////////////////////////////////////////
ULONGLONG Symbol::getSize()
{
return callSymbol(get_length);
}
////////////////////////////////////////////////////////////////////////////////
std::string Symbol::getName()
{
autoBstr retValue( callSymbol(get_name) );
return retValue.asStr();
}
////////////////////////////////////////////////////////////////////////////////
std::string Symbol::getUndecoratedName()
{
autoBstr retValue( callSymbol(get_undecoratedName) );
return retValue.asStr();
}
////////////////////////////////////////////////////////////////////////////////
SymbolPtr Symbol::getType()
{
return SymbolPtr( new Symbol(callSymbol(get_type), m_machineType) );
}
////////////////////////////////////////////////////////////////////////////////
SymbolPtr Symbol::getIndexType()
{
return SymbolPtr( new Symbol(callSymbol(get_arrayIndexType), m_machineType) );
}
////////////////////////////////////////////////////////////////////////////////
ULONG Symbol::getSymTag()
{
return callSymbol(get_symTag);
}
////////////////////////////////////////////////////////////////////////////////
ULONG Symbol::getRva()
{
return callSymbol(get_relativeVirtualAddress);
}
////////////////////////////////////////////////////////////////////////////////
ULONGLONG Symbol::getVa()
{
return callSymbol(get_virtualAddress);
}
////////////////////////////////////////////////////////////////////////////////
ULONG Symbol::getLocType()
{
return callSymbol(get_locationType);
}
////////////////////////////////////////////////////////////////////////////////
LONG Symbol::getOffset()
{
return callSymbol(get_offset);
}
////////////////////////////////////////////////////////////////////////////////
ULONG Symbol::getCount()
{
return callSymbol(get_count);
}
////////////////////////////////////////////////////////////////////////////////
int Symbol::getVirtualBasePointerOffset()
{
return callSymbol(get_virtualBasePointerOffset);
}
////////////////////////////////////////////////////////////////////////////////
ULONG Symbol::getVirtualBaseDispIndex()
{
return callSymbol(get_virtualBaseDispIndex);
}
////////////////////////////////////////////////////////////////////////////////
ULONG Symbol::getVirtualBaseDispSize()
{
SymbolPtr baseTableType = SymbolPtr( new Symbol( callSymbol(get_virtualBaseTableType), m_machineType ) );
return (ULONG)baseTableType->getType()->getSize();
}
////////////////////////////////////////////////////////////////////////////////
ULONG Symbol::getSection()
{
return callSymbol(get_targetSection);
}
////////////////////////////////////////////////////////////////////////////////
void Symbol::getValueImpl(IDiaSymbol *_symbol, VARIANT &vtValue)
{
HRESULT hres = _symbol->get_value(&vtValue);
if (S_OK != hres)
throw Exception("Call IDiaSymbol::get_value", hres);
}
void Symbol::getValue( VARIANT &vtValue)
{
HRESULT hres = m_symbol->get_value(&vtValue);
if (S_OK != hres)
throw Exception("Call IDiaSymbol::get_value", hres);
}
////////////////////////////////////////////////////////////////////////////////
python::object Symbol::getValue()
{
VARIANT vtValue = { VT_EMPTY };
getValueImpl(m_symbol, vtValue);
switch (vtValue.vt)
{
case VT_I1:
case VT_UI1:
return python::object( static_cast<ULONG>(vtValue.bVal) );
case VT_BOOL:
return python::object( static_cast<bool>(!!vtValue.iVal) );
case VT_I2:
case VT_UI2:
return python::object( static_cast<ULONG>(vtValue.iVal) );
case VT_I4:
case VT_UI4:
case VT_INT:
case VT_UINT:
case VT_ERROR:
case VT_HRESULT:
return python::object( vtValue.lVal );
case VT_I8:
case VT_UI8:
return python::object( vtValue.llVal );
case VT_R4:
return python::object( double(vtValue.fltVal) );
case VT_R8:
return python::object( vtValue.dblVal );
case VT_BSTR:
return python::object( autoBstr::asStr(vtValue.bstrVal).c_str() );
}
throw Exception("Unknown value type");
}
////////////////////////////////////////////////////////////////////////////////
bool Symbol::isBasicType()
{
DWORD baseType = btNoType;
return
SUCCEEDED( m_symbol->get_baseType(&baseType) ) &&
(btNoType != baseType);
}
////////////////////////////////////////////////////////////////////////////////
bool Symbol::isVirtualBaseClass()
{
return !!callSymbol(get_virtualBaseClass);
}
////////////////////////////////////////////////////////////////////////////////
bool Symbol::isIndirectVirtualBaseClass()
{
return !!callSymbol(get_indirectVirtualBaseClass);
}
////////////////////////////////////////////////////////////////////////////////
ULONG Symbol::getBaseType()
{
return callSymbol(get_baseType);
}
////////////////////////////////////////////////////////////////////////////////
ULONG Symbol::getBitPosition()
{
return callSymbol(get_bitPosition);
}
////////////////////////////////////////////////////////////////////////////////
ULONG Symbol::getIndexId()
{
return callSymbol(get_symIndexId);
}
////////////////////////////////////////////////////////////////////////////////
ULONG Symbol::getUdtKind()
{
return callSymbol(get_udtKind);
}
////////////////////////////////////////////////////////////////////////////////
ULONG Symbol::getDataKind()
{
return callSymbol(get_dataKind);
}
////////////////////////////////////////////////////////////////////////////////
ULONG Symbol::getRegisterId()
{
return callSymbol(get_registerId);
}
////////////////////////////////////////////////////////////////////////////////
bool Symbol::isConstant()
{
return !!callSymbol(get_constType);
}
////////////////////////////////////////////////////////////////////////////////
SymbolPtr Symbol::getChildByName(const std::string &_name)
{
DiaEnumSymbolsPtr symbols;
HRESULT hres =
m_symbol->findChildren(
SymTagNull,
toWStr(_name),
nsCaseSensitive,
&symbols);
if (S_OK != hres)
throw Exception("Call IDiaSymbol::findChildren", hres);
LONG count;
hres = symbols->get_Count(&count);
if (S_OK != hres)
throw Exception("Call IDiaEnumSymbols::get_Count", hres);
if (!count)
throw Exception(_name + " not found");
if (count != 1)
throw Exception(_name + " is not unique");
DiaSymbolPtr child;
hres = symbols->Item(0, &child);
if (S_OK != hres)
throw Exception("Call IDiaEnumSymbols::Item", hres);
return SymbolPtr( new Symbol(child, m_machineType) );
}
////////////////////////////////////////////////////////////////////////////////
std::string Symbol::print()
{
return printImpl(m_symbol, m_machineType);
}
////////////////////////////////////////////////////////////////////////////////
bool Symbol::eq(Symbol &rhs)
{
return getIndexId() == rhs.getIndexId();
}
////////////////////////////////////////////////////////////////////////////////
GlobalScope::GlobalScope(
__inout DiaDataSourcePtr &dataSource,
__inout DiaSessionPtr &_session,
__inout DiaSymbolPtr &_globalScope
) : Symbol(_globalScope, CV_CFL_80386)
, m_dataSource( dataSource.Detach() )
, m_session( _session.Detach() )
{
m_symbol->get_machineType(&m_machineType);
}
////////////////////////////////////////////////////////////////////////////////
GlobalScopePtr GlobalScope::loadPdb(const std::string &filePath)
{
class CLoaderFromPdb : public IScopeDataLoader {
public:
CLoaderFromPdb(const std::string &filePath) : m_filePath(filePath) {}
virtual void loadData(IDiaDataSource *dataSource) override {
HRESULT hres = dataSource->loadDataFromPdb( toWStr(m_filePath) );
if ( S_OK != hres )
throw Exception("Call IDiaDataSource::loadDataFromPdb", hres);
}
private:
const std::string &m_filePath;
} loaderFromPdb(filePath);
return loadImpl(loaderFromPdb);
}
////////////////////////////////////////////////////////////////////////////////
GlobalScopePtr GlobalScope::loadExe(const std::string &filePath, PCSTR searchPath /*= NULL*/)
{
if (!searchPath)
searchPath = "SRV**\\\\symbols\\symbols";
class CLoaderForExe : public IScopeDataLoader {
public:
CLoaderForExe(const std::string &filePath, PCSTR searchPath)
: m_filePath(filePath), m_searchPath(searchPath)
{
}
virtual void loadData(IDiaDataSource *dataSource) override {
LoadCallback loadCallback;
HRESULT hres =
dataSource->loadDataForExe( toWStr(m_filePath), toWStr(m_searchPath), &loadCallback );
if ( S_OK != hres )
throw Exception("Call IDiaDataSource::loadDataForExe", hres);
}
private:
const std::string &m_filePath;
const std::string m_searchPath;
} loaderForExe(filePath, searchPath);
return loadImpl(loaderForExe);
}
////////////////////////////////////////////////////////////////////////////////
GlobalScopePtr GlobalScope::loadImpl(IScopeDataLoader &ScopeDataLoader)
{
DiaDataSourcePtr dataSource;
HRESULT hres =
dataSource.CoCreateInstance(__uuidof(DiaSource), NULL, CLSCTX_INPROC_SERVER);
if ( S_OK != hres )
throw Exception("Call ::CoCreateInstance", hres);
ScopeDataLoader.loadData(dataSource);
DiaSessionPtr _session;
hres = dataSource->openSession(&_session);
if ( S_OK != hres )
throw Exception("Call IDiaDataSource::openSession", hres);
DiaSymbolPtr _globalScope;
hres = _session->get_globalScope(&_globalScope);
if ( S_OK != hres )
throw Exception("Call IDiaSymbol::get_globalScope", hres);
return GlobalScopePtr( new GlobalScope(dataSource, _session, _globalScope) );
}
////////////////////////////////////////////////////////////////////////////////
SymbolPtr GlobalScope::findByRvaImpl(
__in ULONG rva,
__in ULONG symTag,
__out LONG &displacement
)
{
DiaSymbolPtr child;
HRESULT hres =
m_session->findSymbolByRVAEx(
rva,
static_cast<enum SymTagEnum>(symTag),
&child,
&displacement);
if (S_OK != hres)
throw Exception("Call IDiaSession::findSymbolByRVAEx", hres);
if (!child)
throw Exception("Call IDiaSession::findSymbolByRVAEx", E_UNEXPECTED);
return SymbolPtr( new Symbol(child, m_machineType) );
}
////////////////////////////////////////////////////////////////////////////////
SymbolPtr GlobalScope::findByVaImpl(
__in ULONGLONG va,
__in ULONG symTag,
__out LONG &displacement
)
{
DiaSymbolPtr child;
HRESULT hres =
m_session->findSymbolByVAEx(
va,
static_cast<enum SymTagEnum>(symTag),
&child,
&displacement);
if (S_OK != hres)
throw Exception("Call IDiaSession::findSymbolByVAEx", hres);
if (!child)
throw Exception("Call IDiaSession::findSymbolByVAEx", E_UNEXPECTED);
return SymbolPtr( new Symbol(child, m_machineType) );
}
////////////////////////////////////////////////////////////////////////////////
SymbolPtr GlobalScope::getSymbolById(ULONG symId)
{
DiaSymbolPtr _symbol;
HRESULT hres = m_session->symbolById(symId, &_symbol);
if (S_OK != hres)
throw Exception("Call IDiaSession::findSymbolByRVAEx", hres);
if (!_symbol)
throw Exception("Call IDiaSession::findSymbolByRVAEx", E_UNEXPECTED);
return SymbolPtr( new Symbol(_symbol, m_machineType) );
}
////////////////////////////////////////////////////////////////////////////////
ULONGLONG GlobalScope::getLoadAddress()
{
ULONGLONG loadAddress;
HRESULT hres = m_session->get_loadAddress(&loadAddress);
if (S_OK != hres)
throw Exception("Call IDiaSession::get_loadAddress", hres);
return loadAddress;
}
////////////////////////////////////////////////////////////////////////////////
void GlobalScope::setLoadAddress(ULONGLONG loadAddress)
{
HRESULT hres = m_session->put_loadAddress(loadAddress);
if (S_OK != hres)
throw Exception("Call IDiaSession::put_loadAddress", hres);
}
////////////////////////////////////////////////////////////////////////////////
}

View File

@ -1,373 +0,0 @@
#pragma once
#include <set>
#include <boost\smart_ptr\scoped_ptr.hpp>
#include <cvconst.h>
#include "utils.h"
#include "dbgexcept.h"
namespace pyDia {
typedef CComPtr< IDiaSymbol > DiaSymbolPtr;
typedef CComPtr< IDiaEnumSymbols > DiaEnumSymbolsPtr;
typedef CComPtr< IDiaDataSource > DiaDataSourcePtr;
typedef CComPtr< IDiaSession > DiaSessionPtr;
////////////////////////////////////////////////////////////////////////////////
// DIA Exceptions
////////////////////////////////////////////////////////////////////////////////
class Exception : public pykd::SymbolException {
public:
Exception(const std::string &desc, HRESULT hres)
: SymbolException( makeFullDesc(desc, hres) )
, m_hres(hres)
{
}
Exception(const std::string &desc)
: SymbolException(descPrefix + desc)
, m_hres(S_FALSE)
{
}
HRESULT getRes() const {
return m_hres;
}
private:
static const std::string descPrefix;
static std::string makeFullDesc(const std::string &desc, HRESULT hres);
HRESULT m_hres;
};
class Symbol;
typedef boost::shared_ptr< Symbol > SymbolPtr;
typedef std::list< SymbolPtr > SymbolPtrList;
////////////////////////////////////////////////////////////////////////////////
// Symbol
////////////////////////////////////////////////////////////////////////////////
class Symbol {
public:
Symbol()
{
throw Exception("DiaSymbol must be created over factory from DiaScope::...");
}
Symbol(__inout DiaSymbolPtr &_symbol, DWORD machineType)
: m_machineType(machineType)
{
m_symbol = _symbol.Detach();
}
Symbol(__in IDiaSymbol *_symbol, DWORD machineType)
: m_machineType(machineType)
{
m_symbol = _symbol;
}
SymbolPtrList findChildrenImpl(
ULONG symTag,
const std::string &name = "",
DWORD nameCmpFlags = 0
);
python::list findChildrenEx(
ULONG symTag,
const std::string &name = "",
DWORD nameCmpFlags = 0
)
{
return toPyList( findChildrenImpl(symTag, name, nameCmpFlags) );
}
python::list findChildren(
const std::string &name
)
{
return toPyList( findChildrenImpl(SymTagNull, name, nsfCaseSensitive) );
}
ULONGLONG getSize();
std::string getName();
std::string getUndecoratedName();
SymbolPtr getType();
SymbolPtr getIndexType();
ULONG getSymTag();
ULONG getRva();
ULONGLONG getVa();
ULONG getLocType();
LONG getOffset();
ULONG getCount();
static void getValueImpl(IDiaSymbol *_symbol, VARIANT &vtValue);
python::object getValue();
void getValue( VARIANT &vtValue);
bool isBasicType();
bool isVirtualBaseClass();
bool isIndirectVirtualBaseClass();
ULONG getBaseType();
ULONG getBitPosition();
ULONG getIndexId();
ULONG getUdtKind();
ULONG getDataKind();
ULONG getRegisterId();
ULONG getMachineType() const {
return m_machineType;
}
SymbolPtr getChildByName(const std::string &_name);
template<ULONG symTag>
ULONG getChildCount();
ULONG getChildCount() {
return getChildCount<SymTagNull>();
}
template<ULONG symTag>
SymbolPtr getChildByIndex(ULONG _index );
SymbolPtr getChildByIndex(ULONG _index ) {
return getChildByIndex<SymTagNull>( _index );
}
bool isConstant();
std::string print();
bool eq(Symbol &rhs);
int getVirtualBasePointerOffset();
ULONG getVirtualBaseDispIndex();
ULONG getVirtualBaseDispSize();
ULONG getSection();
public:
typedef std::pair<ULONG, const char *> ValueNameEntry;
static const ValueNameEntry dataKindName[DataIsConstant + 1];
static const ValueNameEntry symTagName[SymTagMax];
static const ValueNameEntry locTypeName[LocTypeMax];
static const ValueNameEntry basicTypeName[];
static const size_t cntBasicTypeName;
static const ValueNameEntry udtKindName[];
static const size_t cntUdtKindName;
static const ValueNameEntry i386RegName[];
static const size_t cntI386RegName;
static const ValueNameEntry amd64RegName[];
static const size_t cntAmd64RegName;
static std::string getBasicTypeName( ULONG basicType );
protected:
// Check symbols loop
class checkSymLoop
{
public:
checkSymLoop(checkSymLoop *prev)
: m_symSetPtr( prev ? prev->m_symSetPtr : symSetPtr(new symSet) )
{
}
bool check(IDiaSymbol *_symbol)
{
DWORD symIndexId = 0;
_symbol->get_symIndexId(&symIndexId);
return !m_symSetPtr->insert(symIndexId).second;
}
private:
typedef std::set<DWORD> symSet;
typedef boost::shared_ptr<symSet> symSetPtr;
symSetPtr m_symSetPtr;
};
static std::string printImpl(
IDiaSymbol *_symbol,
DWORD machineType,
ULONG indent = 0,
checkSymLoop *checkLoopPrev = NULL,
const char *prefix = NULL
);
template <typename TRet>
TRet callSymbolT(
HRESULT(STDMETHODCALLTYPE IDiaSymbol::*method)(TRet *),
const char *methodName
)
{
TRet retValue;
HRESULT hres = (m_symbol->*method)(&retValue);
if (S_OK != hres)
throw Exception(std::string("Call IDiaSymbol::") + methodName, hres);
return retValue;
}
DiaSymbolPtr m_symbol;
DWORD m_machineType;
};
class GlobalScope;
typedef boost::shared_ptr< GlobalScope > GlobalScopePtr;
////////////////////////////////////////////////////////////////////////////////
// Global scope: source + sessions
////////////////////////////////////////////////////////////////////////////////
class GlobalScope : public Symbol {
public:
GlobalScope() {}
// GlobalScope factory
static GlobalScopePtr loadPdb(const std::string &filePath);
static GlobalScopePtr loadExe(const std::string &filePath, PCSTR searchPath = NULL);
// RVA -> Symbol
python::tuple findByRva(
ULONG rva,
ULONG symTag
)
{
LONG displacement;
SymbolPtr child = findByRvaImpl(rva, symTag, displacement);
return python::make_tuple(child, displacement);
}
SymbolPtr findByRvaImpl(
__in ULONG rva,
__in ULONG symTag,
__out LONG &displacement
);
// VA -> Symbol
python::tuple findByVa(
ULONG va,
ULONG symTag
)
{
LONG displacement;
SymbolPtr child = findByVaImpl(va, symTag, displacement);
return python::make_tuple(child, displacement);
}
SymbolPtr findByVaImpl(
__in ULONGLONG va,
__in ULONG symTag,
__out LONG &displacement
);
// get symbol by unique index
SymbolPtr getSymbolById(ULONG symId);
// get/set load address
ULONGLONG getLoadAddress();
void setLoadAddress(ULONGLONG loadAddress);
private:
interface IScopeDataLoader {
virtual ~IScopeDataLoader() {}
virtual void loadData(IDiaDataSource *dataSource) = 0;
};
static GlobalScopePtr loadImpl(IScopeDataLoader &ScopeDataLoader);
GlobalScope(
__inout DiaDataSourcePtr &dataSource,
__inout DiaSessionPtr &_session,
__inout DiaSymbolPtr &_globalScope
);
DiaDataSourcePtr m_dataSource;
DiaSessionPtr m_session;
};
////////////////////////////////////////////////////////////////////////////////
template<ULONG symTag>
ULONG Symbol::getChildCount()
{
DiaEnumSymbolsPtr symbols;
HRESULT hres =
m_symbol->findChildren(
static_cast<enum SymTagEnum>(symTag),
NULL,
nsCaseSensitive,
&symbols);
if (S_OK != hres)
throw Exception("Call IDiaSymbol::findChildren", hres);
LONG count;
hres = symbols->get_Count(&count);
if (S_OK != hres)
throw Exception("Call IDiaEnumSymbols::get_Count", hres);
return count;
}
////////////////////////////////////////////////////////////////////////////////
template<ULONG symTag>
SymbolPtr Symbol::getChildByIndex(ULONG _index )
{
DiaEnumSymbolsPtr symbols;
HRESULT hres =
m_symbol->findChildren(
static_cast<enum SymTagEnum>(symTag),
NULL,
nsCaseSensitive,
&symbols);
if (S_OK != hres)
throw Exception("Call IDiaSymbol::findChildren", hres);
LONG count;
hres = symbols->get_Count(&count);
if (S_OK != hres)
throw Exception("Call IDiaEnumSymbols::get_Count", hres);
if (LONG(_index) >= count)
{
PyErr_SetString(PyExc_IndexError, "Index out of range");
boost::python::throw_error_already_set();
}
DiaSymbolPtr child;
hres = symbols->Item(_index, &child);
if (S_OK != hres)
throw Exception("Call IDiaEnumSymbols::Item", hres);
return SymbolPtr( new Symbol(child, m_machineType) );
}
////////////////////////////////////////////////////////////////////////////////
};

View File

@ -1,6 +1,7 @@
#include "stdafx.h"
#include "dbgengine.h"
#include "module.h"
#include "dbgexcept.h"
namespace pykd {
@ -32,6 +33,38 @@ Module::Module(ULONG64 offset )
/////////////////////////////////////////////////////////////////////////////////////
SymbolPtr& Module::getSymScope()
{
do {
if ( m_symScope )
break;
std::string symbolName = getModuleSymbolFileName( m_base );
if ( symbolName.empty() )
break;
m_symScope = loadSymbolFile( symbolName );
} while( false );
if ( !m_symScope )
throw SymbolException( "failed to find symbol file" );
return m_symScope;
}
/////////////////////////////////////////////////////////////////////////////////////
ULONG Module::getRvaByName(const std::string &symName)
{
SymbolPtr &symScope = getSymScope();
SymbolPtr child = symScope->getChildByName( symName );
return child->getRva();
}
/////////////////////////////////////////////////////////////////////////////////////
}; // end of namespace pykd
@ -39,6 +72,17 @@ Module::Module(ULONG64 offset )
//#include "module.h"
//#include "dbgclient.h"
//#include "dbgmem.h"

View File

@ -1,6 +1,7 @@
#pragma once
#include "intbase.h"
#include "symengine.h"
namespace pykd {
@ -48,15 +49,31 @@ public:
{
}
ULONG64
getSymbol( const std::string &symbolname ) {
return m_base + getRvaByName(symbolname);
}
ULONG
getSymbolRva( const std::string &symbolname ) {
return getRvaByName(symbolname);
}
private:
SymbolPtr& getSymScope();
BaseTypeVariant getValue() {
return BaseTypeVariant(m_base);
}
ULONG getRvaByName(const std::string &symName);
std::string m_name;
ULONG64 m_base;
ULONG m_size;
SymbolPtr m_symScope;
};
///////////////////////////////////////////////////////////////////////////////////

View File

@ -45,7 +45,7 @@
Name="VCCLCompilerTool"
AdditionalOptions="/bigobj"
Optimization="0"
AdditionalIncludeDirectories="&quot;$(DIA_SDK_ROOT)\include&quot;;&quot;$(DBG_SDK_ROOT)\inc&quot;;&quot;$(BOOST_ROOT)&quot;;&quot;$(PYTHON_ROOT)\x86\include&quot;"
AdditionalIncludeDirectories="&quot;$(ProjectDir)&quot;;&quot;$(DIA_SDK_ROOT)\include&quot;;&quot;$(DBG_SDK_ROOT)\inc&quot;;&quot;$(BOOST_ROOT)&quot;;&quot;$(PYTHON_ROOT)\x64\include&quot;"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;PYKD_EXPORTS"
GeneratePreprocessedFile="0"
KeepComments="false"
@ -126,7 +126,7 @@
Name="VCCLCompilerTool"
AdditionalOptions="/bigobj"
Optimization="0"
AdditionalIncludeDirectories="&quot;$(DIA_SDK_ROOT)\include&quot;;&quot;$(DBG_SDK_ROOT)\inc&quot;;&quot;$(BOOST_ROOT)&quot;;&quot;$(PYTHON_ROOT)\x64\include&quot;"
AdditionalIncludeDirectories="&quot;$(ProjectDir)&quot;;&quot;$(DIA_SDK_ROOT)\include&quot;;&quot;$(DBG_SDK_ROOT)\inc&quot;;&quot;$(BOOST_ROOT)&quot;;&quot;$(PYTHON_ROOT)\x64\include&quot;"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;PYKD_EXPORTS"
GeneratePreprocessedFile="0"
KeepComments="false"
@ -207,7 +207,7 @@
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/bigobj"
AdditionalIncludeDirectories="&quot;$(DIA_SDK_ROOT)\include&quot;;&quot;$(DBG_SDK_ROOT)\inc&quot;;&quot;$(BOOST_ROOT)&quot;;&quot;$(PYTHON_ROOT)\x86\include&quot;"
AdditionalIncludeDirectories="&quot;$(ProjectDir)&quot;;&quot;$(DIA_SDK_ROOT)\include&quot;;&quot;$(DBG_SDK_ROOT)\inc&quot;;&quot;$(BOOST_ROOT)&quot;;&quot;$(PYTHON_ROOT)\x64\include&quot;"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;PYKD_EXPORTS"
RuntimeLibrary="2"
UsePrecompiledHeader="2"
@ -287,7 +287,7 @@
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/bigobj"
AdditionalIncludeDirectories="&quot;$(DIA_SDK_ROOT)\include&quot;;&quot;$(DBG_SDK_ROOT)\inc&quot;;&quot;$(BOOST_ROOT)&quot;;&quot;$(PYTHON_ROOT)\x64\include&quot;"
AdditionalIncludeDirectories="&quot;$(ProjectDir)&quot;;&quot;$(DIA_SDK_ROOT)\include&quot;;&quot;$(DBG_SDK_ROOT)\inc&quot;;&quot;$(BOOST_ROOT)&quot;;&quot;$(PYTHON_ROOT)\x64\include&quot;"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;PYKD_EXPORTS"
RuntimeLibrary="2"
UsePrecompiledHeader="2"
@ -357,6 +357,10 @@
RelativePath=".\dbgext.cpp"
>
</File>
<File
RelativePath=".\dbgmem.cpp"
>
</File>
<File
RelativePath=".\module.cpp"
>
@ -405,10 +409,6 @@
/>
</FileConfiguration>
</File>
<File
RelativePath=".\windbgeng.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
@ -423,6 +423,10 @@
RelativePath=".\dbgexcept.h"
>
</File>
<File
RelativePath=".\dbgmem.h"
>
</File>
<File
RelativePath=".\intbase.h"
>
@ -444,7 +448,11 @@
>
</File>
<File
RelativePath=".\windbgeng.h"
RelativePath=".\symengine.h"
>
</File>
<File
RelativePath=".\typeinfo.h"
>
</File>
</Filter>
@ -458,6 +466,38 @@
>
</File>
</Filter>
<Filter
Name="win"
>
<File
RelativePath=".\win\dbgeng.cpp"
>
</File>
<File
RelativePath=".\win\dbgeng.h"
>
</File>
<File
RelativePath=".\win\memory.cpp"
>
</File>
<File
RelativePath=".\win\utils.h"
>
</File>
</Filter>
<Filter
Name="dia"
>
<File
RelativePath=".\dia\diawrapper.cpp"
>
</File>
<File
RelativePath=".\dia\diawrapper.h"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>

View File

@ -5,27 +5,46 @@
#include "stdafx.h"
#include "pykdver.h"
#include "dbgengine.h"
#include "symengine.h"
#include "module.h"
#include "intbase.h"
#include "dbgexcept.h"
#include "dbgmem.h"
using namespace pykd;
////////////////////////////////////////////////////////////////////////////////
static const std::string pykdVersion = PYKD_VERSION_BUILD_STR
#ifdef _DEBUG
" <DBG>"
#endif // _DEBUG
;
using namespace pykd;
////////////////////////////////////////////////////////////////////////////////
BOOST_PYTHON_FUNCTION_OVERLOADS( loadChars_, loadChars, 2, 3 );
BOOST_PYTHON_FUNCTION_OVERLOADS( loadWChars_, loadWChars, 2, 3 );
BOOST_PYTHON_FUNCTION_OVERLOADS( loadBytes_, loadBytes, 2, 3 );
BOOST_PYTHON_FUNCTION_OVERLOADS( loadWords_, loadWords, 2, 3 );
BOOST_PYTHON_FUNCTION_OVERLOADS( loadDWords_, loadDWords, 2, 3 );
BOOST_PYTHON_FUNCTION_OVERLOADS( loadQWords_, loadQWords, 2, 3 );
BOOST_PYTHON_FUNCTION_OVERLOADS( loadSignBytes_, loadSignBytes, 2, 3 );
BOOST_PYTHON_FUNCTION_OVERLOADS( loadSignWords_, loadSignWords, 2, 3 );
BOOST_PYTHON_FUNCTION_OVERLOADS( loadSignDWords_, loadSignDWords, 2, 3 );
BOOST_PYTHON_FUNCTION_OVERLOADS( loadSignQWords_, loadSignQWords, 2, 3 );
//////////////////////////////////////////////////////////////////////////////////
BOOST_PYTHON_MODULE( pykd )
{
python::scope().attr("version") = pykdVersion;
// Manage debug target
python::def( "startProcess", &startProcess,
"Start process for debugging");
python::def( "detachProcess", &detachProcess,
@ -36,6 +55,41 @@ BOOST_PYTHON_MODULE( pykd )
python::def( "go", &debugGo,
"Go debugging" );
// Manage target memory access
python::def( "loadBytes", &loadBytes, loadBytes_( python::args( "offset", "count", "phyAddr" ),
"Read the block of the target's memory and return it as liat of unsigned bytes" ) );
python::def( "loadWords", &loadWords, loadWords_( python::args( "offset", "count", "phyAddr" ),
"Read the block of the target's memory and return it as list of unsigned shorts" ) );
python::def( "loadDWords", &loadDWords, loadDWords_( python::args( "offset", "count", "phyAddr" ),
"Read the block of the target's memory and return it as list of unsigned long ( double word )" ) );
python::def( "loadQWords", &loadQWords, loadQWords_( python::args( "offset", "count", "phyAddr" ),
"Read the block of the target's memory and return it as list of unsigned long long ( quad word )" ) );
python::def( "loadSignBytes", &loadSignBytes, loadSignBytes_( python::args( "offset", "count", "phyAddr" ),
"Read the block of the target's memory and return it as list of signed bytes" ) );
python::def( "loadSignWords", &loadSignWords, loadSignWords_( python::args( "offset", "count", "phyAddr" ),
"Read the block of the target's memory and return it as list of signed words" ) );
python::def( "loadSignDWords", &loadSignDWords, loadSignDWords_( python::args( "offset", "count", "phyAddr" ),
"Read the block of the target's memory and return it as list of signed longs" ) );
python::def( "loadSignQWords", &loadSignQWords, loadSignQWords_( python::args( "offset", "count", "phyAddr" ),
"Read the block of the target's memory and return it as list of signed long longs" ) );
//python::def( "loadChars", &loadChars, loadChars_( python::args( "address", "count", "phyAddr" ),
// "Load string from target memory" ) );
//python::def( "loadWChars", &loadWChars, loadWChars_( python::args( "address", "count", "phyAddr" ),
// "Load string from target memory" ) );
//python::def( "loadCStr", &loadCStr,
// "Load string from the target buffer containing 0-terminated ansi-string" );
//python::def( "loadWStr", &loadWStr,
// "Load string from the target buffer containing 0-terminated unicode-string" );
//python::def( "loadUnicodeString", &loadUnicodeStr,
// "Return string represention of windows UNICODE_STRING type" );
//python::def( "loadAnsiString", &loadAnsiStr,
// "Return string represention of windows ANSU_STRING type" );
//python::def( "loadPtrList", &loadPtrList,
// "Return list of pointers, each points to next" );
//python::def( "loadPtrs", &loadPtrArray,
// "Read the block of the target's memory and return it as a list of pointers" );
python::class_<intBase>( "intBase", "intBase", python::no_init )
.def( python::init<python::object&>() )
.def( "__eq__", &intBase::eq )
@ -92,7 +146,9 @@ BOOST_PYTHON_MODULE( pykd )
.def("name", &Module::getName,
"Return name of the module" )
.def("reload", &Module::reloadSymbols,
"(Re)load symbols for the module" );
"(Re)load symbols for the module" )
.def("__getattr__", &Module::getSymbol,
"Return address of the symbol" );
//.def("image", &Module::getImageName,
// "Return name of the image of the module" )
@ -139,9 +195,9 @@ BOOST_PYTHON_MODULE( pykd )
//.def( "__str__", &Module::print );
pykd::exception<DbgException>( "BaseException", "Pykd base exception class" );
//pykd::exception<MemoryException,DbgException>( "MemoryException", "Target memory access exception class" );
pykd::exception<MemoryException,DbgException>( "MemoryException", "Target memory access exception class" );
//pykd::exception<WaitEventException,DbgException>( "WaitEventException", "Debug interface access exception" );
//pykd::exception<SymbolException,DbgException>( "SymbolException", "Symbol exception" );
pykd::exception<SymbolException,DbgException>( "SymbolException", "Symbol exception" );
//pykd::exception<pyDia::Exception,SymbolException>( "DiaException", "Debug interface access exception" );
//pykd::exception<TypeException,SymbolException>( "TypeException", "type exception" );
//pykd::exception<AddSyntheticSymbolException,DbgException>( "AddSynSymbolException", "synthetic symbol exception" );

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
#include "stdafx.h"
#include "windbgeng.h"
#include "win/dbgeng.h"
#include "dbgexcept.h"
namespace pykd {
@ -174,32 +174,55 @@ std::string getModuleName( ULONG64 baseOffset )
///////////////////////////////////////////////////////////////////////////////////
ULONG64 addr64( ULONG64 addr )
std::string getModuleSymbolFileName( ULONG64 baseOffset )
{
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
HRESULT hres;
HRESULT hres;
IMAGEHLP_MODULEW64 moduleInfo = {};
hres = g_dbgEng->advanced->GetSymbolInformation(
DEBUG_SYMINFO_IMAGEHLP_MODULEW64,
baseOffset,
0,
&moduleInfo,
sizeof(moduleInfo),
NULL,
NULL,
0,
NULL );
ULONG processorMode;
hres = g_dbgEng->control->GetActualProcessorType( &processorMode );
if ( FAILED( hres ) )
throw DbgException( "IDebugControl::GetEffectiveProcessorType failed" );
throw DbgException( "IDebugAdvanced2::GetSymbolInformation failed" );
switch( processorMode )
if (!*moduleInfo.LoadedPdbName)
{
case IMAGE_FILE_MACHINE_I386:
if ( *( (ULONG*)&addr + 1 ) == 0 )
return (ULONG64)(LONG)addr;
std::wstring param = L"/f ";
param += moduleInfo.ImageName;
case IMAGE_FILE_MACHINE_AMD64:
break;
hres = g_dbgEng->symbols->ReloadWide( param.c_str() );
if ( FAILED( hres ) )
throw DbgException("IDebugSymbols::Reload failed" );
default:
throw DbgException( "Unknown processor type" );
break;
hres = g_dbgEng->advanced->GetSymbolInformation(
DEBUG_SYMINFO_IMAGEHLP_MODULEW64,
baseOffset,
0,
&moduleInfo,
sizeof(moduleInfo),
NULL,
NULL,
0,
NULL );
if ( FAILED( hres ) )
throw DbgException( "IDebugAdvanced2::GetSymbolInformation failed" );
}
return addr;
char pdbName[ 256 ];
WideCharToMultiByte( CP_ACP, 0, moduleInfo.LoadedPdbName, 256, pdbName, 256, NULL, NULL );
return std::string( pdbName );
}
///////////////////////////////////////////////////////////////////////////////////

View File

@ -4,6 +4,9 @@
#include "dbgexcept.h"
#include "pyaux.h"
#include <dbgeng.h>
#include <dbghelp.h>
namespace pykd {
///////////////////////////////////////////////////////////////////////////////////
@ -18,6 +21,8 @@ public:
CComQIPtr<IDebugControl4> control;
CComQIPtr<IDebugSystemObjects2> system;
CComQIPtr<IDebugSymbols3> symbols;
CComQIPtr<IDebugDataSpaces4> dataspace;
CComQIPtr<IDebugAdvanced2> advanced;
DbgEngBind( PDEBUG_CLIENT4 c )
{
@ -25,6 +30,8 @@ public:
control = c;
system = c;
symbols = c;
dataspace = c;
advanced = c;
}
PyThreadStateSaver pystate;

74
pykd/win/memory.cpp Normal file
View File

@ -0,0 +1,74 @@
#include "stdafx.h"
#include "win/dbgeng.h"
namespace pykd {
///////////////////////////////////////////////////////////////////////////////////
ULONG64 addr64NoSafe( ULONG64 addr )
{
HRESULT hres;
ULONG processorMode;
hres = g_dbgEng->control->GetActualProcessorType( &processorMode );
if ( FAILED( hres ) )
throw DbgException( "IDebugControl::GetEffectiveProcessorType failed" );
switch( processorMode )
{
case IMAGE_FILE_MACHINE_I386:
if ( *( (ULONG*)&addr + 1 ) == 0 )
return (ULONG64)(LONG)addr;
case IMAGE_FILE_MACHINE_AMD64:
break;
default:
throw DbgException( "Unknown processor type" );
break;
}
return addr;
}
ULONG64 addr64( ULONG64 addr )
{
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
return addr64NoSafe( addr );
}
///////////////////////////////////////////////////////////////////////////////////
void readMemory( ULONG64 offset, PVOID buffer, ULONG length, bool phyAddr )
{
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
HRESULT hres;
if ( phyAddr == false )
{
offset = addr64NoSafe( offset );
// workitem/10473 workaround
ULONG64 nextAddress;
hres =
g_dbgEng->dataspace->GetNextDifferentlyValidOffsetVirtual( offset, &nextAddress );
DBG_UNREFERENCED_LOCAL_VARIABLE(nextAddress);
hres = g_dbgEng->dataspace->ReadVirtual( offset, buffer, length, NULL );
}
else
{
hres = g_dbgEng->dataspace->ReadPhysical( offset, buffer, length, NULL );
}
if ( FAILED( hres ) )
throw MemoryException( offset, phyAddr );
}
///////////////////////////////////////////////////////////////////////////////////
}; //namespace pykd

View File

@ -12,16 +12,20 @@ sys.path.insert(0, os.path.dirname(sys.argv[1]))
import pykd
import target
import moduletest
import intbase
import memtest
import moduletest
def getTestSuite( singleName = "" ):
if singleName == "":
return unittest.TestSuite(
[
unittest.TestLoader().loadTestsFromTestCase( target.TargetTest ),
unittest.TestLoader().loadTestsFromTestCase( moduletest.ModuleTest ),
unittest.TestLoader().loadTestsFromTestCase( intbase.IntBaseTest ),
unittest.TestLoader().loadTestsFromTestCase( moduletest.ModuleTest ),
unittest.TestLoader().loadTestsFromTestCase( memtest.MemoryTest )
] )
else:
return unittest.TestSuite( unittest.TestLoader().loadTestsFromName( singleName ) )