[0.2.x] added : typedVar class

git-svn-id: https://pykd.svn.codeplex.com/svn@78536 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
SND\kernelnet_cp 2012-08-06 16:14:56 +00:00 committed by Mikhail I. Izmestev
parent 011f1b4ad5
commit c8d99b5565
18 changed files with 449 additions and 736 deletions

View File

@ -1,5 +1,7 @@
#pragma once #pragma once
#include "dbgmem.h"
namespace pykd { namespace pykd {
// manage debug target // manage debug target
@ -22,10 +24,8 @@ std::string getModuleSymbolFileName( ULONG64 baseOffset );
ULONG getModuleTimeStamp( ULONG64 baseOffset ); ULONG getModuleTimeStamp( ULONG64 baseOffset );
ULONG getModuleCheckSum( ULONG64 baseOffset ); ULONG getModuleCheckSum( ULONG64 baseOffset );
//manage access to target memory // ýòî íóæíî ñäåëàòü ïî-äðóãîìó!
ULONG64 addr64( ULONG64 offset ); std::string getSymbolByOffset( ULONG64 offset );
void readMemory( ULONG64 offset, PVOID buffer, ULONG length, bool phyAddr = FALSE );
}; };

View File

@ -1,11 +1,12 @@
#include "stdafx.h" #include "stdafx.h"
#include "dbgengine.h" #include "dbgengine.h"
namespace pykd { namespace pykd {
///////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////
bool compareMemory( ULONG64 addr1, ULONG64 addr2, ULONG length, bool phyAddr = FALSE ) bool compareMemory( ULONG64 addr1, ULONG64 addr2, ULONG length, bool phyAddr )
{ {
bool result = false; bool result = false;

View File

@ -4,6 +4,8 @@ namespace pykd {
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
ULONG64 addr64( ULONG64 offset );
void readMemory( ULONG64 offset, PVOID buffer, ULONG length, bool phyAddr = FALSE );
bool isVaValid( ULONG64 addr ); bool isVaValid( ULONG64 addr );
bool compareMemory( ULONG64 addr1, ULONG64 addr2, ULONG length, bool phyAddr = FALSE ); bool compareMemory( ULONG64 addr1, ULONG64 addr2, ULONG length, bool phyAddr = FALSE );

View File

@ -45,7 +45,7 @@ std::string DiaException::makeFullDesc(const std::string &desc, HRESULT hres)
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
SymbolPtr loadSymbolFile(const std::string &filePath) SymbolPtr loadSymbolFile(const std::string &filePath, ULONGLONG loadBase )
{ {
HRESULT hres; HRESULT hres;
DiaDataSourcePtr dataSource; DiaDataSourcePtr dataSource;
@ -64,6 +64,10 @@ SymbolPtr loadSymbolFile(const std::string &filePath)
if ( S_OK != hres ) if ( S_OK != hres )
throw DiaException("Call IDiaDataSource::openSession", hres); throw DiaException("Call IDiaDataSource::openSession", hres);
hres = _session->put_loadAddress(loadBase);
if (S_OK != hres)
throw DiaException("Call IDiaSession::put_loadAddress", hres);
DiaSymbolPtr _globalScope; DiaSymbolPtr _globalScope;
hres = _session->get_globalScope(&_globalScope); hres = _session->get_globalScope(&_globalScope);
if ( S_OK != hres ) if ( S_OK != hres )
@ -368,7 +372,6 @@ bool DiaSymbol::isVirtualBaseClass()
// return !!callSymbol(get_indirectVirtualBaseClass); // return !!callSymbol(get_indirectVirtualBaseClass);
//} //}
//////////////////////////////////////////////////////////////////////////////
}; // pykd nemaspace end }; // pykd nemaspace end

View File

@ -154,6 +154,8 @@ public:
//ULONG getSection(); //ULONG getSection();
void setLoadAddress( ULONGLONG baseAddress );
public: public:
typedef std::pair<ULONG, const char *> ValueNameEntry; typedef std::pair<ULONG, const char *> ValueNameEntry;

View File

@ -2,6 +2,7 @@
#include "dbgengine.h" #include "dbgengine.h"
#include "module.h" #include "module.h"
#include "dbgexcept.h" #include "dbgexcept.h"
#include "vardata.h"
namespace pykd { namespace pykd {
@ -51,7 +52,7 @@ SymbolPtr& Module::getSymScope()
if ( m_symfile.empty() ) if ( m_symfile.empty() )
break; break;
m_symScope = loadSymbolFile( m_symfile ); m_symScope = loadSymbolFile( m_symfile, m_base );
} while( false ); } while( false );
@ -109,450 +110,106 @@ std::string Module::print()
sstr << "Start: " << std::hex << m_base << " End: " << getEnd() << " Size: " << m_size << std::endl; sstr << "Start: " << std::hex << m_base << " End: " << getEnd() << " Size: " << m_size << std::endl;
sstr << "Image: " << m_imageName << std::endl; sstr << "Image: " << m_imageName << std::endl;
sstr << "Symnol: " << m_symfile << std::endl; sstr << "Symnol: " << m_symfile << std::endl;
//sstr << "Timestamp: " << m_timeDataStamp << std::endl; sstr << "Timestamp: " << m_timeDataStamp << std::endl;
//sstr << "Check Sum: " << m_checkSum << std::endl; sstr << "Check Sum: " << m_checkSum << std::endl;
return sstr.str(); return sstr.str();
} }
///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
TypedVarPtr
Module::getTypedVarByAddr( ULONG64 offset )
{
offset = addr64(offset);
if ( offset < m_base || offset > getEnd() )
throw DbgException( "address is out of the module space" );
std::string symName = getSymbolByOffset( offset );
return getTypedVarByName( symName );
}
///////////////////////////////////////////////////////////////////////////////
TypedVarPtr
Module::getTypedVarByName( const std::string &symName )
{
SymbolPtr symVar = getSymScope()->getChildByName( symName );
TypeInfoPtr typeInfo = TypeInfo::getTypeInfo( symVar->getType() );
if ( LocIsConstant != symVar->getLocType() )
{
ULONG64 offset = getSymbol( symName );
return TypedVar::getTypedVar(typeInfo, VarDataMemory::factory(offset) );
}
return TypedVar::getTypedVar( typeInfo, VarDataConst::factory(symVar) );
//HRESULT hres;
//pyDia::SymbolPtr symVar = getSymScope()->getChildByName( symName );
//std::string fullName = m_name;
//fullName += '!';
//fullName += symName;
//ULONG64 offset;
//hres = m_symbols->GetOffsetByName( fullName.c_str(), &offset );
//TypeInfoPtr typeInfo = TypeInfo::getTypeInfo( symVar->getType() );
//if ( FAILED( hres ) )
//{
// if ( LocIsConstant == symVar->getLocType() )
// return TypedVar::getTypedVar( m_client, typeInfo, VarDataConst::factory(m_control, symVar) );
// throw DbgException("IDebugSymbols::GetOffsetByName failed" );
//}
//return TypedVar::getTypedVar( m_client, typeInfo, VarDataMemory::factory(m_dataSpaces, offset) );
}
///////////////////////////////////////////////////////////////////////////////
TypedVarPtr
Module::getTypedVarByTypeName( const std::string &typeName, ULONG64 offset )
{
TypeInfoPtr typeInfo = getTypeByName( typeName );
return TypedVar::getTypedVar(typeInfo, VarDataMemory::factory(offset) );
}
///////////////////////////////////////////////////////////////////////////////
TypedVarPtr Module::containingRecordByName( ULONG64 offset, const std::string &typeName, const std::string &fieldName )
{
TypeInfoPtr typeInfo = getTypeByName( typeName );
return containingRecordByType( offset, typeInfo, fieldName );
}
///////////////////////////////////////////////////////////////////////////////////
python::list Module::getTypedVarArrayByTypeName( ULONG64 offset, const std::string &typeName, ULONG number )
{
return getTypedVarArrayByType( offset, getTypeByName( typeName ), number );
}
///////////////////////////////////////////////////////////////////////////////////
python::list Module::getTypedVarListByTypeName( ULONG64 listHeadAddress, const std::string &typeName, const std::string &listEntryName )
{
return getTypedVarListByType( listHeadAddress, getTypeByName( typeName ), listEntryName );
}
///////////////////////////////////////////////////////////////////////////////////
}; // end of namespace pykd }; // end of namespace pykd
//#include "module.h"
//#include "dbgclient.h"
//#include "dbgmem.h"
//
//namespace pykd {
//
/////////////////////////////////////////////////////////////////////////////////////
//
//ModulePtr Module::loadModuleByName( const std::string &moduleName ) {
// return g_dbgClient->loadModuleByName( moduleName );
//};
//
//ModulePtr Module::loadModuleByOffset( ULONG64 offset ) {
// return g_dbgClient->loadModuleByOffset( offset );
//}
//
/////////////////////////////////////////////////////////////////////////////////////
//
//Module::Module( IDebugClient4 *client, SynSymbolsPtr synSymbols, const std::string& moduleName )
// : DbgObject( client )
// , m_synSymbols(synSymbols)
//{
// HRESULT hres;
//
// m_name = moduleName;
//
// hres = m_symbols->GetModuleByModuleName( moduleName.c_str(), 0, NULL, &m_base );
// if ( FAILED( hres ) )
// throw DbgException( "IDebugSymbol::GetModuleByModuleName failed" );
//
// DEBUG_MODULE_PARAMETERS moduleParam = { 0 };
// hres = m_symbols->GetModuleParameters( 1, &m_base, 0, &moduleParam );
// if ( FAILED( hres ) )
// throw DbgException( "IDebugSymbol::GetModuleParameters failed" );
//
// m_size = moduleParam.Size;
// m_timeDataStamp = moduleParam.TimeDateStamp;
// m_checkSum = moduleParam.Checksum;
//
// char imageName[0x100];
//
// hres = m_symbols->GetModuleNameString(
// DEBUG_MODNAME_IMAGE,
// DEBUG_ANY_ID,
// m_base,
// imageName,
// sizeof( imageName ),
// NULL );
//
// if ( FAILED( hres ) )
// throw DbgException( "IDebugSymbol::GetModuleNameString failed" );
//
// m_imageName = std::string( imageName );
//}
//
/////////////////////////////////////////////////////////////////////////////////////
//
//Module::Module( IDebugClient4 *client, SynSymbolsPtr synSymbols, ULONG64 offset )
// : DbgObject( client )
// , m_synSymbols(synSymbols)
//{
// HRESULT hres;
//
// offset = addr64( offset );
//
// ULONG moduleIndex;
// hres = m_symbols->GetModuleByOffset( offset, 0, &moduleIndex, &m_base );
// if ( FAILED( hres ) )
// throw DbgException( "IDebugSymbol::GetModuleByOffset failed" );
//
// char moduleName[0x100];
//
// hres = m_symbols->GetModuleNameString(
// DEBUG_MODNAME_MODULE,
// moduleIndex,
// 0,
// moduleName,
// sizeof( moduleName ),
// NULL );
//
// if ( FAILED( hres ) )
// throw DbgException( "IDebugSymbol::GetModuleNameString failed" );
//
// m_name = std::string( moduleName );
//
// char imageName[0x100];
//
// hres = m_symbols->GetModuleNameString(
// DEBUG_MODNAME_IMAGE,
// DEBUG_ANY_ID,
// m_base,
// imageName,
// sizeof( imageName ),
// NULL );
//
// if ( FAILED( hres ) )
// throw DbgException( "IDebugSymbol::GetModuleNameString failed" );
//
// m_imageName = std::string( imageName );
//
// DEBUG_MODULE_PARAMETERS moduleParam = { 0 };
// hres = m_symbols->GetModuleParameters( 1, &m_base, 0, &moduleParam );
// if ( FAILED( hres ) )
// throw DbgException( "IDebugSymbol::GetModuleParameters failed" );
//
// m_size = moduleParam.Size;
// m_timeDataStamp = moduleParam.TimeDateStamp;
// m_checkSum = moduleParam.Checksum;
//}
//
/////////////////////////////////////////////////////////////////////////////////////
//
//std::string
//Module::getPdbName()
//{
// HRESULT hres;
//
// IMAGEHLP_MODULEW64 moduleInfo = {};
//
// hres = m_advanced->GetSymbolInformation(
// DEBUG_SYMINFO_IMAGEHLP_MODULEW64,
// m_base,
// 0,
// &moduleInfo,
// sizeof(moduleInfo),
// NULL,
// NULL,
// 0,
// NULL );
//
// if ( FAILED( hres ) )
// throw DbgException( "IDebugAdvanced2::GetSymbolInformation failed" );
//
// if (!*moduleInfo.LoadedPdbName)
// {
// reloadSymbolsImpl();
//
// hres = m_advanced->GetSymbolInformation(
// DEBUG_SYMINFO_IMAGEHLP_MODULEW64,
// m_base,
// 0,
// &moduleInfo,
// sizeof(moduleInfo),
// NULL,
// NULL,
// 0,
// NULL );
//
// if ( FAILED( hres ) )
// throw DbgException( "IDebugAdvanced2::GetSymbolInformation failed" );
// }
//
// char pdbName[ 256 ];
// WideCharToMultiByte( CP_ACP, 0, moduleInfo.LoadedPdbName, 256, pdbName, 256, NULL, NULL );
//
// return std::string( pdbName );
//}
//
/////////////////////////////////////////////////////////////////////////////////////
//
//void
//Module::reloadSymbolsImpl()
//{
// HRESULT hres;
//
// std::string param = "/f ";
// param += m_imageName;
//
// hres = m_symbols->Reload( param.c_str() );
// if ( FAILED( hres ) )
// throw DbgException("IDebugSymbols::Reload failed" );
//}
//
//
/////////////////////////////////////////////////////////////////////////////////////
//
//void
//Module::reloadSymbols()
//{
// reloadSymbolsImpl();
//
// m_dia.reset();
// m_dia = pyDia::GlobalScope::loadPdb( getPdbName() );
//}
//
/////////////////////////////////////////////////////////////////////////////////////
//
//TypedVarPtr
//Module::getTypedVarByTypeName( const std::string &typeName, ULONG64 addr )
//{
// return TypedVar::getTypedVar( m_client, getTypeByName(typeName), VarDataMemory::factory(m_dataSpaces, addr) );
//}
//
/////////////////////////////////////////////////////////////////////////////////////
//
//TypedVarPtr
//Module::getTypedVarByType( const TypeInfoPtr &typeInfo, ULONG64 addr )
//{
// return TypedVar::getTypedVar( m_client, typeInfo, VarDataMemory::factory(m_dataSpaces, addr) );
//}
//
/////////////////////////////////////////////////////////////////////////////////////
//
//ULONG64
//Module::getSymbolSize( const std::string &symName )
//{
// try {
//
// pyDia::SymbolPtr symVar = getDia()->getChildByName( symName );
//
// if ( symVar->getSymTag() == SymTagData )
// return symVar->getSize();
//
// } catch( const SymbolException& )
// {
// }
//
// return getTypeByName(symName)->getSize();
//}
//
/////////////////////////////////////////////////////////////////////////////////////
//
//TypedVarPtr
//Module::getTypedVarByName( const std::string &symName )
//{
// HRESULT hres;
//
// pyDia::SymbolPtr symVar = getDia()->getChildByName( symName );
//
// std::string fullName = m_name;
// fullName += '!';
// fullName += symName;
//
// ULONG64 offset;
//
// hres = m_symbols->GetOffsetByName( fullName.c_str(), &offset );
//
// TypeInfoPtr typeInfo = TypeInfo::getTypeInfo( symVar->getType() );
//
// if ( FAILED( hres ) )
// {
// if ( LocIsConstant == symVar->getLocType() )
// return TypedVar::getTypedVar( m_client, typeInfo, VarDataConst::factory(m_control, symVar) );
// throw DbgException("IDebugSymbols::GetOffsetByName failed" );
// }
//
// return TypedVar::getTypedVar( m_client, typeInfo, VarDataMemory::factory(m_dataSpaces, offset) );
//}
//
/////////////////////////////////////////////////////////////////////////////////////
//
//TypedVarPtr
//Module::getTypedVarByAddr( ULONG64 addr )
//{
// HRESULT hres;
//
// addr = addr64(addr);
//
// if ( addr < m_base || addr > getEnd() )
// throw DbgException( "address is out of the module space" );
//
// char nameBuf[0x100];
//
// hres =
// m_symbols->GetNameByOffset(
// addr,
// nameBuf,
// sizeof(nameBuf),
// NULL,
// NULL );
//
// std::string fullName( nameBuf );
//
// size_t symPos = fullName.find ( '!' ) + 1;
//
// std::string symbolName;
// symbolName.assign( fullName, symPos, fullName.length() - symPos );
//
// if ( FAILED(hres) )
// throw DbgException( "failed IDebugSymbols::GetNameByOffset" );
//
// return getTypedVarByName( symbolName );
//
// //LONG displacement;
// //pyDia::SymbolPtr diaSym =
// // getDia()->findByRvaImpl((ULONG)(addr - m_base), SymTagData, displacement);
// //if (displacement)
// // throw DbgException( "not exactly match by RVA" );
//
// //return TypedVar::getTypedVar( m_client, TypeInfo::getTypeInfo( diaSym->getType() ), addr );
//}
//
/////////////////////////////////////////////////////////////////////////////////////
//
//ULONG Module::getRvaByName(const std::string &symName)
//{
// HRESULT hres;
// ULONG64 offset;
//
// hres = m_symbols->GetOffsetByName( symName.c_str(), &offset );
// if ( SUCCEEDED(hres) )
// return (ULONG)(offset - m_base);
//
// return (ULONG)m_synSymbols->getRvaByName(m_timeDataStamp, m_checkSum, symName);
//
// //try {
// // pyDia::SymbolPtr sym = getDia()->getChildByName( symName );
// // return sym->getRva();
// //}
// //catch (const pyDia::Exception &) {
// //}
// //return (ULONG)m_synSymbols->getRvaByName(m_timeDataStamp, m_checkSumm, symName);
//}
//
/////////////////////////////////////////////////////////////////////////////////////
//
//TypedVarPtr Module::containingRecordByName( ULONG64 address, const std::string &typeName, const std::string &fieldName )
//{
// address = addr64(address);
//
// TypeInfoPtr typeInfo = getTypeByName( typeName );
//
// VarDataPtr varData =
// VarDataMemory::factory(
// m_dataSpaces,
// address - typeInfo->getFieldOffsetByNameRecirsive( fieldName )
// );
//
// return TypedVar::getTypedVar( m_client, typeInfo, varData );
//}
//
/////////////////////////////////////////////////////////////////////////////////////
//
//TypedVarPtr Module::containingRecordByType( ULONG64 address, const TypeInfoPtr &typeInfo, const std::string &fieldName )
//{
// address = addr64(address);
//
// VarDataPtr varData =
// VarDataMemory::factory(
// m_dataSpaces,
// address - typeInfo->getFieldOffsetByNameRecirsive( fieldName )
// );
//
// return TypedVar::getTypedVar( m_client, typeInfo, varData );
//}
//
//
/////////////////////////////////////////////////////////////////////////////////////
//
//python::list Module::getTypedVarListByTypeName( ULONG64 listHeadAddress, const std::string &typeName, const std::string &listEntryName )
//{
// return getTypedVarListByType( listHeadAddress, getTypeByName( typeName ), listEntryName );
//}
//
/////////////////////////////////////////////////////////////////////////////////////
//
//python::list Module::getTypedVarListByType( ULONG64 listHeadAddress, const TypeInfoPtr &typeInfo, const std::string &listEntryName )
//{
// python::list lst;
//
// listHeadAddress = addr64( listHeadAddress );
//
// ULONG64 entryAddress = 0;
//
// TypeInfoPtr fieldTypeInfo = typeInfo->getField( listEntryName );
//
// if ( fieldTypeInfo->getName() == ( typeInfo->getName() + "*" ) )
// {
// for( entryAddress = ptrPtr( listHeadAddress, m_dataSpaces ); addr64(entryAddress) != listHeadAddress && entryAddress != NULL; entryAddress = ptrPtr( entryAddress + typeInfo->getFieldOffsetByNameRecirsive(listEntryName) ) )
// lst.append( getTypedVarByType( typeInfo, entryAddress ) );
// }
// else
// {
// for( entryAddress = ptrPtr( listHeadAddress, m_dataSpaces ); addr64(entryAddress) != listHeadAddress && entryAddress != NULL; entryAddress = ptrPtr( entryAddress ) )
// lst.append( containingRecordByType( entryAddress, typeInfo, listEntryName ) );
// }
//
// return lst;
//}
//
/////////////////////////////////////////////////////////////////////////////////////
//
//python::list Module::getTypedVarArrayByTypeName( ULONG64 addr, const std::string &typeName, ULONG number )
//{
// return getTypedVarArrayByType( addr, getTypeByName( typeName ), number );
//}
//
/////////////////////////////////////////////////////////////////////////////////////
//
//python::list Module::getTypedVarArrayByType( ULONG64 address, const TypeInfoPtr &typeInfo, ULONG number )
//{
// address = addr64(address);
//
// python::list lst;
//
// for( ULONG i = 0; i < number; ++i )
// lst.append( getTypedVarByType( typeInfo, address + i * typeInfo->getSize() ) );
//
// return lst;
//}
//
/////////////////////////////////////////////////////////////////////////////////////
//
//std::string Module::print()
//{
// std::stringstream sstr;
//
// sstr << "Module: " << m_name << std::endl;
// sstr << "Start: " << std::hex << m_base << " End: " << getEnd() << " Size: " << m_size << std::endl;
// sstr << "Image: " << m_imageName << std::endl;
// sstr << "Pdb: " << getPdbName() << std::endl;
// sstr << "Timestamp: " << m_timeDataStamp << std::endl;
// sstr << "Check Sum: " << m_checkSum << std::endl;
//
// return sstr.str();
//}
//
/////////////////////////////////////////////////////////////////////////////////////
//
//}; // end of namespace pykd
//

View File

@ -3,6 +3,7 @@
#include "intbase.h" #include "intbase.h"
#include "symengine.h" #include "symengine.h"
#include "typeinfo.h" #include "typeinfo.h"
#include "typedvar.h"
namespace pykd { namespace pykd {
@ -78,6 +79,18 @@ public:
return TypeInfo::getTypeInfo( boost::static_pointer_cast<Symbol>( getSymScope() ), typeName); return TypeInfo::getTypeInfo( boost::static_pointer_cast<Symbol>( getSymScope() ), typeName);
} }
TypedVarPtr getTypedVarByAddr( ULONG64 addr );
TypedVarPtr getTypedVarByName( const std::string &symName );
TypedVarPtr getTypedVarByTypeName( const std::string &typeName, ULONG64 addr );
python::list getTypedVarListByTypeName( ULONG64 listHeadAddres, const std::string &typeName, const std::string &listEntryName );
python::list getTypedVarArrayByTypeName( ULONG64 offset, const std::string &typeName, ULONG number );
TypedVarPtr containingRecordByName( ULONG64 offset, const std::string &typeName, const std::string &fieldName );
ULONG64 getSymbolSize( const std::string &symName ); ULONG64 getSymbolSize( const std::string &symName );
std::string print(); std::string print();
@ -107,156 +120,3 @@ private:
}; // end pykd namespace }; // end pykd namespace
//#include <string>
//
//#include "dbgobj.h"
//#include "diawrapper.h"
//#include "typeinfo.h"
//#include "typedvar.h"
//#include "synsymbol.h"
//
//namespace pykd {
//
/////////////////////////////////////////////////////////////////////////////////////
//
//class Module;
//typedef boost::shared_ptr<Module> ModulePtr;
//
/////////////////////////////////////////////////////////////////////////////////////
//
//class Module : public intBase, private DbgObject {
//
//public:
//
// static
// ModulePtr loadModuleByName( const std::string &name );
//
// static
// ModulePtr loadModuleByOffset( ULONG64 offset );
//
//public:
//
// Module( IDebugClient4 *client, SynSymbolsPtr synSymbols, const std::string& moduleName );
//
// Module( IDebugClient4 *client, SynSymbolsPtr synSymbols, ULONG64 offset );
//
// std::string getName() {
// return m_name;
// }
//
// std::string getImageName() {
// return m_imageName;
// }
//
// ULONG64 getBase() const {
// return m_base;
// }
//
// ULONG64 getEnd() const {
// return m_base + m_size;
// }
//
// ULONG getSize() const {
// return m_size;
// }
//
// std::string
// getPdbName();
//
// void
// reloadSymbols();
//
// ULONG64
// getSymbol( const std::string &symbolname ) {
// return m_base + getRvaByName(symbolname);
// }
//
// ULONG
// getSymbolRva( const std::string &symbolname ) {
// return getRvaByName(symbolname);
// }
//
// TypeInfoPtr getTypeByName( const std::string &typeName ) {
// return TypeInfo::getTypeInfo( boost::static_pointer_cast<pyDia::Symbol>( getDia() ), typeName);
// }
//
// TypedVarPtr getTypedVarByTypeName( const std::string &typeName, ULONG64 addr );
//
// TypedVarPtr getTypedVarByType( const TypeInfoPtr &typeInfo, ULONG64 addr );
//
// TypedVarPtr getTypedVarByAddr( ULONG64 addr );
//
// TypedVarPtr getTypedVarByName( const std::string &symName );
//
// TypedVarPtr containingRecordByName( ULONG64 addr, const std::string &typeName, const std::string &fieldName );
//
// TypedVarPtr containingRecordByType( ULONG64 addr, const TypeInfoPtr &typeInfo, const std::string &fieldName );
//
// python::list getTypedVarListByTypeName( ULONG64 listHeadAddres, const std::string &typeName, const std::string &listEntryName );
//
// python::list getTypedVarListByType( ULONG64 listHeadAddres, const TypeInfoPtr &typeInfo, const std::string &listEntryName );
//
// python::list getTypedVarArrayByTypeName( ULONG64 addr, const std::string &typeName, ULONG number );
//
// python::list getTypedVarArrayByType( ULONG64 addr, const TypeInfoPtr &typeInfo, ULONG number );
//
// ULONG64 getSymbolSize( const std::string &symName );
//
// pyDia::GlobalScopePtr& getDia() {
// if (!m_dia)
// {
// m_dia = pyDia::GlobalScope::loadPdb( getPdbName() );
// if ( m_dia )
// {
// m_dia->setLoadAddress( m_base );
// }
// }
//
// return m_dia;
// }
//
// ULONG getCheckSum() const {
// return m_checkSum;
// }
//
// ULONG getTimeDataStamp() const {
// return m_timeDataStamp;
// }
//
// std::string print();
//
//private:
//
// void
// reloadSymbolsImpl();
//
//
// ULONG getRvaByName(const std::string &symName);
//
// BaseTypeVariant getValue() {
// return BaseTypeVariant(m_base);
// }
//
//
// std::string m_name;
// std::string m_imageName;
// ULONG64 m_base;
// ULONG m_size;
//
// pyDia::GlobalScopePtr m_dia;
//
// ULONG m_timeDataStamp;
// ULONG m_checkSum;
// SynSymbolsPtr m_synSymbols;
//};
//
/////////////////////////////////////////////////////////////////////////////////////
//
//}; // end pykd namespace

View File

@ -409,6 +409,10 @@
/> />
</FileConfiguration> </FileConfiguration>
</File> </File>
<File
RelativePath=".\typedvar.cpp"
>
</File>
<File <File
RelativePath=".\typeinfo.cpp" RelativePath=".\typeinfo.cpp"
> >
@ -417,6 +421,10 @@
RelativePath=".\udtutils.cpp" RelativePath=".\udtutils.cpp"
> >
</File> </File>
<File
RelativePath=".\vardata.cpp"
>
</File>
</Filter> </Filter>
<Filter <Filter
Name="Header Files" Name="Header Files"
@ -459,6 +467,10 @@
RelativePath=".\symengine.h" RelativePath=".\symengine.h"
> >
</File> </File>
<File
RelativePath=".\typedvar.h"
>
</File>
<File <File
RelativePath=".\typeinfo.h" RelativePath=".\typeinfo.h"
> >
@ -467,6 +479,10 @@
RelativePath=".\udtutils.h" RelativePath=".\udtutils.h"
> >
</File> </File>
<File
RelativePath=".\vardata.h"
>
</File>
</Filter> </Filter>
<Filter <Filter
Name="Resource Files" Name="Resource Files"

View File

@ -14,6 +14,7 @@
#include "dbgexcept.h" #include "dbgexcept.h"
#include "dbgmem.h" #include "dbgmem.h"
#include "typeinfo.h" #include "typeinfo.h"
#include "typedvar.h"
using namespace pykd; using namespace pykd;
@ -127,6 +128,20 @@ BOOST_PYTHON_MODULE( pykd )
// typed and vaiables // typed and vaiables
python::def( "sizeof", &TypeInfo::getSymbolSize, python::def( "sizeof", &TypeInfo::getSymbolSize,
"Return a size of the type or variable" ); "Return a size of the type or variable" );
python::def("typedVarList", &getTypedVarListByTypeName,
"Return a list of the typedVar class instances. Each item represents an item of the linked list in the target memory" );
python::def("typedVarList", &getTypedVarListByType,
"Return a list of the typedVar class instances. Each item represents an item of the linked list in the target memory" );
python::def("typedVarArray", &getTypedVarArrayByTypeName,
"Return a list of the typedVar class instances. Each item represents an item of the counted array in the target memory" );
python::def("typedVarArray", &getTypedVarArrayByType,
"Return a list of the typedVar class instances. Each item represents an item of the counted array in the target memory" );
python::def("containingRecord", &containingRecordByName,
"Return instance of the typedVar class. It's value are loaded from the target memory."
"The start address is calculated by the same method as the standard macro CONTAINING_RECORD does" );
python::def("containingRecord", &containingRecordByType,
"Return instance of the typedVar class. It's value are loaded from the target memory."
"The start address is calculated by the same method as the standard macro CONTAINING_RECORD does" );
python::class_<intBase>( "intBase", "intBase", python::no_init ) python::class_<intBase>( "intBase", "intBase", python::no_init )
.def( python::init<python::object&>() ) .def( python::init<python::object&>() )
@ -193,32 +208,23 @@ BOOST_PYTHON_MODULE( pykd )
"Return offset of the symbol" ) "Return offset of the symbol" )
.def("rva", &Module::getSymbolRva, .def("rva", &Module::getSymbolRva,
"Return rva of the symbol" ) "Return rva of the symbol" )
//.def( "sizeof", &Module::getSymbolSize, .def( "sizeof", &Module::getSymbolSize,
// "Return a size of the type or variable" ) "Return a size of the type or variable" )
.def("type", &Module::getTypeByName, .def("type", &Module::getTypeByName,
"Return typeInfo class by type name" ) "Return typeInfo class by type name" )
//.def("typedVar", &Module::getTypedVarByAddr, .def("typedVar", &Module::getTypedVarByAddr,
// "Return a typedVar class instance" ) "Return a typedVar class instance" )
//.def("typedVar",&Module::getTypedVarByName, .def("typedVar",&Module::getTypedVarByName,
// "Return a typedVar class instance" ) "Return a typedVar class instance" )
//.def("typedVar",&Module::getTypedVarByType, .def("typedVar",&Module::getTypedVarByTypeName,
// "Return a typedVar class instance" ) "Return a typedVar class instance" )
//.def("typedVar",&Module::getTypedVarByTypeName, .def("typedVarList", &Module::getTypedVarListByTypeName,
// "Return a typedVar class instance" ) "Return a list of the typedVar class instances. Each item represents an item of the linked list in the target memory" )
//.def("typedVarList", &Module::getTypedVarListByTypeName, .def("typedVarArray", &Module::getTypedVarArrayByTypeName,
// "Return a list of the typedVar class instances. Each item represents an item of the linked list in the target memory" ) "Return a list of the typedVar class instances. Each item represents an item of the counted array in the target memory" )
//.def("typedVarList", &Module::getTypedVarListByType, .def("containingRecord", &Module::containingRecordByName,
// "Return a list of the typedVar class instances. Each item represents an item of the linked list in the target memory" ) "Return instance of the typedVar class. It's value are loaded from the target memory."
//.def("typedVarArray", &Module::getTypedVarArrayByTypeName, "The start address is calculated by the same method as the standard macro CONTAINING_RECORD does" )
// "Return a list of the typedVar class instances. Each item represents an item of the counted array in the target memory" )
//.def("typedVarArray", &Module::getTypedVarArrayByType,
// "Return a list of the typedVar class instances. Each item represents an item of the counted array in the target memory" )
//.def("containingRecord", &Module::containingRecordByName,
// "Return instance of the typedVar class. It's value are loaded from the target memory."
// "The start address is calculated by the same method as the standard macro CONTAINING_RECORD does" )
//.def("containingRecord", &Module::containingRecordByType,
// "Return instance of the typedVar class. It's value are loaded from the target memory."
// "The start address is calculated by the same method as the standard macro CONTAINING_RECORD does" )
.def("checksum",&Module::getCheckSum, .def("checksum",&Module::getCheckSum,
"Return a image file checksum: IMAGE_OPTIONAL_HEADER.CheckSum" ) "Return a image file checksum: IMAGE_OPTIONAL_HEADER.CheckSum" )
.def("timestamp",&Module::getTimeDataStamp, .def("timestamp",&Module::getTimeDataStamp,
@ -243,6 +249,34 @@ BOOST_PYTHON_MODULE( pykd )
.def("__len__", &TypeInfo::getElementCount ) .def("__len__", &TypeInfo::getElementCount )
.def("__getitem__", &TypeInfo::getElementByIndex ); .def("__getitem__", &TypeInfo::getElementByIndex );
python::class_<TypedVar, TypedVarPtr, python::bases<intBase>, boost::noncopyable >("typedVar",
"Class of non-primitive type object, child class of typeClass. Data from target is copied into object instance", python::no_init )
.def("__init__", python::make_constructor(TypedVar::getTypedVarByName) )
.def("__init__", python::make_constructor(TypedVar::getTypedVarByTypeName) )
.def("__init__", python::make_constructor(TypedVar::getTypedVarByTypeInfo) )
.def("getAddress", &TypedVar::getAddress,
"Return virtual address" )
.def("sizeof", &TypedVar::getSize,
"Return size of a variable in the target memory" )
.def("fieldOffset", &TypedVar::getFieldOffsetByNameRecirsive,
"Return target field offset" )
.def("field", &TypedVar::getField,
"Return field of structure as an object attribute" )
.def( "dataKind", &TypedVar::getDataKind,
"Retrieves the variable classification of a data: DataIsXxx")
.def("deref", &TypedVar::deref,
"Return value by pointer" )
.def("type", &TypedVar::getType,
"Return typeInfo instance" )
.def("__getattr__", &TypedVar::getField,
"Return field of structure as an object attribute" )
.def( "__str__", &TypedVar::print )
.def("__len__", &TypedVar::getElementCount )
.def("__getitem__", &TypedVar::getElementByIndex )
.def("__getitem__", &TypedVar::getElementByIndexPtr );
// wrapper for standart python exceptions
python::register_exception_translator<PyException>( &PyException::exceptionTranslate );
pykd::exception<DbgException>( "BaseException", "Pykd base exception class" ); pykd::exception<DbgException>( "BaseException", "Pykd base exception class" );
pykd::exception<MemoryException,DbgException>( "MemoryException", "Target memory access exception class" ); pykd::exception<MemoryException,DbgException>( "MemoryException", "Target memory access exception class" );

View File

@ -110,7 +110,6 @@ class Symbol {
public: public:
virtual SymbolPtrList findChildren( ULONG symTag, const std::string &name = "", bool caseSensitive = FALSE ) = 0; virtual SymbolPtrList findChildren( ULONG symTag, const std::string &name = "", bool caseSensitive = FALSE ) = 0;
virtual ULONG getBaseType() = 0; virtual ULONG getBaseType() = 0;
virtual ULONG getBitPosition() = 0; virtual ULONG getBitPosition() = 0;
@ -140,7 +139,7 @@ public:
std::string getBasicTypeName( ULONG basicType ); std::string getBasicTypeName( ULONG basicType );
SymbolPtr loadSymbolFile(const std::string &filePath); SymbolPtr loadSymbolFile(const std::string &filePath, ULONGLONG loadBase = 0);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -3,50 +3,50 @@
#include <iomanip> #include <iomanip>
#include "typedvar.h" #include "typedvar.h"
#include "dbgclient.h" #include "module.h"
#include "dbgmem.h" #include "dbgmem.h"
namespace pykd { namespace pykd {
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
TypedVarPtr TypedVar::getTypedVar( IDebugClient4 *client, const TypeInfoPtr& typeInfo, VarDataPtr varData ) TypedVarPtr TypedVar::getTypedVar( const TypeInfoPtr& typeInfo, VarDataPtr varData )
{ {
TypedVarPtr tv; TypedVarPtr tv;
if ( typeInfo->isBasicType() ) if ( typeInfo->isBasicType() )
{ {
tv.reset( new BasicTypedVar( client, typeInfo, varData) ); tv.reset( new BasicTypedVar( typeInfo, varData) );
return tv; return tv;
} }
if ( typeInfo->isPointer() ) if ( typeInfo->isPointer() )
{ {
tv.reset( new PtrTypedVar( client, typeInfo, varData ) ); tv.reset( new PtrTypedVar( typeInfo, varData ) );
return tv; return tv;
} }
if ( typeInfo->isArray() ) if ( typeInfo->isArray() )
{ {
tv.reset( new ArrayTypedVar( client, typeInfo, varData ) ); tv.reset( new ArrayTypedVar( typeInfo, varData ) );
return tv; return tv;
} }
if ( typeInfo->isUserDefined() ) if ( typeInfo->isUserDefined() )
{ {
tv.reset( new UdtTypedVar( client, typeInfo, varData ) ); tv.reset( new UdtTypedVar( typeInfo, varData ) );
return tv; return tv;
} }
if ( typeInfo->isBitField() ) if ( typeInfo->isBitField() )
{ {
tv.reset( new BitFieldVar( client, typeInfo, varData ) ); tv.reset( new BitFieldVar( typeInfo, varData ) );
return tv; return tv;
} }
if ( typeInfo->isEnum() ) if ( typeInfo->isEnum() )
{ {
tv.reset( new EnumTypedVar( client, typeInfo, varData ) ); tv.reset( new EnumTypedVar( typeInfo, varData ) );
return tv; return tv;
} }
@ -59,23 +59,42 @@ TypedVarPtr TypedVar::getTypedVar( IDebugClient4 *client, const TypeInfoPtr& t
TypedVarPtr TypedVar::getTypedVarByName( const std::string &varName ) TypedVarPtr TypedVar::getTypedVarByName( const std::string &varName )
{ {
return g_dbgClient->getTypedVarByName( varName ); std::string moduleName;
} std::string symName;
TypedVarPtr TypedVar::getTypedVarByTypeName( const std::string &typeName, ULONG64 addr ) splitSymName( varName, moduleName, symName );
{
return g_dbgClient->getTypedVarByTypeName( typeName, addr );
}
TypedVarPtr TypedVar::getTypedVarByTypeInfo( const TypeInfoPtr &typeInfo, ULONG64 addr ) ModulePtr module = Module::loadModuleByName( moduleName );
{
return g_dbgClient->getTypedVarByTypeInfo( typeInfo, addr ); return module->getTypedVarByName( symName );
} }
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
TypedVar::TypedVar ( IDebugClient4 *client, const TypeInfoPtr& typeInfo, VarDataPtr varData ) : TypedVarPtr TypedVar::getTypedVarByTypeName( const std::string &typeName, ULONG64 addr )
DbgObject( client ), {
addr = addr64( addr );
std::string moduleName;
std::string symName;
splitSymName( typeName, moduleName, symName );
ModulePtr module = Module::loadModuleByName( moduleName );
return module->getTypedVarByTypeName( symName, addr );
}
///////////////////////////////////////////////////////////////////////////////////
TypedVarPtr TypedVar::getTypedVarByTypeInfo( const TypeInfoPtr &typeInfo, ULONG64 addr )
{
return getTypedVar( typeInfo, VarDataMemory::factory(addr) );
}
///////////////////////////////////////////////////////////////////////////////////
TypedVar::TypedVar ( const TypeInfoPtr& typeInfo, VarDataPtr varData ) :
m_typeInfo( typeInfo ), m_typeInfo( typeInfo ),
m_varData( varData ), m_varData( varData ),
m_dataKind( DataIsGlobal ) m_dataKind( DataIsGlobal )
@ -166,8 +185,8 @@ BaseTypeVariant PtrTypedVar::getValue()
TypedVarPtr PtrTypedVar::deref() TypedVarPtr PtrTypedVar::deref()
{ {
VarDataPtr varData = VarDataMemory::factory( m_dataSpaces, m_varData->readPtr() ); VarDataPtr varData = VarDataMemory::factory( m_varData->readPtr() );
return TypedVar::getTypedVar( m_client, m_typeInfo->deref(), varData ); return TypedVar::getTypedVar( m_typeInfo->deref(), varData );
} }
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
@ -220,7 +239,7 @@ python::object ArrayTypedVar::getElementByIndex( ULONG index )
TypeInfoPtr elementType = m_typeInfo->getElementType(); TypeInfoPtr elementType = m_typeInfo->getElementType();
return python::object( TypedVar::getTypedVar( m_client, elementType, m_varData->fork(elementType->getSize()*index) ) ); return python::object( TypedVar::getTypedVar( elementType, m_varData->fork(elementType->getSize()*index) ) );
} }
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
@ -235,7 +254,7 @@ UdtTypedVar::getField( const std::string &fieldName )
if ( fieldType->getStaticOffset() == 0 ) if ( fieldType->getStaticOffset() == 0 )
throw ImplementException( __FILE__, __LINE__, "Fix ME"); throw ImplementException( __FILE__, __LINE__, "Fix ME");
return TypedVar::getTypedVar( m_client, fieldType, VarDataMemory::factory(m_dataSpaces, fieldType->getStaticOffset() ) ); return TypedVar::getTypedVar( fieldType, VarDataMemory::factory(fieldType->getStaticOffset() ) );
} }
ULONG fieldOffset = 0; ULONG fieldOffset = 0;
@ -247,7 +266,7 @@ UdtTypedVar::getField( const std::string &fieldName )
fieldOffset += getVirtualBaseDisplacement( fieldType ); fieldOffset += getVirtualBaseDisplacement( fieldType );
} }
return TypedVar::getTypedVar( m_client, fieldType, m_varData->fork(fieldOffset) ); return TypedVar::getTypedVar( fieldType, m_varData->fork(fieldOffset) );
} }
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
@ -264,7 +283,7 @@ UdtTypedVar::getElementByIndex( ULONG index )
return python::make_tuple( return python::make_tuple(
m_typeInfo->getFieldNameByIndex(index), m_typeInfo->getFieldNameByIndex(index),
TypedVar::getTypedVar( m_client, fieldType, VarDataMemory::factory(m_dataSpaces, fieldType->getStaticOffset() ) ) ); TypedVar::getTypedVar(fieldType, VarDataMemory::factory(fieldType->getStaticOffset() ) ) );
} }
ULONG fieldOffset = m_typeInfo->getFieldOffsetByIndex(index); ULONG fieldOffset = m_typeInfo->getFieldOffsetByIndex(index);
@ -276,7 +295,7 @@ UdtTypedVar::getElementByIndex( ULONG index )
return python::make_tuple( return python::make_tuple(
m_typeInfo->getFieldNameByIndex(index), m_typeInfo->getFieldNameByIndex(index),
TypedVar::getTypedVar( m_client, fieldType, m_varData->fork(fieldOffset) ) ); TypedVar::getTypedVar( fieldType, m_varData->fork(fieldOffset) ) );
} }
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
@ -288,7 +307,7 @@ LONG UdtTypedVar::getVirtualBaseDisplacement( TypeInfoPtr& typeInfo )
ULONG64 vbtableOffset = m_varData->fork( virtualBasePtr )->readPtr(); ULONG64 vbtableOffset = m_varData->fork( virtualBasePtr )->readPtr();
VarDataPtr vbtable = VarDataMemory::factory(m_dataSpaces, vbtableOffset); VarDataPtr vbtable = VarDataMemory::factory(vbtableOffset);
LONG displacement = 0; LONG displacement = 0;
@ -313,7 +332,7 @@ std::string UdtTypedVar::print()
if ( fieldType->isStaticMember() ) if ( fieldType->isStaticMember() )
{ {
if ( fieldType->getStaticOffset() != 0 ) if ( fieldType->getStaticOffset() != 0 )
fieldVar = TypedVar::getTypedVar( m_client, fieldType, VarDataMemory::factory(m_dataSpaces, fieldType->getStaticOffset() ) ); fieldVar = TypedVar::getTypedVar( fieldType, VarDataMemory::factory( fieldType->getStaticOffset() ) );
sstr << " =" << std::right << std::setw(10) << std::setfill('0') << std::hex << fieldType->getStaticOffset(); sstr << " =" << std::right << std::setw(10) << std::setfill('0') << std::hex << fieldType->getStaticOffset();
sstr << " " << std::left << std::setw(18) << std::setfill(' ') << m_typeInfo->getFieldNameByIndex(i) << ':'; sstr << " " << std::left << std::setw(18) << std::setfill(' ') << m_typeInfo->getFieldNameByIndex(i) << ':';
@ -327,7 +346,7 @@ std::string UdtTypedVar::print()
fieldOffset += getVirtualBaseDisplacement( fieldType ); fieldOffset += getVirtualBaseDisplacement( fieldType );
} }
fieldVar = TypedVar::getTypedVar( m_client, fieldType, m_varData->fork(fieldOffset) ); fieldVar = TypedVar::getTypedVar( fieldType, m_varData->fork(fieldOffset) );
sstr << " +" << std::right << std::setw(4) << std::setfill('0') << std::hex << fieldOffset; sstr << " +" << std::right << std::setw(4) << std::setfill('0') << std::hex << fieldOffset;
sstr << " " << std::left << std::setw(24) << std::setfill(' ') << m_typeInfo->getFieldNameByIndex(i) << ':'; sstr << " " << std::left << std::setw(24) << std::setfill(' ') << m_typeInfo->getFieldNameByIndex(i) << ':';
} }
@ -446,4 +465,98 @@ std::string EnumTypedVar::printValue()
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
TypedVarPtr containingRecordByName( ULONG64 offset, const std::string &typeName, const std::string &fieldName )
{
std::string moduleName;
std::string symName;
splitSymName( typeName, moduleName, symName );
ModulePtr module = Module::loadModuleByName( moduleName );
return module->containingRecordByName( offset, symName, fieldName );
}
///////////////////////////////////////////////////////////////////////////////////
TypedVarPtr containingRecordByType( ULONG64 addr, const TypeInfoPtr &typeInfo, const std::string &fieldName )
{
addr = addr64(addr);
VarDataPtr varData = VarDataMemory::factory( addr - typeInfo->getFieldOffsetByNameRecirsive(fieldName) );
return TypedVar::getTypedVar( typeInfo, varData );
}
///////////////////////////////////////////////////////////////////////////////////
python::list getTypedVarListByTypeName( ULONG64 listHeadAddress, const std::string &typeName, const std::string &listEntryName )
{
std::string moduleName;
std::string symName;
splitSymName( typeName, moduleName, symName );
ModulePtr module = Module::loadModuleByName( moduleName );
return module->getTypedVarListByTypeName( listHeadAddress, symName, listEntryName );
}
///////////////////////////////////////////////////////////////////////////////////
python::list getTypedVarListByType( ULONG64 listHeadAddress, const TypeInfoPtr &typeInfo, const std::string &listEntryName )
{
python::list lst;
listHeadAddress = addr64( listHeadAddress );
ULONG64 entryAddress = 0;
TypeInfoPtr fieldTypeInfo = typeInfo->getField( listEntryName );
if ( fieldTypeInfo->getName() == ( typeInfo->getName() + "*" ) )
{
for( entryAddress = ptrPtr( listHeadAddress ); addr64(entryAddress) != listHeadAddress && entryAddress != NULL; entryAddress = ptrPtr( entryAddress + typeInfo->getFieldOffsetByNameRecirsive(listEntryName) ) )
lst.append( TypedVar::getTypedVarByTypeInfo( typeInfo, entryAddress ) );
}
else
{
for( entryAddress = ptrPtr( listHeadAddress ); addr64(entryAddress) != listHeadAddress && entryAddress != NULL; entryAddress = ptrPtr( entryAddress ) )
lst.append( containingRecordByType( entryAddress, typeInfo, listEntryName ) );
}
return lst;
}
///////////////////////////////////////////////////////////////////////////////////
python::list getTypedVarArrayByTypeName( ULONG64 addr, const std::string &typeName, ULONG number )
{
std::string moduleName;
std::string symName;
splitSymName( typeName, moduleName, symName );
ModulePtr module = Module::loadModuleByName( moduleName );
return module->getTypedVarArrayByTypeName( addr, symName, number );
}
///////////////////////////////////////////////////////////////////////////////////
python::list getTypedVarArrayByType( ULONG64 offset, const TypeInfoPtr &typeInfo, ULONG number )
{
offset = addr64(offset);
python::list lst;
for( ULONG i = 0; i < number; ++i )
lst.append( TypedVar::getTypedVarByTypeInfo( typeInfo, offset + i * typeInfo->getSize() ) );
return lst;
}
///////////////////////////////////////////////////////////////////////////////////
} // end pykd namespace } // end pykd namespace

