From 9cbbbb7ea63bf5beb7e41bd7c94f1257bb4af451 Mon Sep 17 00:00:00 2001 From: "SND\\kernelnet_cp" Date: Tue, 31 Jul 2012 13:40:05 +0000 Subject: [PATCH] [0.2.x] added facade for retrieving symbol information git-svn-id: https://pykd.svn.codeplex.com/svn@78409 9b283d60-5439-405e-af05-b73fd8c4d996 --- pykd/dbgengine.h | 3 + pykd/dbgexcept.cpp | 4 +- pykd/dbgexcept.h | 7 +- pykd/dbgmem.cpp | 1433 +++++++++++++----------- pykd/dbgmem.h | 226 ++-- pykd/dia/diawrapper.cpp | 714 ++++++++++++ pykd/dia/diawrapper.h | 635 +++++++++++ pykd/diawrapper.cpp | 555 --------- pykd/diawrapper.h | 373 ------ pykd/module.cpp | 44 + pykd/module.h | 17 + pykd/pykd_2008.vcproj | 58 +- pykd/pymod.cpp | 66 +- pykd/typeinfo.h | 1010 +++++++++-------- pykd/{windbgeng.cpp => win/dbgeng.cpp} | 55 +- pykd/{windbgeng.h => win/dbgeng.h} | 7 + pykd/win/memory.cpp | 74 ++ pykd/{ => win}/utils.h | 0 test/scripts/pykdtest.py | 8 +- 19 files changed, 3078 insertions(+), 2211 deletions(-) create mode 100644 pykd/dia/diawrapper.cpp create mode 100644 pykd/dia/diawrapper.h delete mode 100644 pykd/diawrapper.cpp delete mode 100644 pykd/diawrapper.h rename pykd/{windbgeng.cpp => win/dbgeng.cpp} (78%) rename pykd/{windbgeng.h => win/dbgeng.h} (83%) create mode 100644 pykd/win/memory.cpp rename pykd/{ => win}/utils.h (100%) diff --git a/pykd/dbgengine.h b/pykd/dbgengine.h index 1c4497b..e7128bb 100644 --- a/pykd/dbgengine.h +++ b/pykd/dbgengine.h @@ -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 ); + }; diff --git a/pykd/dbgexcept.cpp b/pykd/dbgexcept.cpp index 4ed7e1f..a022644 100644 --- a/pykd/dbgexcept.cpp +++ b/pykd/dbgexcept.cpp @@ -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::pyExceptType; python::handle<> exceptPyType::pyExceptType; python::handle<> exceptPyType::pyExceptType; python::handle<> exceptPyType::pyExceptType; -python::handle<> exceptPyType::pyExceptType; +//python::handle<> exceptPyType::pyExceptType; python::handle<> exceptPyType::pyExceptType; python::handle<> exceptPyType::pyExceptType; python::handle<> exceptPyType::pyExceptType; diff --git a/pykd/dbgexcept.h b/pykd/dbgexcept.h index 91b0b28..62ebb2f 100644 --- a/pykd/dbgexcept.h +++ b/pykd/dbgexcept.h @@ -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 ) diff --git a/pykd/dbgmem.cpp b/pykd/dbgmem.cpp index c2d7dee..ee9a687 100644 --- a/pykd/dbgmem.cpp +++ b/pykd/dbgmem.cpp @@ -1,7 +1,5 @@ #include "stdafx.h" - -#include "dbgclient.h" -#include "dbgexcept.h" +#include "dbgengine.h" namespace pykd { @@ -21,12 +19,12 @@ struct PyListType template python::list -DebugClient::loadArray( ULONG64 offset, ULONG count, bool phyAddr ) +loadArray( ULONG64 offset, ULONG count, bool phyAddr ) { std::vector buffer(count); if (count) - readMemory( m_dataSpaces, offset, &buffer[0], count*sizeof(T), phyAddr ); + readMemory( offset, &buffer[0], count*sizeof(T), phyAddr ); python::list lst; @@ -38,708 +36,821 @@ DebugClient::loadArray( ULONG64 offset, ULONG count, bool phyAddr ) ///////////////////////////////////////////////////////////////////////////////////// -ULONG64 -addr64( IDebugControl4* dbgControl, ULONG64 addr) -{ - HRESULT hres; - - ULONG processorMode; - hres = dbgControl->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 -DebugClient::addr64( ULONG64 addr ) -{ - return pykd::addr64( m_control, addr ); -} - -ULONG64 -addr64( ULONG64 addr) -{ - return g_dbgClient->addr64( addr ); -} - -///////////////////////////////////////////////////////////////////////////////////// - -bool DebugClient::isVaValid( ULONG64 addr ) -{ - HRESULT hres; - ULONG offsetInfo; - - hres = - m_dataSpaces->GetOffsetInformation( - DEBUG_DATA_SPACE_VIRTUAL, - DEBUG_OFFSINFO_VIRTUAL_SOURCE, - addr, - &offsetInfo, - sizeof( offsetInfo ), - NULL ); - - if ( FAILED( hres ) ) - throw DbgException( "IDebugDataSpace4::GetOffsetInformation failed" ); - - return offsetInfo != DEBUG_VSOURCE_INVALID; -} - -bool isVaValid( ULONG64 addr ) -{ - return g_dbgClient->isVaValid( addr ); -} - -///////////////////////////////////////////////////////////////////////////////////// - -HRESULT readVirtual( - IDebugDataSpaces4 *dbgDataSpace, - ULONG64 address, - PVOID buffer, - ULONG length, - PULONG readed -) -{ - HRESULT hres; - - CComQIPtr dbgControl(dbgDataSpace); - - address = addr64( dbgControl, address); - - { - // workitem/10473 workaround - ULONG64 nextAddress; - hres = - dbgDataSpace->GetNextDifferentlyValidOffsetVirtual( - address, - &nextAddress); - DBG_UNREFERENCED_LOCAL_VARIABLE(nextAddress); - } - - hres = dbgDataSpace->ReadVirtual( address, buffer, length, readed ); - - return hres; -} - -///////////////////////////////////////////////////////////////////////////////////// - -void -readMemory( IDebugDataSpaces4* dbgDataSpace, ULONG64 address, PVOID buffer, ULONG length, bool phyAddr = FALSE ) -{ - HRESULT hres; - - if ( phyAddr == false ) - { - hres = readVirtual( dbgDataSpace, address, buffer, length, NULL ); - } - else - { - hres = dbgDataSpace->ReadPhysical( address, buffer, length, NULL ); - } - - if ( FAILED( hres ) ) - throw MemoryException( address, phyAddr ); -} - -///////////////////////////////////////////////////////////////////////////////////// - -void -readMemoryPtr( IDebugDataSpaces4* dbgDataSpace, ULONG64 address, PULONG64 ptrValue ) -{ - HRESULT hres; - - CComQIPtr dbgControl(dbgDataSpace); - - hres = dbgDataSpace->ReadPointersVirtual( 1, addr64( dbgControl, address), ptrValue ); - - if ( FAILED( hres ) ) - throw MemoryException( address, false ); -} - -///////////////////////////////////////////////////////////////////////////////////// - -bool compareMemoryRange( IDebugDataSpaces4* dbgDataSpace, ULONG64 addr1, ULONG64 addr2, ULONG length, bool phyAddr ) -{ - bool result = false; - - CComQIPtr dbgControl(dbgDataSpace); - - addr1 = addr64( addr1 ); - addr2 = addr64( addr2 ); - - std::vector m1(length); - std::vector m2(length); - - readMemory( dbgDataSpace, addr64( dbgControl, addr1), &m1[0], length, phyAddr ); - readMemory( dbgDataSpace, addr64( dbgControl, addr2), &m2[0], length, phyAddr ); - - return std::equal( m1.begin(), m1.end(), m2.begin() ); -} - -///////////////////////////////////////////////////////////////////////////////////// - -std::string DebugClient::loadChars( ULONG64 address, ULONG number, bool phyAddr ) -{ - std::vector buffer(number); - - ULONG bufferSize = (ULONG)( sizeof(std::vector::value_type)*buffer.size() ); - - if (number) - readMemory( m_dataSpaces, address, &buffer[0], bufferSize, phyAddr ); - - return std::string( buffer.begin(), buffer.end() ); -} - -std::string loadChars( ULONG64 address, ULONG number, bool phyAddr ) -{ - return g_dbgClient->loadChars( address, number, phyAddr ); -} - -///////////////////////////////////////////////////////////////////////////////////// - -std::wstring DebugClient::loadWChars( ULONG64 address, ULONG number, bool phyAddr ) -{ - std::vector buffer(number); - - ULONG bufferSize = (ULONG)( sizeof(std::vector::value_type)*buffer.size() ); - - if (number) - readMemory( m_dataSpaces, address, &buffer[0], bufferSize, phyAddr ); - - return std::wstring( buffer.begin(), buffer.end() ); -} - -std::wstring loadWChars( ULONG64 address, ULONG number, bool phyAddr ) -{ - return g_dbgClient->loadWChars( address, number, phyAddr ); -} - -///////////////////////////////////////////////////////////////////////////////////// - -std::string DebugClient::loadCStr( ULONG64 address ) -{ - const size_t maxLength = 0x10000; - - address = addr64( address ); - - ULONG strLength = 0; - - HRESULT hres = - m_dataSpaces->ReadMultiByteStringVirtual( - address, - maxLength, - NULL, - 0, - &strLength ); - - if ( FAILED( hres ) ) - throw MemoryException( address ); - - std::vector buffer(strLength); - - hres = - m_dataSpaces->ReadMultiByteStringVirtual( - address, - strLength, - &buffer[0], - strLength, - NULL ); - - if ( FAILED( hres ) ) - throw MemoryException( address ); - - return std::string( &buffer[0] ); -} - -std::string loadCStr( ULONG64 offset ) -{ - return g_dbgClient->loadCStr( offset ); -} - -///////////////////////////////////////////////////////////////////////////////////// - -std::wstring DebugClient::loadWStr( ULONG64 address ) -{ - const size_t maxLength = 0x10000; - - address = addr64( address ); - - ULONG strLength = 0; - - HRESULT hres = - m_dataSpaces->ReadUnicodeStringVirtualWide( - address, - maxLength, - NULL, - 0, - &strLength ); - - std::vector buffer(strLength); - - hres = - m_dataSpaces->ReadUnicodeStringVirtualWide( - address, - strLength, - &buffer[0], - strLength, - NULL ); - - if ( FAILED( hres ) ) - throw MemoryException( address ); - - return std::wstring( &buffer[0] ); -} - -std::wstring loadWStr( ULONG64 offset ) -{ - return g_dbgClient->loadWStr( offset ); -} - -///////////////////////////////////////////////////////////////////////////////////// - -python::list DebugClient::loadBytes( ULONG64 offset, ULONG count, bool phyAddr ) +python::list loadBytes( ULONG64 offset, ULONG count, bool phyAddr ) { return loadArray( offset, count, phyAddr ); } -python::list loadBytes( ULONG64 offset, ULONG count, bool phyAddr ) -{ - return g_dbgClient->loadBytes( offset, count, phyAddr ); -} - ///////////////////////////////////////////////////////////////////////////////////// -python::list DebugClient::loadWords( ULONG64 offset, ULONG count, bool phyAddr ) +python::list loadWords( ULONG64 offset, ULONG count, bool phyAddr ) { return loadArray( offset, count, phyAddr ); } -python::list loadWords( ULONG64 offset, ULONG count, bool phyAddr ) -{ - return g_dbgClient->loadWords( offset, count, phyAddr ); -} - ///////////////////////////////////////////////////////////////////////////////////// -python::list DebugClient::loadDWords( ULONG64 offset, ULONG count, bool phyAddr ) +python::list loadDWords( ULONG64 offset, ULONG count, bool phyAddr ) { return loadArray( offset, count, phyAddr ); } -python::list loadDWords( ULONG64 offset, ULONG count, bool phyAddr ) -{ - return g_dbgClient->loadDWords( offset, count, phyAddr ); -} - ///////////////////////////////////////////////////////////////////////////////////// -python::list DebugClient::loadQWords( ULONG64 offset, ULONG count, bool phyAddr ) +python::list loadQWords( ULONG64 offset, ULONG count, bool phyAddr ) { return loadArray( offset, count, phyAddr ); } -python::list loadQWords( ULONG64 offset, ULONG count, bool phyAddr ) -{ - return g_dbgClient->loadQWords( offset, count, phyAddr ); -} - ///////////////////////////////////////////////////////////////////////////////////// -python::list DebugClient::loadSignBytes( ULONG64 offset, ULONG count, bool phyAddr ) +python::list loadSignBytes( ULONG64 offset, ULONG count, bool phyAddr ) { return loadArray( offset, count, phyAddr ); } -python::list loadSignBytes( ULONG64 offset, ULONG count, bool phyAddr ) -{ - return g_dbgClient->loadSignBytes( offset, count, phyAddr ); -} - ///////////////////////////////////////////////////////////////////////////////////// -python::list DebugClient::loadSignWords( ULONG64 offset, ULONG count, bool phyAddr ) +python::list loadSignWords( ULONG64 offset, ULONG count, bool phyAddr ) { return loadArray( offset, count, phyAddr ); } -python::list loadSignWords( ULONG64 offset, ULONG count, bool phyAddr ) -{ - return g_dbgClient->loadSignWords( offset, count, phyAddr ); -} - ///////////////////////////////////////////////////////////////////////////////////// -python::list DebugClient::loadSignDWords( ULONG64 offset, ULONG count, bool phyAddr ) +python::list loadSignDWords( ULONG64 offset, ULONG count, bool phyAddr ) { return loadArray( offset, count, phyAddr ); } -python::list loadSignDWords( ULONG64 offset, ULONG count, bool phyAddr ) -{ - return g_dbgClient->loadSignDWords( offset, count, phyAddr ); -} - ///////////////////////////////////////////////////////////////////////////////////// -python::list DebugClient::loadSignQWords( ULONG64 offset, ULONG count, bool phyAddr ) +python::list loadSignQWords( ULONG64 offset, ULONG count, bool phyAddr ) { return loadArray<__int64>( offset, count, phyAddr ); } -python::list loadSignQWords( ULONG64 offset, ULONG count, bool phyAddr ) -{ - return g_dbgClient->loadSignQWords( offset, count, phyAddr ); -} - ///////////////////////////////////////////////////////////////////////////////////// -ULONG64 DebugClient::ptrByte( ULONG64 offset ) -{ - unsigned char val = 0; - - readMemory( m_dataSpaces, offset, &val, sizeof(val), false ); - - return val; -} - -ULONG64 ptrByte( ULONG64 offset ) -{ - return g_dbgClient->ptrByte( offset ); -} - -///////////////////////////////////////////////////////////////////////////////////// - -ULONG64 DebugClient::ptrWord( ULONG64 offset ) -{ - unsigned short val = 0; - - readMemory( m_dataSpaces, offset, &val, sizeof(val), false ); - - return val; -} - -ULONG64 ptrWord( ULONG64 offset ) -{ - return g_dbgClient->ptrWord( offset ); -} - -///////////////////////////////////////////////////////////////////////////////////// - -ULONG64 ptrDWord( ULONG64 offset, IDebugDataSpaces4* dbgDataSpace ) -{ - unsigned long val = 0; - - readMemory( dbgDataSpace, offset, &val, sizeof(val), false ); - - return val; -} - -ULONG64 DebugClient::ptrDWord( ULONG64 offset ) -{ - return pykd::ptrDWord( offset, m_dataSpaces ); -} - -ULONG64 ptrDWord( ULONG64 offset ) -{ - return g_dbgClient->ptrDWord( offset ); -} - -///////////////////////////////////////////////////////////////////////////////////// - -ULONG64 ptrQWord( ULONG64 offset, IDebugDataSpaces4* dbgDataSpace ) -{ - unsigned __int64 val = 0; - - readMemory( dbgDataSpace, offset, &val, sizeof(val), false ); - - return val; -} - -ULONG64 DebugClient::ptrQWord( ULONG64 offset ) -{ - return pykd::ptrQWord( offset, m_dataSpaces ); -} - -ULONG64 ptrQWord( ULONG64 offset ) -{ - return g_dbgClient->ptrQWord( offset ); -} - -///////////////////////////////////////////////////////////////////////////////////// - -ULONG64 ptrMWord( ULONG64 offset, IDebugDataSpaces4* dbgDataSpace ) -{ - return ptrSize() == 8 ? ptrQWord( offset, dbgDataSpace ) : ptrDWord(offset, dbgDataSpace); -} - -ULONG64 DebugClient::ptrMWord( ULONG64 offset ) -{ - return ptrSize() == 8 ? ptrQWord( offset ) : ptrDWord(offset); -} - -ULONG64 ptrMWord( ULONG64 offset ) -{ - return g_dbgClient->ptrMWord( offset ); -} - -///////////////////////////////////////////////////////////////////////////////////// - -ULONG64 ptrPtr( ULONG64 offset, IDebugDataSpaces4* dbgDataSpace ) -{ - return ptrMWord( offset, dbgDataSpace ); -} - -ULONG64 DebugClient::ptrPtr( ULONG64 offset ) -{ - return addr64( pykd::ptrPtr( offset, m_dataSpaces ) ); -} - -ULONG64 ptrPtr( ULONG64 offset ) -{ - return g_dbgClient->ptrPtr( offset ); -} - -///////////////////////////////////////////////////////////////////////////////////// - -LONG64 DebugClient::ptrSignByte( ULONG64 offset ) -{ - char val = 0; - - readMemory( m_dataSpaces, offset, &val, sizeof(val), false ); - - return val; -} - -LONG64 ptrSignByte( ULONG64 offset ) -{ - return g_dbgClient->ptrSignByte( offset ); -} - -///////////////////////////////////////////////////////////////////////////////////// - -LONG64 DebugClient::ptrSignWord( ULONG64 offset ) -{ - short val = 0; - - readMemory( m_dataSpaces, offset, &val, sizeof(val), false ); - - return val; -} - -LONG64 ptrSignWord( ULONG64 offset ) -{ - return g_dbgClient->ptrSignWord( offset ); -} - -///////////////////////////////////////////////////////////////////////////////////// - -LONG64 DebugClient::ptrSignDWord( ULONG64 offset ) -{ - long val = 0; - - readMemory( m_dataSpaces, offset, &val, sizeof(val), false ); - - return val; -} - -LONG64 ptrSignDWord( ULONG64 offset ) -{ - return g_dbgClient->ptrSignDWord( offset ); -} - -///////////////////////////////////////////////////////////////////////////////////// - -LONG64 DebugClient::ptrSignQWord( ULONG64 offset ) -{ - __int64 val = 0; - - readMemory( m_dataSpaces, offset, &val, sizeof(val), false ); - - return val; -} - -LONG64 ptrSignQWord( ULONG64 offset ) -{ - return g_dbgClient->ptrSignQWord( offset ); -} - -///////////////////////////////////////////////////////////////////////////////////// - -LONG64 DebugClient::ptrSignMWord( ULONG64 offset ) -{ - return ptrSize() == 8 ? ptrSignQWord( offset ) : ptrSignDWord(offset); -} - -LONG64 ptrSignMWord( ULONG64 offset ) -{ - return g_dbgClient->ptrSignMWord( offset ); -} - -///////////////////////////////////////////////////////////////////////////////////// - -bool DebugClient::compareMemory( ULONG64 addr1, ULONG64 addr2, ULONG length, bool phyAddr ) -{ - return compareMemoryRange( m_dataSpaces, addr1, addr2, length, phyAddr ); -} - -bool compareMemory( ULONG64 addr1, ULONG64 addr2, ULONG length, bool phyAddr ) -{ - return g_dbgClient->compareMemory( addr1, addr2, length, phyAddr ); -} - -///////////////////////////////////////////////////////////////////////////////////// - -std::wstring DebugClient::loadUnicodeStr( ULONG64 address ) -{ - USHORT length; - USHORT maximumLength; - ULONG64 buffer = 0; - - readMemory( m_dataSpaces, address, &length, sizeof( length ) ); - - if ( length == 0 ) - return L""; - - address += sizeof( length ); - - readMemory( m_dataSpaces, address, &maximumLength, sizeof( maximumLength ) ); - - address += sizeof( maximumLength ); - - if ( is64bitSystem() ) - { - address += address % 8 ? ( 8 - address % 8 ) : 0 ; // выравнивание на 8 байт - - buffer = ptrPtr( address ); - - address += 8; - } - else - { - address += address % 4 ? ( 4 - address % 4 ) : 0 ; // выравнивание на 8 байт - - buffer = addr64( ptrPtr( address ) ); - - address += 4; - } - - std::vector str(length / 2); - - readMemory( m_dataSpaces, buffer, &str[0], length ); - - return std::wstring (&str[0], length/2); -} - -std::wstring loadUnicodeStr( ULONG64 address ) -{ - return g_dbgClient->loadUnicodeStr( address ); -} - -///////////////////////////////////////////////////////////////////////////////////// - -std::string DebugClient::loadAnsiStr( ULONG64 address ) -{ - USHORT length; - USHORT maximumLength; - ULONG64 buffer = 0; - - readMemory( m_dataSpaces, address, &length, sizeof( length ) ); - - if ( length == 0 ) - return ""; - - address += sizeof( length ); - - readMemory( m_dataSpaces, address, &maximumLength, sizeof( maximumLength ) ); - - address += sizeof( maximumLength ); - - if ( is64bitSystem() ) - { - address += address % 8 ? ( 8 - address % 8 ) : 0 ; // выравнивание на 8 байт - - buffer = ptrPtr( address ); - - address += 8; - } - else - { - address += address % 4 ? ( 4 - address % 4 ) : 0 ; // выравнивание на 8 байт - - buffer = addr64( ptrPtr( address ) ); - - address += 4; - } - - std::vector str(length); - - readMemory( m_dataSpaces, buffer, &str[0], length ); - - return std::string (&str[0], length); -} - - -std::string loadAnsiStr( ULONG64 address ) -{ - return g_dbgClient->loadAnsiStr( address ); -} - -///////////////////////////////////////////////////////////////////////////////////// - -python::list DebugClient::loadPtrList( ULONG64 address ) -{ - address = addr64( address ); - - ULONG64 entryAddress = 0; - - python::list lst; - - for( entryAddress = ptrPtr( address ); entryAddress != address && entryAddress != 0; entryAddress = ptrPtr( entryAddress ) ) - lst.append( entryAddress ); - - return lst; -} - -python::list loadPtrList( ULONG64 address ) -{ - return g_dbgClient->loadPtrList( address ); -} - -///////////////////////////////////////////////////////////////////////////////////// - -python::list DebugClient::loadPtrArray( ULONG64 address, ULONG number ) -{ - address = addr64( address ); - - python::list lst; - - for ( ULONG i = 0; i < number; ++i ) - lst.append( ptrPtr( address + i*ptrSize() ) ); - - return lst; -} - -python::list loadPtrArray( ULONG64 address, ULONG number ) -{ - return g_dbgClient->loadPtrArray( address, number ); -} - -///////////////////////////////////////////////////////////////////////////////////// - -}; // end of pykd +}; // end pykd namespace + + + + + + + + + + + + + + + + + + +//#include "dbgclient.h" +//#include "dbgexcept.h" +// +//namespace pykd { +// +/////////////////////////////////////////////////////////////////////////////////////// +// +//template +//struct PyListType +//{ +// typedef T ElementType; +//}; +// +//template<> +//struct PyListType +//{ +// typedef int ElementType; +//}; +// +//template +//python::list +//DebugClient::loadArray( ULONG64 offset, ULONG count, bool phyAddr ) +//{ +// std::vector buffer(count); +// +// if (count) +// readMemory( m_dataSpaces, offset, &buffer[0], count*sizeof(T), phyAddr ); +// +// python::list lst; +// +// for( ULONG i = 0; i < count; ++i ) +// lst.append( static_cast::ElementType> (buffer[i]) ); +// +// return lst; +//} +// +/////////////////////////////////////////////////////////////////////////////////////// +// +//ULONG64 +//addr64( IDebugControl4* dbgControl, ULONG64 addr) +//{ +// HRESULT hres; +// +// ULONG processorMode; +// hres = dbgControl->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 +//DebugClient::addr64( ULONG64 addr ) +//{ +// return pykd::addr64( m_control, addr ); +//} +// +//ULONG64 +//addr64( ULONG64 addr) +//{ +// return g_dbgClient->addr64( addr ); +//} +// +/////////////////////////////////////////////////////////////////////////////////////// +// +//bool DebugClient::isVaValid( ULONG64 addr ) +//{ +// HRESULT hres; +// ULONG offsetInfo; +// +// hres = +// m_dataSpaces->GetOffsetInformation( +// DEBUG_DATA_SPACE_VIRTUAL, +// DEBUG_OFFSINFO_VIRTUAL_SOURCE, +// addr, +// &offsetInfo, +// sizeof( offsetInfo ), +// NULL ); +// +// if ( FAILED( hres ) ) +// throw DbgException( "IDebugDataSpace4::GetOffsetInformation failed" ); +// +// return offsetInfo != DEBUG_VSOURCE_INVALID; +//} +// +//bool isVaValid( ULONG64 addr ) +//{ +// return g_dbgClient->isVaValid( addr ); +//} +// +/////////////////////////////////////////////////////////////////////////////////////// +// +//HRESULT readVirtual( +// IDebugDataSpaces4 *dbgDataSpace, +// ULONG64 address, +// PVOID buffer, +// ULONG length, +// PULONG readed +//) +//{ +// HRESULT hres; +// +// CComQIPtr dbgControl(dbgDataSpace); +// +// address = addr64( dbgControl, address); +// +// { +// // workitem/10473 workaround +// ULONG64 nextAddress; +// hres = +// dbgDataSpace->GetNextDifferentlyValidOffsetVirtual( +// address, +// &nextAddress); +// DBG_UNREFERENCED_LOCAL_VARIABLE(nextAddress); +// } +// +// hres = dbgDataSpace->ReadVirtual( address, buffer, length, readed ); +// +// return hres; +//} +// +/////////////////////////////////////////////////////////////////////////////////////// +// +//void +//readMemory( IDebugDataSpaces4* dbgDataSpace, ULONG64 address, PVOID buffer, ULONG length, bool phyAddr = FALSE ) +//{ +// HRESULT hres; +// +// if ( phyAddr == false ) +// { +// hres = readVirtual( dbgDataSpace, address, buffer, length, NULL ); +// } +// else +// { +// hres = dbgDataSpace->ReadPhysical( address, buffer, length, NULL ); +// } +// +// if ( FAILED( hres ) ) +// throw MemoryException( address, phyAddr ); +//} +// +/////////////////////////////////////////////////////////////////////////////////////// +// +//void +//readMemoryPtr( IDebugDataSpaces4* dbgDataSpace, ULONG64 address, PULONG64 ptrValue ) +//{ +// HRESULT hres; +// +// CComQIPtr dbgControl(dbgDataSpace); +// +// hres = dbgDataSpace->ReadPointersVirtual( 1, addr64( dbgControl, address), ptrValue ); +// +// if ( FAILED( hres ) ) +// throw MemoryException( address, false ); +//} +// +/////////////////////////////////////////////////////////////////////////////////////// +// +//bool compareMemoryRange( IDebugDataSpaces4* dbgDataSpace, ULONG64 addr1, ULONG64 addr2, ULONG length, bool phyAddr ) +//{ +// bool result = false; +// +// CComQIPtr dbgControl(dbgDataSpace); +// +// addr1 = addr64( addr1 ); +// addr2 = addr64( addr2 ); +// +// std::vector m1(length); +// std::vector m2(length); +// +// readMemory( dbgDataSpace, addr64( dbgControl, addr1), &m1[0], length, phyAddr ); +// readMemory( dbgDataSpace, addr64( dbgControl, addr2), &m2[0], length, phyAddr ); +// +// return std::equal( m1.begin(), m1.end(), m2.begin() ); +//} +// +/////////////////////////////////////////////////////////////////////////////////////// +// +//std::string DebugClient::loadChars( ULONG64 address, ULONG number, bool phyAddr ) +//{ +// std::vector buffer(number); +// +// ULONG bufferSize = (ULONG)( sizeof(std::vector::value_type)*buffer.size() ); +// +// if (number) +// readMemory( m_dataSpaces, address, &buffer[0], bufferSize, phyAddr ); +// +// return std::string( buffer.begin(), buffer.end() ); +//} +// +//std::string loadChars( ULONG64 address, ULONG number, bool phyAddr ) +//{ +// return g_dbgClient->loadChars( address, number, phyAddr ); +//} +// +/////////////////////////////////////////////////////////////////////////////////////// +// +//std::wstring DebugClient::loadWChars( ULONG64 address, ULONG number, bool phyAddr ) +//{ +// std::vector buffer(number); +// +// ULONG bufferSize = (ULONG)( sizeof(std::vector::value_type)*buffer.size() ); +// +// if (number) +// readMemory( m_dataSpaces, address, &buffer[0], bufferSize, phyAddr ); +// +// return std::wstring( buffer.begin(), buffer.end() ); +//} +// +//std::wstring loadWChars( ULONG64 address, ULONG number, bool phyAddr ) +//{ +// return g_dbgClient->loadWChars( address, number, phyAddr ); +//} +// +/////////////////////////////////////////////////////////////////////////////////////// +// +//std::string DebugClient::loadCStr( ULONG64 address ) +//{ +// const size_t maxLength = 0x10000; +// +// address = addr64( address ); +// +// ULONG strLength = 0; +// +// HRESULT hres = +// m_dataSpaces->ReadMultiByteStringVirtual( +// address, +// maxLength, +// NULL, +// 0, +// &strLength ); +// +// if ( FAILED( hres ) ) +// throw MemoryException( address ); +// +// std::vector buffer(strLength); +// +// hres = +// m_dataSpaces->ReadMultiByteStringVirtual( +// address, +// strLength, +// &buffer[0], +// strLength, +// NULL ); +// +// if ( FAILED( hres ) ) +// throw MemoryException( address ); +// +// return std::string( &buffer[0] ); +//} +// +//std::string loadCStr( ULONG64 offset ) +//{ +// return g_dbgClient->loadCStr( offset ); +//} +// +/////////////////////////////////////////////////////////////////////////////////////// +// +//std::wstring DebugClient::loadWStr( ULONG64 address ) +//{ +// const size_t maxLength = 0x10000; +// +// address = addr64( address ); +// +// ULONG strLength = 0; +// +// HRESULT hres = +// m_dataSpaces->ReadUnicodeStringVirtualWide( +// address, +// maxLength, +// NULL, +// 0, +// &strLength ); +// +// std::vector buffer(strLength); +// +// hres = +// m_dataSpaces->ReadUnicodeStringVirtualWide( +// address, +// strLength, +// &buffer[0], +// strLength, +// NULL ); +// +// if ( FAILED( hres ) ) +// throw MemoryException( address ); +// +// return std::wstring( &buffer[0] ); +//} +// +//std::wstring loadWStr( ULONG64 offset ) +//{ +// return g_dbgClient->loadWStr( offset ); +//} +// +/////////////////////////////////////////////////////////////////////////////////////// +// +//python::list DebugClient::loadBytes( ULONG64 offset, ULONG count, bool phyAddr ) +//{ +// return loadArray( offset, count, phyAddr ); +//} +// +//python::list loadBytes( ULONG64 offset, ULONG count, bool phyAddr ) +//{ +// return g_dbgClient->loadBytes( offset, count, phyAddr ); +//} +// +/////////////////////////////////////////////////////////////////////////////////////// +// +//python::list DebugClient::loadWords( ULONG64 offset, ULONG count, bool phyAddr ) +//{ +// return loadArray( offset, count, phyAddr ); +//} +// +//python::list loadWords( ULONG64 offset, ULONG count, bool phyAddr ) +//{ +// return g_dbgClient->loadWords( offset, count, phyAddr ); +//} +// +/////////////////////////////////////////////////////////////////////////////////////// +// +//python::list DebugClient::loadDWords( ULONG64 offset, ULONG count, bool phyAddr ) +//{ +// return loadArray( offset, count, phyAddr ); +//} +// +//python::list loadDWords( ULONG64 offset, ULONG count, bool phyAddr ) +//{ +// return g_dbgClient->loadDWords( offset, count, phyAddr ); +//} +// +/////////////////////////////////////////////////////////////////////////////////////// +// +//python::list DebugClient::loadQWords( ULONG64 offset, ULONG count, bool phyAddr ) +//{ +// return loadArray( offset, count, phyAddr ); +//} +// +//python::list loadQWords( ULONG64 offset, ULONG count, bool phyAddr ) +//{ +// return g_dbgClient->loadQWords( offset, count, phyAddr ); +//} +// +/////////////////////////////////////////////////////////////////////////////////////// +// +//python::list DebugClient::loadSignBytes( ULONG64 offset, ULONG count, bool phyAddr ) +//{ +// return loadArray( offset, count, phyAddr ); +//} +// +//python::list loadSignBytes( ULONG64 offset, ULONG count, bool phyAddr ) +//{ +// return g_dbgClient->loadSignBytes( offset, count, phyAddr ); +//} +// +/////////////////////////////////////////////////////////////////////////////////////// +// +//python::list DebugClient::loadSignWords( ULONG64 offset, ULONG count, bool phyAddr ) +//{ +// return loadArray( offset, count, phyAddr ); +//} +// +//python::list loadSignWords( ULONG64 offset, ULONG count, bool phyAddr ) +//{ +// return g_dbgClient->loadSignWords( offset, count, phyAddr ); +//} +// +/////////////////////////////////////////////////////////////////////////////////////// +// +//python::list DebugClient::loadSignDWords( ULONG64 offset, ULONG count, bool phyAddr ) +//{ +// return loadArray( offset, count, phyAddr ); +//} +// +//python::list loadSignDWords( ULONG64 offset, ULONG count, bool phyAddr ) +//{ +// return g_dbgClient->loadSignDWords( offset, count, phyAddr ); +//} +// +/////////////////////////////////////////////////////////////////////////////////////// +// +//python::list DebugClient::loadSignQWords( ULONG64 offset, ULONG count, bool phyAddr ) +//{ +// return loadArray<__int64>( offset, count, phyAddr ); +//} +// +//python::list loadSignQWords( ULONG64 offset, ULONG count, bool phyAddr ) +//{ +// return g_dbgClient->loadSignQWords( offset, count, phyAddr ); +//} +// +/////////////////////////////////////////////////////////////////////////////////////// +// +//ULONG64 DebugClient::ptrByte( ULONG64 offset ) +//{ +// unsigned char val = 0; +// +// readMemory( m_dataSpaces, offset, &val, sizeof(val), false ); +// +// return val; +//} +// +//ULONG64 ptrByte( ULONG64 offset ) +//{ +// return g_dbgClient->ptrByte( offset ); +//} +// +/////////////////////////////////////////////////////////////////////////////////////// +// +//ULONG64 DebugClient::ptrWord( ULONG64 offset ) +//{ +// unsigned short val = 0; +// +// readMemory( m_dataSpaces, offset, &val, sizeof(val), false ); +// +// return val; +//} +// +//ULONG64 ptrWord( ULONG64 offset ) +//{ +// return g_dbgClient->ptrWord( offset ); +//} +// +/////////////////////////////////////////////////////////////////////////////////////// +// +//ULONG64 ptrDWord( ULONG64 offset, IDebugDataSpaces4* dbgDataSpace ) +//{ +// unsigned long val = 0; +// +// readMemory( dbgDataSpace, offset, &val, sizeof(val), false ); +// +// return val; +//} +// +//ULONG64 DebugClient::ptrDWord( ULONG64 offset ) +//{ +// return pykd::ptrDWord( offset, m_dataSpaces ); +//} +// +//ULONG64 ptrDWord( ULONG64 offset ) +//{ +// return g_dbgClient->ptrDWord( offset ); +//} +// +/////////////////////////////////////////////////////////////////////////////////////// +// +//ULONG64 ptrQWord( ULONG64 offset, IDebugDataSpaces4* dbgDataSpace ) +//{ +// unsigned __int64 val = 0; +// +// readMemory( dbgDataSpace, offset, &val, sizeof(val), false ); +// +// return val; +//} +// +//ULONG64 DebugClient::ptrQWord( ULONG64 offset ) +//{ +// return pykd::ptrQWord( offset, m_dataSpaces ); +//} +// +//ULONG64 ptrQWord( ULONG64 offset ) +//{ +// return g_dbgClient->ptrQWord( offset ); +//} +// +/////////////////////////////////////////////////////////////////////////////////////// +// +//ULONG64 ptrMWord( ULONG64 offset, IDebugDataSpaces4* dbgDataSpace ) +//{ +// return ptrSize() == 8 ? ptrQWord( offset, dbgDataSpace ) : ptrDWord(offset, dbgDataSpace); +//} +// +//ULONG64 DebugClient::ptrMWord( ULONG64 offset ) +//{ +// return ptrSize() == 8 ? ptrQWord( offset ) : ptrDWord(offset); +//} +// +//ULONG64 ptrMWord( ULONG64 offset ) +//{ +// return g_dbgClient->ptrMWord( offset ); +//} +// +/////////////////////////////////////////////////////////////////////////////////////// +// +//ULONG64 ptrPtr( ULONG64 offset, IDebugDataSpaces4* dbgDataSpace ) +//{ +// return ptrMWord( offset, dbgDataSpace ); +//} +// +//ULONG64 DebugClient::ptrPtr( ULONG64 offset ) +//{ +// return addr64( pykd::ptrPtr( offset, m_dataSpaces ) ); +//} +// +//ULONG64 ptrPtr( ULONG64 offset ) +//{ +// return g_dbgClient->ptrPtr( offset ); +//} +// +/////////////////////////////////////////////////////////////////////////////////////// +// +//LONG64 DebugClient::ptrSignByte( ULONG64 offset ) +//{ +// char val = 0; +// +// readMemory( m_dataSpaces, offset, &val, sizeof(val), false ); +// +// return val; +//} +// +//LONG64 ptrSignByte( ULONG64 offset ) +//{ +// return g_dbgClient->ptrSignByte( offset ); +//} +// +/////////////////////////////////////////////////////////////////////////////////////// +// +//LONG64 DebugClient::ptrSignWord( ULONG64 offset ) +//{ +// short val = 0; +// +// readMemory( m_dataSpaces, offset, &val, sizeof(val), false ); +// +// return val; +//} +// +//LONG64 ptrSignWord( ULONG64 offset ) +//{ +// return g_dbgClient->ptrSignWord( offset ); +//} +// +/////////////////////////////////////////////////////////////////////////////////////// +// +//LONG64 DebugClient::ptrSignDWord( ULONG64 offset ) +//{ +// long val = 0; +// +// readMemory( m_dataSpaces, offset, &val, sizeof(val), false ); +// +// return val; +//} +// +//LONG64 ptrSignDWord( ULONG64 offset ) +//{ +// return g_dbgClient->ptrSignDWord( offset ); +//} +// +/////////////////////////////////////////////////////////////////////////////////////// +// +//LONG64 DebugClient::ptrSignQWord( ULONG64 offset ) +//{ +// __int64 val = 0; +// +// readMemory( m_dataSpaces, offset, &val, sizeof(val), false ); +// +// return val; +//} +// +//LONG64 ptrSignQWord( ULONG64 offset ) +//{ +// return g_dbgClient->ptrSignQWord( offset ); +//} +// +/////////////////////////////////////////////////////////////////////////////////////// +// +//LONG64 DebugClient::ptrSignMWord( ULONG64 offset ) +//{ +// return ptrSize() == 8 ? ptrSignQWord( offset ) : ptrSignDWord(offset); +//} +// +//LONG64 ptrSignMWord( ULONG64 offset ) +//{ +// return g_dbgClient->ptrSignMWord( offset ); +//} +// +/////////////////////////////////////////////////////////////////////////////////////// +// +//bool DebugClient::compareMemory( ULONG64 addr1, ULONG64 addr2, ULONG length, bool phyAddr ) +//{ +// return compareMemoryRange( m_dataSpaces, addr1, addr2, length, phyAddr ); +//} +// +//bool compareMemory( ULONG64 addr1, ULONG64 addr2, ULONG length, bool phyAddr ) +//{ +// return g_dbgClient->compareMemory( addr1, addr2, length, phyAddr ); +//} +// +/////////////////////////////////////////////////////////////////////////////////////// +// +//std::wstring DebugClient::loadUnicodeStr( ULONG64 address ) +//{ +// USHORT length; +// USHORT maximumLength; +// ULONG64 buffer = 0; +// +// readMemory( m_dataSpaces, address, &length, sizeof( length ) ); +// +// if ( length == 0 ) +// return L""; +// +// address += sizeof( length ); +// +// readMemory( m_dataSpaces, address, &maximumLength, sizeof( maximumLength ) ); +// +// address += sizeof( maximumLength ); +// +// if ( is64bitSystem() ) +// { +// address += address % 8 ? ( 8 - address % 8 ) : 0 ; // выравнивание на 8 байт +// +// buffer = ptrPtr( address ); +// +// address += 8; +// } +// else +// { +// address += address % 4 ? ( 4 - address % 4 ) : 0 ; // выравнивание на 8 байт +// +// buffer = addr64( ptrPtr( address ) ); +// +// address += 4; +// } +// +// std::vector str(length / 2); +// +// readMemory( m_dataSpaces, buffer, &str[0], length ); +// +// return std::wstring (&str[0], length/2); +//} +// +//std::wstring loadUnicodeStr( ULONG64 address ) +//{ +// return g_dbgClient->loadUnicodeStr( address ); +//} +// +/////////////////////////////////////////////////////////////////////////////////////// +// +//std::string DebugClient::loadAnsiStr( ULONG64 address ) +//{ +// USHORT length; +// USHORT maximumLength; +// ULONG64 buffer = 0; +// +// readMemory( m_dataSpaces, address, &length, sizeof( length ) ); +// +// if ( length == 0 ) +// return ""; +// +// address += sizeof( length ); +// +// readMemory( m_dataSpaces, address, &maximumLength, sizeof( maximumLength ) ); +// +// address += sizeof( maximumLength ); +// +// if ( is64bitSystem() ) +// { +// address += address % 8 ? ( 8 - address % 8 ) : 0 ; // выравнивание на 8 байт +// +// buffer = ptrPtr( address ); +// +// address += 8; +// } +// else +// { +// address += address % 4 ? ( 4 - address % 4 ) : 0 ; // выравнивание на 8 байт +// +// buffer = addr64( ptrPtr( address ) ); +// +// address += 4; +// } +// +// std::vector str(length); +// +// readMemory( m_dataSpaces, buffer, &str[0], length ); +// +// return std::string (&str[0], length); +//} +// +// +//std::string loadAnsiStr( ULONG64 address ) +//{ +// return g_dbgClient->loadAnsiStr( address ); +//} +// +/////////////////////////////////////////////////////////////////////////////////////// +// +//python::list DebugClient::loadPtrList( ULONG64 address ) +//{ +// address = addr64( address ); +// +// ULONG64 entryAddress = 0; +// +// python::list lst; +// +// for( entryAddress = ptrPtr( address ); entryAddress != address && entryAddress != 0; entryAddress = ptrPtr( entryAddress ) ) +// lst.append( entryAddress ); +// +// return lst; +//} +// +//python::list loadPtrList( ULONG64 address ) +//{ +// return g_dbgClient->loadPtrList( address ); +//} +// +/////////////////////////////////////////////////////////////////////////////////////// +// +//python::list DebugClient::loadPtrArray( ULONG64 address, ULONG number ) +//{ +// address = addr64( address ); +// +// python::list lst; +// +// for ( ULONG i = 0; i < number; ++i ) +// lst.append( ptrPtr( address + i*ptrSize() ) ); +// +// return lst; +//} +// +//python::list loadPtrArray( ULONG64 address, ULONG number ) +//{ +// return g_dbgClient->loadPtrArray( address, number ); +//} +// +/////////////////////////////////////////////////////////////////////////////////////// +// +//}; // end of pykd diff --git a/pykd/dbgmem.h b/pykd/dbgmem.h index bb8cde3..2f9c3c2 100644 --- a/pykd/dbgmem.h +++ b/pykd/dbgmem.h @@ -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 ); +// +///////////////////////////////////////////////////////////////////////////////////// +// +//}; diff --git a/pykd/dia/diawrapper.cpp b/pykd/dia/diawrapper.cpp new file mode 100644 index 0000000..585fe52 --- /dev/null +++ b/pykd/dia/diawrapper.cpp @@ -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(symTag), +// NULL, +// nameCmpFlags, +// &symbols); +// +// } +// else +// { +// hres = m_symbol->findChildren( +// static_cast(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(vtValue.bVal) ); +// +// case VT_BOOL: +// return python::object( static_cast(!!vtValue.iVal) ); +// +// case VT_I2: +// case VT_UI2: +// return python::object( static_cast(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(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(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); +//} +// +////////////////////////////////////////////////////////////////////////////////// +// +//} diff --git a/pykd/dia/diawrapper.h b/pykd/dia/diawrapper.h new file mode 100644 index 0000000..fd65d4e --- /dev/null +++ b/pykd/dia/diawrapper.h @@ -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 getChildCount(); + + //ULONG getChildCount() { + // return getChildCount(); + //} + + //template + //SymbolPtr getChildByIndex(ULONG _index ); + + //SymbolPtr getChildByIndex(ULONG _index ) { + // return getChildByIndex( _index ); + //} + // + //bool isConstant(); + + //std::string print(); + + //bool eq(Symbol &rhs); + + //int getVirtualBasePointerOffset(); + + //ULONG getVirtualBaseDispIndex(); + + //ULONG getVirtualBaseDispSize(); + + //ULONG getSection(); + +public: + //typedef std::pair 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 symSet; + // typedef boost::shared_ptr symSetPtr; + // symSetPtr m_symSetPtr; + //}; + + //static std::string printImpl( + // IDiaSymbol *_symbol, + // DWORD machineType, + // ULONG indent = 0, + // checkSymLoop *checkLoopPrev = NULL, + // const char *prefix = NULL + //); + + template + 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 +// +//#include +// +//#include +// +//#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 getChildCount(); +// +// ULONG getChildCount() { +// return getChildCount(); +// } +// +// template +// SymbolPtr getChildByIndex(ULONG _index ); +// +// SymbolPtr getChildByIndex(ULONG _index ) { +// return getChildByIndex( _index ); +// } +// +// bool isConstant(); +// +// std::string print(); +// +// bool eq(Symbol &rhs); +// +// int getVirtualBasePointerOffset(); +// +// ULONG getVirtualBaseDispIndex(); +// +// ULONG getVirtualBaseDispSize(); +// +// ULONG getSection(); +// +//public: +// typedef std::pair 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 symSet; +// typedef boost::shared_ptr symSetPtr; +// symSetPtr m_symSetPtr; +// }; +// +// static std::string printImpl( +// IDiaSymbol *_symbol, +// DWORD machineType, +// ULONG indent = 0, +// checkSymLoop *checkLoopPrev = NULL, +// const char *prefix = NULL +// ); +// +// template +// 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 Symbol::getChildCount() +//{ +// DiaEnumSymbolsPtr symbols; +// HRESULT hres = +// m_symbol->findChildren( +// static_cast(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 +//SymbolPtr Symbol::getChildByIndex(ULONG _index ) +//{ +// DiaEnumSymbolsPtr symbols; +// HRESULT hres = +// m_symbol->findChildren( +// static_cast(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) ); +//} +// +////////////////////////////////////////////////////////////////////////////////// +// +//}; diff --git a/pykd/diawrapper.cpp b/pykd/diawrapper.cpp deleted file mode 100644 index a3b8fe7..0000000 --- a/pykd/diawrapper.cpp +++ /dev/null @@ -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(symTag), - NULL, - nameCmpFlags, - &symbols); - - } - else - { - hres = m_symbol->findChildren( - static_cast(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(vtValue.bVal) ); - - case VT_BOOL: - return python::object( static_cast(!!vtValue.iVal) ); - - case VT_I2: - case VT_UI2: - return python::object( static_cast(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(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(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); -} - -//////////////////////////////////////////////////////////////////////////////// - -} diff --git a/pykd/diawrapper.h b/pykd/diawrapper.h deleted file mode 100644 index 68843c8..0000000 --- a/pykd/diawrapper.h +++ /dev/null @@ -1,373 +0,0 @@ - -#pragma once -#include - -#include - -#include - -#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 getChildCount(); - - ULONG getChildCount() { - return getChildCount(); - } - - template - SymbolPtr getChildByIndex(ULONG _index ); - - SymbolPtr getChildByIndex(ULONG _index ) { - return getChildByIndex( _index ); - } - - bool isConstant(); - - std::string print(); - - bool eq(Symbol &rhs); - - int getVirtualBasePointerOffset(); - - ULONG getVirtualBaseDispIndex(); - - ULONG getVirtualBaseDispSize(); - - ULONG getSection(); - -public: - typedef std::pair 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 symSet; - typedef boost::shared_ptr symSetPtr; - symSetPtr m_symSetPtr; - }; - - static std::string printImpl( - IDiaSymbol *_symbol, - DWORD machineType, - ULONG indent = 0, - checkSymLoop *checkLoopPrev = NULL, - const char *prefix = NULL - ); - - template - 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 Symbol::getChildCount() -{ - DiaEnumSymbolsPtr symbols; - HRESULT hres = - m_symbol->findChildren( - static_cast(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 -SymbolPtr Symbol::getChildByIndex(ULONG _index ) -{ - DiaEnumSymbolsPtr symbols; - HRESULT hres = - m_symbol->findChildren( - static_cast(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) ); -} - -//////////////////////////////////////////////////////////////////////////////// - -}; diff --git a/pykd/module.cpp b/pykd/module.cpp index b4adc1d..c5daa5b 100644 --- a/pykd/module.cpp +++ b/pykd/module.cpp @@ -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" diff --git a/pykd/module.h b/pykd/module.h index f1bb3ff..2a19164 100644 --- a/pykd/module.h +++ b/pykd/module.h @@ -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; }; /////////////////////////////////////////////////////////////////////////////////// diff --git a/pykd/pykd_2008.vcproj b/pykd/pykd_2008.vcproj index 87606a6..3264249 100644 --- a/pykd/pykd_2008.vcproj +++ b/pykd/pykd_2008.vcproj @@ -45,7 +45,7 @@ Name="VCCLCompilerTool" AdditionalOptions="/bigobj" Optimization="0" - AdditionalIncludeDirectories=""$(DIA_SDK_ROOT)\include";"$(DBG_SDK_ROOT)\inc";"$(BOOST_ROOT)";"$(PYTHON_ROOT)\x86\include"" + AdditionalIncludeDirectories=""$(ProjectDir)";"$(DIA_SDK_ROOT)\include";"$(DBG_SDK_ROOT)\inc";"$(BOOST_ROOT)";"$(PYTHON_ROOT)\x64\include"" PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;PYKD_EXPORTS" GeneratePreprocessedFile="0" KeepComments="false" @@ -126,7 +126,7 @@ Name="VCCLCompilerTool" AdditionalOptions="/bigobj" Optimization="0" - AdditionalIncludeDirectories=""$(DIA_SDK_ROOT)\include";"$(DBG_SDK_ROOT)\inc";"$(BOOST_ROOT)";"$(PYTHON_ROOT)\x64\include"" + AdditionalIncludeDirectories=""$(ProjectDir)";"$(DIA_SDK_ROOT)\include";"$(DBG_SDK_ROOT)\inc";"$(BOOST_ROOT)";"$(PYTHON_ROOT)\x64\include"" PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;PYKD_EXPORTS" GeneratePreprocessedFile="0" KeepComments="false" @@ -207,7 +207,7 @@ + + @@ -405,10 +409,6 @@ /> - - + + @@ -444,7 +448,11 @@ > + + @@ -458,6 +466,38 @@ > + + + + + + + + + + + + + + + + diff --git a/pykd/pymod.cpp b/pykd/pymod.cpp index fb41924..b3a232a 100644 --- a/pykd/pymod.cpp +++ b/pykd/pymod.cpp @@ -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 " " #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", python::no_init ) .def( python::init() ) .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( "BaseException", "Pykd base exception class" ); - //pykd::exception( "MemoryException", "Target memory access exception class" ); + pykd::exception( "MemoryException", "Target memory access exception class" ); //pykd::exception( "WaitEventException", "Debug interface access exception" ); - //pykd::exception( "SymbolException", "Symbol exception" ); + pykd::exception( "SymbolException", "Symbol exception" ); //pykd::exception( "DiaException", "Debug interface access exception" ); //pykd::exception( "TypeException", "type exception" ); //pykd::exception( "AddSynSymbolException", "synthetic symbol exception" ); diff --git a/pykd/typeinfo.h b/pykd/typeinfo.h index 45e06a0..2c6a51a 100644 --- a/pykd/typeinfo.h +++ b/pykd/typeinfo.h @@ -1,13 +1,5 @@ #pragma once -#include - -#include - -#include "udtutils.h" -#include "diawrapper.h" -#include "intbase.h" - namespace pykd { /////////////////////////////////////////////////////////////////////////////////// @@ -15,499 +7,529 @@ namespace pykd { class TypeInfo; typedef boost::shared_ptr TypeInfoPtr; -/////////////////////////////////////////////////////////////////////////////////// - -class TypeInfo : boost::noncopyable, public intBase, public boost::enable_shared_from_this { +class TypeInfo : boost::noncopyable, public intBase { public: static TypeInfoPtr getTypeInfoByName( const std::string &symName ); - static - TypeInfoPtr getTypeInfo( pyDia::SymbolPtr &symScope, const std::string &symName ); - - static - TypeInfoPtr getTypeInfo( pyDia::SymbolPtr &symScope, pyDia::SymbolPtr &symChild ); - - static - TypeInfoPtr getTypeInfo( pyDia::SymbolPtr &symbol ); - - static - TypeInfoPtr getBaseTypeInfo( const std::string &name ); - - static - TypeInfoPtr getBaseTypeInfo( pyDia::SymbolPtr &symbol ); - - static - bool isBaseType( const std::string &name ); - -public: - - TypeInfo() : - m_staticOffset( 0 ), - m_constant( false ), - m_staticMember( false ), - m_virtualMember( false ), - m_virtualBasePtr( 0 ), - m_virtualDispIndex( 0 ), - m_virtualDispSize( 0 ) - { - m_constantValue.vt = VT_EMPTY; - } - - virtual std::string print() { - std::stringstream sstr; - sstr << "Type name: " << getName(); - sstr << " Size: 0x" << std::hex << getSize() << " (" << std::dec << getSize() << ")"; - return sstr.str(); - } - - virtual std::string getName() = 0; - - virtual ULONG getSize() = 0; - - virtual TypeInfoPtr getField( const std::string &fieldName ) { - throw TypeException( getName(), "type is not a struct" ); - } - - virtual TypeInfoPtr getFieldByIndex( ULONG index ) { - throw TypeException( getName(), "type is not a struct" ); - } - - virtual std::string getFieldNameByIndex( ULONG index ) { - throw TypeException( getName(), "type is not a struct" ); - } - - virtual ULONG getFieldOffsetByNameRecirsive( const std::string &fieldName ) { - throw TypeException( getName(), "type is not a struct" ); - } - virtual ULONG getFieldOffsetByNameNotRecursively( const std::string &fieldName ) { - throw TypeException( getName(), "type is not a struct" ); - } - - virtual ULONG getFieldOffsetByIndex( ULONG index ) { - throw TypeException( getName(), "type is not a struct" ); - } - - virtual ULONG getFieldCount() { - throw TypeException( getName(), "type is not a struct" ); - } - - virtual BaseTypeVariant getValue(); - - virtual bool isBasicType() { - return false; - } - - virtual bool isPointer() { - return false; - } - - virtual bool isArray() { - return false; - } - - virtual bool isUserDefined() { - return false; - } - - virtual bool isBitField() { - return false; - } - - virtual bool isEnum() { - return false; - } - - virtual ULONG getCount() { - throw TypeException( getName(), "type is not an array" ); - } - - virtual TypeInfoPtr getElementType() { - throw TypeException( getName(), "type is not an array" ); - } - - virtual ULONG getBitOffset() { - return 0; - } - - virtual ULONG getBitWidth() { - return 8 * getSize(); - } - - virtual python::dict asMap() { - throw TypeException( getName(), "type cannot be converted to a dict" ); - } - - virtual TypeInfoPtr deref() { - throw TypeException( getName(), "type is not a pointer" ); - } - - virtual ULONG getElementCount() { - throw PyException( PyExc_TypeError, "object has no len()" ); - } - - virtual python::tuple getElementByIndex( ULONG index ) { - throw PyException( PyExc_TypeError, "object is unsubscriptable"); - } - - void setConstant( const VARIANT& var ) - { - m_constant = true; - m_constantValue = var; - } - bool isConstant() const - { - return m_constant == true; - } - - bool isStaticMember() const - { - return m_staticMember == true; - } - - bool isVirtualMember() const - { - return m_virtualMember == true; - } - - void setStaticOffset( ULONG64 offset ) { - m_staticOffset = offset; - m_staticMember = true; - } - - void setVirtualBase( TypeInfoPtr virtualBase, LONG virtualBasePtr, ULONG virtualDispIndex, ULONG virtualDispSize ) - { - m_virtualMember = true; - m_virtualBaseType = virtualBase; - m_virtualBasePtr = virtualBasePtr; - m_virtualDispIndex = virtualDispIndex; - m_virtualDispSize = virtualDispSize; - } - - ULONG64 getStaticOffset(); - - void getVirtualDisplacement( ULONG &virtualBasePtr, ULONG &virtualDispIndex, ULONG &virtualDispSize ) { - virtualBasePtr = m_virtualBasePtr; - virtualDispIndex = m_virtualDispIndex; - virtualDispSize = m_virtualDispSize; - }; - - TypeInfoPtr getVirtualBase() { - return m_virtualBaseType; - } - -protected: - - std::string getComplexName(); - - static - TypeInfoPtr getComplexType( pyDia::SymbolPtr &symScope, const std::string &symName ); - - static - TypeInfoPtr getRecurciveComplexType( TypeInfoPtr &lowestType, std::string &suffix, ULONG ptrSize ); - - ULONG64 m_staticOffset; - - bool m_constant; - - bool m_staticMember; - - bool m_virtualMember; - - VARIANT m_constantValue; - - LONG m_virtualBasePtr; - - ULONG m_virtualDispIndex; - - ULONG m_virtualDispSize; - - TypeInfoPtr m_virtualBaseType; }; /////////////////////////////////////////////////////////////////////////////////// -template -class TypeInfoWrapper : public TypeInfo -{ -public: - TypeInfoWrapper( const std::string &name ) : - m_name(name) - {} - -private: - - virtual std::string getName() { - return m_name; - } - - virtual ULONG getSize() { - return sizeof(T); - } - - virtual bool isBasicType() { - return true; - } - - std::string m_name; - -}; - -/////////////////////////////////////////////////////////////////////////////////// - -class BitFieldTypeInfo : public TypeInfo -{ -public: - - BitFieldTypeInfo( pyDia::SymbolPtr &symbol ); - - virtual std::string getName() { - return m_name; - } - - virtual ULONG getSize() { - return m_size; - } - - virtual bool isBitField() { - return true; - } - - virtual ULONG getBitOffset() { - return m_bitPos; - } - - virtual ULONG getBitWidth() { - return m_bitWidth; - } - -private: - - ULONG m_size; - ULONG m_bitWidth; - ULONG m_bitPos; - std::string m_name; -}; - -/////////////////////////////////////////////////////////////////////////////////// - -class UdtTypeInfo : public TypeInfo -{ -public: - - UdtTypeInfo ( pyDia::SymbolPtr &symbol ) : - m_dia( symbol ), - m_fields( symbol->getName() ) - { - } - -protected: - - virtual std::string getName() { - return m_dia->getName(); - } - - virtual ULONG getSize() { - return (ULONG)m_dia->getSize(); - } - - virtual TypeInfoPtr getField( const std::string &fieldName ) { - return lookupField(fieldName).m_type; - } - - virtual TypeInfoPtr getFieldByIndex( ULONG index ) { - return lookupField(index).m_type; - } - - virtual std::string getFieldNameByIndex( ULONG index ) { - return lookupField(index).m_name; - } - - virtual ULONG getFieldOffsetByNameRecirsive( const std::string &fieldName ) { - return UdtUtils::getFiledOffsetRecirsive( shared_from_this(), fieldName ); - } - virtual ULONG getFieldOffsetByNameNotRecursively( const std::string &fieldName ) { - return lookupField(fieldName).m_offset; - } - - virtual ULONG getFieldOffsetByIndex( ULONG index ) { - return lookupField(index).m_offset; - } - - virtual ULONG getFieldCount(); - - virtual bool isUserDefined() { - return true; - } - - virtual ULONG getElementCount() { - return getFieldCount(); - } - - virtual python::tuple getElementByIndex( ULONG index ) { - return python::make_tuple( getFieldNameByIndex(index), getFieldByIndex(index) ); - } - - virtual std::string print(); - - pyDia::SymbolPtr m_dia; - - UdtUtils::FieldCollection m_fields; - - void getFields( - pyDia::SymbolPtr &rootSym, - pyDia::SymbolPtr &baseVirtualSym, - ULONG startOffset = 0, - LONG virtualBasePtr = 0, - ULONG virtualDispIndex = 0, - ULONG m_virtualDispSize = 0 ); - - - void getVirtualFields(); - -private: - void refreshFields(); - - template - const UdtUtils::Field &lookupField( T index) { - refreshFields(); - return m_fields.lookup(index); - } -}; - -/////////////////////////////////////////////////////////////////////////////////// - -class EnumTypeInfo : public TypeInfo -{ -public: - - EnumTypeInfo ( pyDia::SymbolPtr &symbol ) : - m_dia( symbol ) - {} - -protected: - - virtual std::string getName() { - return m_dia->getName(); - } - - virtual ULONG getSize() { - return (ULONG)m_dia->getSize(); - } - - virtual TypeInfoPtr getFieldByIndex( ULONG index ); - - virtual std::string getFieldNameByIndex( ULONG index ); - - virtual ULONG getFieldCount(); - - virtual TypeInfoPtr getField( const std::string &fieldName ); - - virtual python::dict asMap(); - - virtual bool isEnum() { - return true; - } - - virtual std::string print(); - - pyDia::SymbolPtr m_dia; -}; - -/////////////////////////////////////////////////////////////////////////////////// - -class PointerTypeInfo : public TypeInfo { - -public: - - PointerTypeInfo( const TypeInfoPtr ptr, ULONG ptrSize ) : - m_size( ptrSize ), - m_derefType( ptr ) - {} - - PointerTypeInfo( pyDia::SymbolPtr &symbol ); - - PointerTypeInfo( pyDia::SymbolPtr &symScope, const std::string &symName ); - - virtual std::string getName(); - - virtual ULONG getSize(); - - virtual bool isPointer() { - return true; - } - - virtual TypeInfoPtr deref() { - return getDerefType(); - } - - TypeInfoPtr getDerefType() { - if (!m_derefType) - throw TypeException("", "this pointer can not be dereferenced"); - return m_derefType; - } - - bool derefPossible() const { - return m_derefType; - } - - const std::string getDerefName() const { - if (m_derefName.empty()) - throw TypeException("", "this pointer can not be dereferenced"); - return m_derefName; - } - -private: - - TypeInfoPtr m_derefType; - ULONG m_size; - std::string m_derefName; -}; - -/////////////////////////////////////////////////////////////////////////////////// - -class ArrayTypeInfo : public TypeInfo { - -public: - - ArrayTypeInfo( const TypeInfoPtr ptr, ULONG count ) : - m_derefType( ptr ), - m_count( count ) - {} - - ArrayTypeInfo( pyDia::SymbolPtr &symbol ); - - ArrayTypeInfo( pyDia::SymbolPtr &symScope, const std::string &symName, ULONG count ); - - virtual std::string getName(); - - virtual ULONG getSize(); - - virtual bool isArray() { - return true; - } - - virtual ULONG getCount() { - return m_count; - } - - virtual TypeInfoPtr getElementType() { - return m_derefType; - } - - TypeInfoPtr getDerefType() { - return m_derefType; - } - -private: - - TypeInfoPtr m_derefType; - - ULONG m_count; -}; - -/////////////////////////////////////////////////////////////////////////////////// - -}; // namespace pykd +}; //end pykd namespace + + + +//#include +// +//#include +// +//#include "udtutils.h" +//#include "diawrapper.h" +//#include "intbase.h" +// +//namespace pykd { +// +///////////////////////////////////////////////////////////////////////////////////// +// +//class TypeInfo; +//typedef boost::shared_ptr TypeInfoPtr; +// +///////////////////////////////////////////////////////////////////////////////////// +// +//class TypeInfo : boost::noncopyable, public intBase, public boost::enable_shared_from_this { +// +//public: +// +// static +// TypeInfoPtr getTypeInfoByName( const std::string &symName ); +// +// static +// TypeInfoPtr getTypeInfo( pyDia::SymbolPtr &symScope, const std::string &symName ); +// +// static +// TypeInfoPtr getTypeInfo( pyDia::SymbolPtr &symScope, pyDia::SymbolPtr &symChild ); +// +// static +// TypeInfoPtr getTypeInfo( pyDia::SymbolPtr &symbol ); +// +// static +// TypeInfoPtr getBaseTypeInfo( const std::string &name ); +// +// static +// TypeInfoPtr getBaseTypeInfo( pyDia::SymbolPtr &symbol ); +// +// static +// bool isBaseType( const std::string &name ); +// +//public: +// +// TypeInfo() : +// m_staticOffset( 0 ), +// m_constant( false ), +// m_staticMember( false ), +// m_virtualMember( false ), +// m_virtualBasePtr( 0 ), +// m_virtualDispIndex( 0 ), +// m_virtualDispSize( 0 ) +// { +// m_constantValue.vt = VT_EMPTY; +// } +// +// virtual std::string print() { +// std::stringstream sstr; +// sstr << "Type name: " << getName(); +// sstr << " Size: 0x" << std::hex << getSize() << " (" << std::dec << getSize() << ")"; +// return sstr.str(); +// } +// +// virtual std::string getName() = 0; +// +// virtual ULONG getSize() = 0; +// +// virtual TypeInfoPtr getField( const std::string &fieldName ) { +// throw TypeException( getName(), "type is not a struct" ); +// } +// +// virtual TypeInfoPtr getFieldByIndex( ULONG index ) { +// throw TypeException( getName(), "type is not a struct" ); +// } +// +// virtual std::string getFieldNameByIndex( ULONG index ) { +// throw TypeException( getName(), "type is not a struct" ); +// } +// +// virtual ULONG getFieldOffsetByNameRecirsive( const std::string &fieldName ) { +// throw TypeException( getName(), "type is not a struct" ); +// } +// virtual ULONG getFieldOffsetByNameNotRecursively( const std::string &fieldName ) { +// throw TypeException( getName(), "type is not a struct" ); +// } +// +// virtual ULONG getFieldOffsetByIndex( ULONG index ) { +// throw TypeException( getName(), "type is not a struct" ); +// } +// +// virtual ULONG getFieldCount() { +// throw TypeException( getName(), "type is not a struct" ); +// } +// +// virtual BaseTypeVariant getValue(); +// +// virtual bool isBasicType() { +// return false; +// } +// +// virtual bool isPointer() { +// return false; +// } +// +// virtual bool isArray() { +// return false; +// } +// +// virtual bool isUserDefined() { +// return false; +// } +// +// virtual bool isBitField() { +// return false; +// } +// +// virtual bool isEnum() { +// return false; +// } +// +// virtual ULONG getCount() { +// throw TypeException( getName(), "type is not an array" ); +// } +// +// virtual TypeInfoPtr getElementType() { +// throw TypeException( getName(), "type is not an array" ); +// } +// +// virtual ULONG getBitOffset() { +// return 0; +// } +// +// virtual ULONG getBitWidth() { +// return 8 * getSize(); +// } +// +// virtual python::dict asMap() { +// throw TypeException( getName(), "type cannot be converted to a dict" ); +// } +// +// virtual TypeInfoPtr deref() { +// throw TypeException( getName(), "type is not a pointer" ); +// } +// +// virtual ULONG getElementCount() { +// throw PyException( PyExc_TypeError, "object has no len()" ); +// } +// +// virtual python::tuple getElementByIndex( ULONG index ) { +// throw PyException( PyExc_TypeError, "object is unsubscriptable"); +// } +// +// void setConstant( const VARIANT& var ) +// { +// m_constant = true; +// m_constantValue = var; +// } +// bool isConstant() const +// { +// return m_constant == true; +// } +// +// bool isStaticMember() const +// { +// return m_staticMember == true; +// } +// +// bool isVirtualMember() const +// { +// return m_virtualMember == true; +// } +// +// void setStaticOffset( ULONG64 offset ) { +// m_staticOffset = offset; +// m_staticMember = true; +// } +// +// void setVirtualBase( TypeInfoPtr virtualBase, LONG virtualBasePtr, ULONG virtualDispIndex, ULONG virtualDispSize ) +// { +// m_virtualMember = true; +// m_virtualBaseType = virtualBase; +// m_virtualBasePtr = virtualBasePtr; +// m_virtualDispIndex = virtualDispIndex; +// m_virtualDispSize = virtualDispSize; +// } +// +// ULONG64 getStaticOffset(); +// +// void getVirtualDisplacement( ULONG &virtualBasePtr, ULONG &virtualDispIndex, ULONG &virtualDispSize ) { +// virtualBasePtr = m_virtualBasePtr; +// virtualDispIndex = m_virtualDispIndex; +// virtualDispSize = m_virtualDispSize; +// }; +// +// TypeInfoPtr getVirtualBase() { +// return m_virtualBaseType; +// } +// +//protected: +// +// std::string getComplexName(); +// +// static +// TypeInfoPtr getComplexType( pyDia::SymbolPtr &symScope, const std::string &symName ); +// +// static +// TypeInfoPtr getRecurciveComplexType( TypeInfoPtr &lowestType, std::string &suffix, ULONG ptrSize ); +// +// ULONG64 m_staticOffset; +// +// bool m_constant; +// +// bool m_staticMember; +// +// bool m_virtualMember; +// +// VARIANT m_constantValue; +// +// LONG m_virtualBasePtr; +// +// ULONG m_virtualDispIndex; +// +// ULONG m_virtualDispSize; +// +// TypeInfoPtr m_virtualBaseType; +//}; +// +///////////////////////////////////////////////////////////////////////////////////// +// +//template +//class TypeInfoWrapper : public TypeInfo +//{ +//public: +// TypeInfoWrapper( const std::string &name ) : +// m_name(name) +// {} +// +//private: +// +// virtual std::string getName() { +// return m_name; +// } +// +// virtual ULONG getSize() { +// return sizeof(T); +// } +// +// virtual bool isBasicType() { +// return true; +// } +// +// std::string m_name; +// +//}; +// +///////////////////////////////////////////////////////////////////////////////////// +// +//class BitFieldTypeInfo : public TypeInfo +//{ +//public: +// +// BitFieldTypeInfo( pyDia::SymbolPtr &symbol ); +// +// virtual std::string getName() { +// return m_name; +// } +// +// virtual ULONG getSize() { +// return m_size; +// } +// +// virtual bool isBitField() { +// return true; +// } +// +// virtual ULONG getBitOffset() { +// return m_bitPos; +// } +// +// virtual ULONG getBitWidth() { +// return m_bitWidth; +// } +// +//private: +// +// ULONG m_size; +// ULONG m_bitWidth; +// ULONG m_bitPos; +// std::string m_name; +//}; +// +///////////////////////////////////////////////////////////////////////////////////// +// +//class UdtTypeInfo : public TypeInfo +//{ +//public: +// +// UdtTypeInfo ( pyDia::SymbolPtr &symbol ) : +// m_dia( symbol ), +// m_fields( symbol->getName() ) +// { +// } +// +//protected: +// +// virtual std::string getName() { +// return m_dia->getName(); +// } +// +// virtual ULONG getSize() { +// return (ULONG)m_dia->getSize(); +// } +// +// virtual TypeInfoPtr getField( const std::string &fieldName ) { +// return lookupField(fieldName).m_type; +// } +// +// virtual TypeInfoPtr getFieldByIndex( ULONG index ) { +// return lookupField(index).m_type; +// } +// +// virtual std::string getFieldNameByIndex( ULONG index ) { +// return lookupField(index).m_name; +// } +// +// virtual ULONG getFieldOffsetByNameRecirsive( const std::string &fieldName ) { +// return UdtUtils::getFiledOffsetRecirsive( shared_from_this(), fieldName ); +// } +// virtual ULONG getFieldOffsetByNameNotRecursively( const std::string &fieldName ) { +// return lookupField(fieldName).m_offset; +// } +// +// virtual ULONG getFieldOffsetByIndex( ULONG index ) { +// return lookupField(index).m_offset; +// } +// +// virtual ULONG getFieldCount(); +// +// virtual bool isUserDefined() { +// return true; +// } +// +// virtual ULONG getElementCount() { +// return getFieldCount(); +// } +// +// virtual python::tuple getElementByIndex( ULONG index ) { +// return python::make_tuple( getFieldNameByIndex(index), getFieldByIndex(index) ); +// } +// +// virtual std::string print(); +// +// pyDia::SymbolPtr m_dia; +// +// UdtUtils::FieldCollection m_fields; +// +// void getFields( +// pyDia::SymbolPtr &rootSym, +// pyDia::SymbolPtr &baseVirtualSym, +// ULONG startOffset = 0, +// LONG virtualBasePtr = 0, +// ULONG virtualDispIndex = 0, +// ULONG m_virtualDispSize = 0 ); +// +// +// void getVirtualFields(); +// +//private: +// void refreshFields(); +// +// template +// const UdtUtils::Field &lookupField( T index) { +// refreshFields(); +// return m_fields.lookup(index); +// } +//}; +// +///////////////////////////////////////////////////////////////////////////////////// +// +//class EnumTypeInfo : public TypeInfo +//{ +//public: +// +// EnumTypeInfo ( pyDia::SymbolPtr &symbol ) : +// m_dia( symbol ) +// {} +// +//protected: +// +// virtual std::string getName() { +// return m_dia->getName(); +// } +// +// virtual ULONG getSize() { +// return (ULONG)m_dia->getSize(); +// } +// +// virtual TypeInfoPtr getFieldByIndex( ULONG index ); +// +// virtual std::string getFieldNameByIndex( ULONG index ); +// +// virtual ULONG getFieldCount(); +// +// virtual TypeInfoPtr getField( const std::string &fieldName ); +// +// virtual python::dict asMap(); +// +// virtual bool isEnum() { +// return true; +// } +// +// virtual std::string print(); +// +// pyDia::SymbolPtr m_dia; +//}; +// +///////////////////////////////////////////////////////////////////////////////////// +// +//class PointerTypeInfo : public TypeInfo { +// +//public: +// +// PointerTypeInfo( const TypeInfoPtr ptr, ULONG ptrSize ) : +// m_size( ptrSize ), +// m_derefType( ptr ) +// {} +// +// PointerTypeInfo( pyDia::SymbolPtr &symbol ); +// +// PointerTypeInfo( pyDia::SymbolPtr &symScope, const std::string &symName ); +// +// virtual std::string getName(); +// +// virtual ULONG getSize(); +// +// virtual bool isPointer() { +// return true; +// } +// +// virtual TypeInfoPtr deref() { +// return getDerefType(); +// } +// +// TypeInfoPtr getDerefType() { +// if (!m_derefType) +// throw TypeException("", "this pointer can not be dereferenced"); +// return m_derefType; +// } +// +// bool derefPossible() const { +// return m_derefType; +// } +// +// const std::string getDerefName() const { +// if (m_derefName.empty()) +// throw TypeException("", "this pointer can not be dereferenced"); +// return m_derefName; +// } +// +//private: +// +// TypeInfoPtr m_derefType; +// ULONG m_size; +// std::string m_derefName; +//}; +// +///////////////////////////////////////////////////////////////////////////////////// +// +//class ArrayTypeInfo : public TypeInfo { +// +//public: +// +// ArrayTypeInfo( const TypeInfoPtr ptr, ULONG count ) : +// m_derefType( ptr ), +// m_count( count ) +// {} +// +// ArrayTypeInfo( pyDia::SymbolPtr &symbol ); +// +// ArrayTypeInfo( pyDia::SymbolPtr &symScope, const std::string &symName, ULONG count ); +// +// virtual std::string getName(); +// +// virtual ULONG getSize(); +// +// virtual bool isArray() { +// return true; +// } +// +// virtual ULONG getCount() { +// return m_count; +// } +// +// virtual TypeInfoPtr getElementType() { +// return m_derefType; +// } +// +// TypeInfoPtr getDerefType() { +// return m_derefType; +// } +// +//private: +// +// TypeInfoPtr m_derefType; +// +// ULONG m_count; +//}; +// +///////////////////////////////////////////////////////////////////////////////////// +// +//}; // namespace pykd diff --git a/pykd/windbgeng.cpp b/pykd/win/dbgeng.cpp similarity index 78% rename from pykd/windbgeng.cpp rename to pykd/win/dbgeng.cpp index a990660..03afe71 100644 --- a/pykd/windbgeng.cpp +++ b/pykd/win/dbgeng.cpp @@ -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 ); } /////////////////////////////////////////////////////////////////////////////////// diff --git a/pykd/windbgeng.h b/pykd/win/dbgeng.h similarity index 83% rename from pykd/windbgeng.h rename to pykd/win/dbgeng.h index 6b156ff..dca1692 100644 --- a/pykd/windbgeng.h +++ b/pykd/win/dbgeng.h @@ -4,6 +4,9 @@ #include "dbgexcept.h" #include "pyaux.h" +#include +#include + namespace pykd { /////////////////////////////////////////////////////////////////////////////////// @@ -18,6 +21,8 @@ public: CComQIPtr control; CComQIPtr system; CComQIPtr symbols; + CComQIPtr dataspace; + CComQIPtr advanced; DbgEngBind( PDEBUG_CLIENT4 c ) { @@ -25,6 +30,8 @@ public: control = c; system = c; symbols = c; + dataspace = c; + advanced = c; } PyThreadStateSaver pystate; diff --git a/pykd/win/memory.cpp b/pykd/win/memory.cpp new file mode 100644 index 0000000..2d53d42 --- /dev/null +++ b/pykd/win/memory.cpp @@ -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 \ No newline at end of file diff --git a/pykd/utils.h b/pykd/win/utils.h similarity index 100% rename from pykd/utils.h rename to pykd/win/utils.h diff --git a/test/scripts/pykdtest.py b/test/scripts/pykdtest.py index 5151d2a..7393a2f 100644 --- a/test/scripts/pykdtest.py +++ b/test/scripts/pykdtest.py @@ -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 ) )