View File

@ -2,7 +2,6 @@
#include "typeinfo.h" #include "typeinfo.h"
#include "intbase.h" #include "intbase.h"
#include "dbgobj.h"
#include "dbgexcept.h" #include "dbgexcept.h"
#include "vardata.h" #include "vardata.h"
@ -15,11 +14,11 @@ typedef boost::shared_ptr<TypedVar> TypedVarPtr;
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
class TypedVar : public intBase, protected DbgObject { class TypedVar : public intBase {
public: public:
static TypedVarPtr getTypedVar( IDebugClient4 *client, const TypeInfoPtr& typeInfo, VarDataPtr varData ); static TypedVarPtr getTypedVar( const TypeInfoPtr& typeInfo, VarDataPtr varData );
static TypedVarPtr getTypedVarByName( const std::string &varName ); static TypedVarPtr getTypedVarByName( const std::string &varName );
@ -86,7 +85,7 @@ public:
protected: protected:
TypedVar ( IDebugClient4 *client, const TypeInfoPtr& typeInfo, VarDataPtr varData ); TypedVar ( const TypeInfoPtr& typeInfo, VarDataPtr varData );
TypeInfoPtr m_typeInfo; TypeInfoPtr m_typeInfo;
@ -104,11 +103,8 @@ class BasicTypedVar : public TypedVar {
public: public:
BasicTypedVar ( IDebugClient4 *client, const TypeInfoPtr& typeInfo, VarDataPtr varData ) BasicTypedVar ( const TypeInfoPtr& typeInfo, VarDataPtr varData ) : TypedVar(typeInfo, varData)
: TypedVar(client, typeInfo, varData) {}
{
}
virtual std::string print(); virtual std::string print();
@ -124,10 +120,8 @@ class PtrTypedVar : public TypedVar {
public: public:
PtrTypedVar ( IDebugClient4 *client, const TypeInfoPtr& typeInfo, VarDataPtr varData ) PtrTypedVar ( const TypeInfoPtr& typeInfo, VarDataPtr varData ) : TypedVar(typeInfo, varData)
: TypedVar(client, typeInfo, varData) {}
{
}
virtual std::string print(); virtual std::string print();
@ -145,10 +139,8 @@ class ArrayTypedVar: public TypedVar {
public: public:
ArrayTypedVar ( IDebugClient4 *client, const TypeInfoPtr& typeInfo, VarDataPtr varData ) ArrayTypedVar ( const TypeInfoPtr& typeInfo, VarDataPtr varData ) : TypedVar(typeInfo, varData)
: TypedVar(client, typeInfo, varData) {}
{
}
virtual ULONG getElementCount() { virtual ULONG getElementCount() {
return m_typeInfo->getCount(); return m_typeInfo->getCount();
@ -167,10 +159,8 @@ class UdtTypedVar : public TypedVar {
public: public:
UdtTypedVar( IDebugClient4 *client, const TypeInfoPtr& typeInfo, VarDataPtr varData ) UdtTypedVar( const TypeInfoPtr& typeInfo, VarDataPtr varData ) : TypedVar(typeInfo, varData)
: TypedVar(client, typeInfo, varData) {}
{
}
protected: protected:
@ -195,10 +185,8 @@ class BitFieldVar: public TypedVar {
public: public:
BitFieldVar( IDebugClient4 *client, const TypeInfoPtr& typeInfo, VarDataPtr varData ) BitFieldVar( const TypeInfoPtr& typeInfo, VarDataPtr varData ) : TypedVar( typeInfo, varData)
: TypedVar(client, typeInfo, varData) {}
{
}
virtual std::string printValue(); virtual std::string printValue();
@ -210,10 +198,8 @@ public:
class EnumTypedVar : public TypedVar { class EnumTypedVar : public TypedVar {
public: public:
EnumTypedVar( IDebugClient4 *client, const TypeInfoPtr& typeInfo, VarDataPtr varData ) EnumTypedVar( const TypeInfoPtr& typeInfo, VarDataPtr varData ) : TypedVar( typeInfo, varData)
: TypedVar(client, typeInfo, varData) {}
{
}
virtual std::string print(); virtual std::string print();
@ -224,5 +210,18 @@ public:
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
TypedVarPtr containingRecordByName( ULONG64 addr, const std::string &typeName, const std::string &fieldName );
TypedVarPtr containingRecordByType( ULONG64 addr, const TypeInfoPtr &typeInfo, const std::string &fieldName );
python::list getTypedVarListByTypeName( ULONG64 listHeadAddres, const std::string &typeName, const std::string &listEntryName );
python::list getTypedVarListByType( ULONG64 listHeadAddres, const TypeInfoPtr &typeInfo, const std::string &listEntryName );
python::list getTypedVarArrayByTypeName( ULONG64 addr, const std::string &typeName, ULONG number );
python::list getTypedVarArrayByType( ULONG64 addr, const TypeInfoPtr &typeInfo, ULONG number );
///////////////////////////////////////////////////////////////////////////////////
} // namespace pykd } // namespace pykd

View File

@ -515,4 +515,8 @@ private:
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
void splitSymName( const std::string &fullName, std::string &moduleName, std::string &symbolName );
///////////////////////////////////////////////////////////////////////////////////
}; // namespace pykd }; // namespace pykd

View File

@ -5,7 +5,7 @@
#include "stdafx.h" #include "stdafx.h"
#include "vardata.h" #include "vardata.h"
#include "dbgmem.h" #include "dbgengine.h"
#include "dbgexcept.h" #include "dbgexcept.h"
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -14,9 +14,8 @@ namespace pykd {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
VarDataMemory::VarDataMemory(CComPtr< IDebugDataSpaces4 > dataSpaces, ULONG64 addr) VarDataMemory::VarDataMemory(ULONG64 addr) :
: m_dataSpaces(dataSpaces) m_addr(addr)
, m_addr(addr)
{ {
} }
@ -40,30 +39,27 @@ ULONG64 VarDataMemory::getAddr() const
VarDataPtr VarDataMemory::fork(ULONG offset) const VarDataPtr VarDataMemory::fork(ULONG offset) const
{ {
return VarDataPtr( new VarDataMemory(m_dataSpaces, m_addr + offset) ); return VarDataPtr( new VarDataMemory(m_addr + offset) );
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void VarDataMemory::read(PVOID buffer, ULONG length, ULONG offset /*= 0*/) const void VarDataMemory::read(PVOID buffer, ULONG length, ULONG offset /*= 0*/) const
{ {
readMemory(m_dataSpaces, m_addr + offset, buffer, length); readMemory( m_addr + offset, buffer, length);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
ULONG64 VarDataMemory::readPtr() const ULONG64 VarDataMemory::readPtr() const
{ {
ULONG64 ptrValue = 0; return ptrPtr( m_addr );
readMemoryPtr(m_dataSpaces, m_addr, &ptrValue);
return ptrValue;
} }
//////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
VarDataConst::VarDataConst(CComPtr< IDebugControl4 > control, pyDia::SymbolPtr symData) VarDataConst::VarDataConst( SymbolPtr &symData) :
: m_control(control) m_fieldOffset(0)
, m_fieldOffset(0)
, m_dataBuff( new std::vector< UCHAR >((size_t)symData->getType()->getSize(), 0) ) , m_dataBuff( new std::vector< UCHAR >((size_t)symData->getType()->getSize(), 0) )
{ {
VARIANT vtValue = {0}; VARIANT vtValue = {0};
@ -147,7 +143,7 @@ void VarDataConst::read(PVOID buffer, ULONG length, ULONG offset /*= 0*/) const
ULONG64 VarDataConst::readPtr() const ULONG64 VarDataConst::readPtr() const
{ {
ULONG64 val = 0; ULONG64 val = 0;
const ULONG length = (S_OK == m_control->IsPointer64Bit()) ? 8 : 4; const ULONG length = ptrSize();
if (length > m_dataBuff->size()) if (length > m_dataBuff->size())
throw DbgException("Internal error in " __FUNCTION__); throw DbgException("Internal error in " __FUNCTION__);
RtlCopyMemory(&val, &m_dataBuff->at(0), length); RtlCopyMemory(&val, &m_dataBuff->at(0), length);
@ -156,9 +152,8 @@ ULONG64 VarDataConst::readPtr() const
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
VarDataConst::VarDataConst(const VarDataConst &from, ULONG fieldOffset) VarDataConst::VarDataConst(const VarDataConst &from, ULONG fieldOffset) :
: m_control(from.m_control) m_fieldOffset(from.m_fieldOffset + fieldOffset)
, m_fieldOffset(from.m_fieldOffset + fieldOffset)
, m_dataBuff(from.m_dataBuff) , m_dataBuff(from.m_dataBuff)
{ {
} }

View File

@ -6,75 +6,73 @@
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#include <array> //#include <array>
#include <boost\smart_ptr\shared_ptr.hpp> #include "symengine.h"
#include "diawrapper.h"
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
namespace pykd { namespace pykd {
// pointer to variable data access interface class VarData;
interface IVarData; typedef boost::shared_ptr< VarData > VarDataPtr;
typedef boost::shared_ptr< IVarData > VarDataPtr;
// access to variable data interface // access to variable data interface
interface IVarData class VarData
{ {
virtual ~IVarData() {} public:
virtual ~VarData() {}
virtual std::string asString() const = 0; virtual std::string asString() const = 0;
virtual ULONG64 getAddr() const = 0; virtual ULONG64 getAddr() const = 0;
virtual VarDataPtr fork(ULONG offset) const = 0; virtual VarDataPtr fork(ULONG offset) const = 0;
virtual void read(PVOID buffer, ULONG length, ULONG offset = 0) const = 0; virtual void read(PVOID buffer, ULONG length, ULONG offset = 0) const = 0;
virtual ULONG64 readPtr() const = 0; virtual ULONG64 readPtr() const = 0;
}; };
// variable in memory // variable in memory
class VarDataMemory : public IVarData class VarDataMemory : public VarData
{ {
public: public:
// IVarData implementation // IVarData implementation
virtual std::string asString() const override; virtual std::string asString() const;
virtual ULONG64 getAddr() const override; virtual ULONG64 getAddr() const;
virtual VarDataPtr fork(ULONG offset) const override; virtual VarDataPtr fork(ULONG offset) const;
virtual void read(PVOID buffer, ULONG length, ULONG offset = 0) const override; virtual void read(PVOID buffer, ULONG length, ULONG offset = 0) const;
virtual ULONG64 readPtr() const override; virtual ULONG64 readPtr() const;
static VarDataPtr factory(CComPtr< IDebugDataSpaces4 > dataSpaces, ULONG64 addr) { static VarDataPtr factory(ULONG64 addr) {
return VarDataPtr( new VarDataMemory(dataSpaces, addr) ); return VarDataPtr( new VarDataMemory(addr) );
} }
protected: protected:
VarDataMemory(CComPtr< IDebugDataSpaces4 > dataSpaces, ULONG64 addr); VarDataMemory(ULONG64 addr);
private: private:
CComPtr< IDebugDataSpaces4 > m_dataSpaces;
ULONG64 m_addr; ULONG64 m_addr;
}; };
// constant variable // constant variable
class VarDataConst : public IVarData class VarDataConst : public VarData
{ {
public: public:
// IVarData implementation // IVarData implementation
virtual std::string asString() const override; virtual std::string asString() const;
virtual ULONG64 getAddr() const override; virtual ULONG64 getAddr() const;
virtual VarDataPtr fork(ULONG offset) const override; virtual VarDataPtr fork(ULONG offset) const;
virtual void read(PVOID buffer, ULONG length, ULONG offset = 0) const override; virtual void read(PVOID buffer, ULONG length, ULONG offset = 0) const;
virtual ULONG64 readPtr() const override; virtual ULONG64 readPtr() const;
static VarDataPtr factory(CComPtr< IDebugControl4 > control, pyDia::SymbolPtr symData) { static VarDataPtr factory(SymbolPtr &symData) {
return VarDataPtr( new VarDataConst(control, symData) ); return VarDataPtr( new VarDataConst(symData) );
} }
protected: protected:
VarDataConst(CComPtr< IDebugControl4 > control, pyDia::SymbolPtr symData); VarDataConst(SymbolPtr &symData);
VarDataConst(const VarDataConst &from, ULONG fieldOffset); VarDataConst(const VarDataConst &from, ULONG fieldOffset);
template<typename T> template<typename T>
@ -84,7 +82,6 @@ protected:
} }
private: private:
CComPtr< IDebugControl4 > m_control;
ULONG m_fieldOffset; ULONG m_fieldOffset;
boost::shared_ptr< std::vector<UCHAR> > m_dataBuff; boost::shared_ptr< std::vector<UCHAR> > m_dataBuff;

View File

@ -318,6 +318,34 @@ ULONG ptrSize()
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
std::string getSymbolByOffset( ULONG64 offset )
{
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
HRESULT hres;
char nameBuf[0x100];
hres =
g_dbgEng->symbols->GetNameByOffset(
offset,
nameBuf,
sizeof(nameBuf),
NULL,
NULL );
std::string fullName( nameBuf );
size_t symPos = fullName.find ( '!' ) + 1;
std::string symbolName;
symbolName.assign( fullName, symPos, fullName.length() - symPos );
return symbolName;
}
///////////////////////////////////////////////////////////////////////////////////
}; };

View File

@ -17,7 +17,7 @@ import intbase
import memtest import memtest
import moduletest import moduletest
import typeinfo import typeinfo
import typedvar
def getTestSuite( singleName = "" ): def getTestSuite( singleName = "" ):
if singleName == "": if singleName == "":
@ -28,6 +28,7 @@ def getTestSuite( singleName = "" ):
unittest.TestLoader().loadTestsFromTestCase( moduletest.ModuleTest ), unittest.TestLoader().loadTestsFromTestCase( moduletest.ModuleTest ),
unittest.TestLoader().loadTestsFromTestCase( memtest.MemoryTest ), unittest.TestLoader().loadTestsFromTestCase( memtest.MemoryTest ),
unittest.TestLoader().loadTestsFromTestCase( typeinfo.TypeInfoTest ), unittest.TestLoader().loadTestsFromTestCase( typeinfo.TypeInfoTest ),
unittest.TestLoader().loadTestsFromTestCase( typedvar.TypedVarTest ),
] ) ] )
else: else:
return unittest.TestSuite( unittest.TestLoader().loadTestsFromName( singleName ) ) return unittest.TestSuite( unittest.TestLoader().loadTestsFromName( singleName ) )
@ -46,6 +47,8 @@ if __name__ == "__main__":
pykd.go() pykd.go()
unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run(getTestSuite( "typedvar.TypedVarTest.testPrint" ) )
unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run( getTestSuite() ) unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run( getTestSuite() )
pykd.killProcess( processId ) pykd.killProcess( processId )

View File

@ -120,7 +120,7 @@ class TypedVarTest( unittest.TestCase ):
self.assertEqual( 3, len( tvl ) ) self.assertEqual( 3, len( tvl ) )
self.assertEqual( [1,2,3], [ tv.num for tv in tvl ] ) self.assertEqual( [1,2,3], [ tv.num for tv in tvl ] )
tvl = target.module.typedVarList( target.module.g_listHead, target.module.type("listStruct"), "listEntry" ) tvl = pykd.typedVarList( target.module.g_listHead, target.module.type("listStruct"), "listEntry" )
self.assertEqual( 3, len( tvl ) ) self.assertEqual( 3, len( tvl ) )
self.assertEqual( [1,2,3], [ tv.num for tv in tvl ] ) self.assertEqual( [1,2,3], [ tv.num for tv in tvl ] )
@ -128,11 +128,11 @@ class TypedVarTest( unittest.TestCase ):
self.assertEqual( 3, len( tvl ) ) self.assertEqual( 3, len( tvl ) )
self.assertEqual( [100,200,300], [ tv.num for tv in tvl ] ) self.assertEqual( [100,200,300], [ tv.num for tv in tvl ] )
tvl = target.module.typedVarList( target.module.g_listHead1, target.module.type("listStruct1"), "next" ) tvl = pykd.typedVarList( target.module.g_listHead1, target.module.type("listStruct1"), "next" )
self.assertEqual( 3, len( tvl ) ) self.assertEqual( 3, len( tvl ) )
self.assertEqual( [100,200,300], [ tv.num for tv in tvl ] ) self.assertEqual( [100,200,300], [ tv.num for tv in tvl ] )
tvl = target.module.typedVarList( target.module.g_childListHead, target.module.type("ChildEntryTest"), "m_next" ) tvl = pykd.typedVarList( target.module.g_childListHead, target.module.type("ChildEntryTest"), "m_next" )
self.assertEqual( 3, len( tvl ) ) self.assertEqual( 3, len( tvl ) )
self.assertEqual( [1000,2000,3000], [ tv.m_someBaseFiled2 for tv in tvl ] ) self.assertEqual( [1000,2000,3000], [ tv.m_someBaseFiled2 for tv in tvl ] )
self.assertEqual( [1001,2001,3001], [ tv.m_childFiled1 for tv in tvl ] ) self.assertEqual( [1001,2001,3001], [ tv.m_childFiled1 for tv in tvl ] )
@ -147,7 +147,7 @@ class TypedVarTest( unittest.TestCase ):
self.assertEqual( 500, tvl[0].m_field1 ) self.assertEqual( 500, tvl[0].m_field1 )
self.assertEqual( False, tvl[1].m_field2 ) self.assertEqual( False, tvl[1].m_field2 )
tvl = target.module.typedVarArray( target.module.g_testArray, target.module.type("structTest"), 2 ) tvl = pykd.typedVarArray( target.module.g_testArray, target.module.type("structTest"), 2 )
self.assertEqual( 2, len( tvl ) ) self.assertEqual( 2, len( tvl ) )
self.assertEqual( 1, tvl[0].m_field3 ) self.assertEqual( 1, tvl[0].m_field3 )
self.assertEqual( 0, tvl[1].m_field4 ) self.assertEqual( 0, tvl[1].m_field4 )