mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-20 03:23:23 +08:00
[+] offset into TypeInfo (for fields)
[+] method TypeInfo::build() for recursive typeClass building [+] virtual method printSelf() for address value for typedVarClass [~] remove trailing blanks, tabs replaced by spaces git-svn-id: https://pykd.svn.codeplex.com/svn@61693 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
parent
5879200d07
commit
dfbbc434d3
@ -153,6 +153,7 @@ BOOST_PYTHON_MODULE( pykd )
|
|||||||
boost::python::def( "setProcessorMode", &setProcessorMode );
|
boost::python::def( "setProcessorMode", &setProcessorMode );
|
||||||
boost::python::class_<typeClass, boost::shared_ptr<typeClass> >( "typeClass" )
|
boost::python::class_<typeClass, boost::shared_ptr<typeClass> >( "typeClass" )
|
||||||
.def("sizeof", &typeClass::size )
|
.def("sizeof", &typeClass::size )
|
||||||
|
.def("offset", &typeClass::getOffset )
|
||||||
.def("__str__", &typeClass::print);
|
.def("__str__", &typeClass::print);
|
||||||
boost::python::class_<typedVarClass, boost::python::bases<typeClass>, boost::shared_ptr<typedVarClass> >( "typedVarClass" )
|
boost::python::class_<typedVarClass, boost::python::bases<typeClass>, boost::shared_ptr<typedVarClass> >( "typedVarClass" )
|
||||||
.def("getAddress", &typedVarClass::getAddress );
|
.def("getAddress", &typedVarClass::getAddress );
|
||||||
@ -168,7 +169,7 @@ BOOST_PYTHON_MODULE( pykd )
|
|||||||
"ext",
|
"ext",
|
||||||
"windbg extension",
|
"windbg extension",
|
||||||
boost::python::init<const char*>( boost::python::args("path"), "__init__ dbgExtensionClass" ) )
|
boost::python::init<const char*>( boost::python::args("path"), "__init__ dbgExtensionClass" ) )
|
||||||
.def("call", &dbgExtensionClass::call );
|
.def("call", &dbgExtensionClass::call );
|
||||||
boost::python::class_<dbgStackFrameClass>( "dbgStackFrameClass", "dbgStackFrameClass" )
|
boost::python::class_<dbgStackFrameClass>( "dbgStackFrameClass", "dbgStackFrameClass" )
|
||||||
.def_readonly( "instructionOffset", &dbgStackFrameClass::InstructionOffset )
|
.def_readonly( "instructionOffset", &dbgStackFrameClass::InstructionOffset )
|
||||||
.def_readonly( "returnOffset", &dbgStackFrameClass::ReturnOffset )
|
.def_readonly( "returnOffset", &dbgStackFrameClass::ReturnOffset )
|
||||||
|
@ -534,10 +534,10 @@ isOffsetValid( ULONG64 addr )
|
|||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
// íóæíî ïîäàâèòü âîçìîæíûé âûâîä â êîíñîëü îá îòñóòñòâóþùåé ñòðàíèöå ïàìÿòè
|
// íóæíî ïîäàâèòü âîçìîæíûé âûâîä â êîíñîëü îá îòñóòñòâóþùåé ñòðàíèöå ïàìÿòè
|
||||||
OutputReader outputReader( dbgExt->client );
|
OutputReader outputReader( dbgExt->client );
|
||||||
|
|
||||||
ULONG offsetInfo;
|
ULONG offsetInfo;
|
||||||
|
|
||||||
hres =
|
hres =
|
||||||
@ -548,23 +548,23 @@ isOffsetValid( ULONG64 addr )
|
|||||||
&offsetInfo,
|
&offsetInfo,
|
||||||
sizeof( offsetInfo ),
|
sizeof( offsetInfo ),
|
||||||
NULL );
|
NULL );
|
||||||
|
|
||||||
if ( FAILED( hres ) )
|
if ( FAILED( hres ) )
|
||||||
throw DbgException( "IDebugDataSpace4::GetOffsetInformation failed" );
|
throw DbgException( "IDebugDataSpace4::GetOffsetInformation failed" );
|
||||||
|
|
||||||
return offsetInfo != DEBUG_VSOURCE_INVALID;
|
return offsetInfo != DEBUG_VSOURCE_INVALID;
|
||||||
|
|
||||||
}
|
}
|
||||||
catch( std::exception &e )
|
catch( std::exception &e )
|
||||||
{
|
{
|
||||||
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd error: %s\n", e.what() );
|
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd error: %s\n", e.what() );
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" );
|
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" );
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
272
pykd/dbgtype.cpp
272
pykd/dbgtype.cpp
@ -19,35 +19,34 @@ loadTypedVar( const std::string &moduleName, const std::string &typeName, ULONG6
|
|||||||
return TypeInfo::get( moduleName, typeName ).load( address );
|
return TypeInfo::get( moduleName, typeName ).load( address );
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ULONG
|
ULONG
|
||||||
sizeofType( const std::string &moduleName, const std::string &typeName )
|
sizeofType( const std::string &moduleName, const std::string &typeName )
|
||||||
{
|
{
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
ULONG typeSize = ~0;
|
ULONG typeSize = ~0;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
ULONG64 moduleBase;
|
ULONG64 moduleBase;
|
||||||
|
|
||||||
hres = dbgExt->symbols->GetModuleByModuleName( moduleName.c_str(), 0, NULL, &moduleBase );
|
hres = dbgExt->symbols->GetModuleByModuleName( moduleName.c_str(), 0, NULL, &moduleBase );
|
||||||
if ( FAILED( hres ) )
|
if ( FAILED( hres ) )
|
||||||
throw DbgException( "IDebugSymbol::GetModuleByModuleName failed" );
|
throw DbgException( "IDebugSymbol::GetModuleByModuleName failed" );
|
||||||
|
|
||||||
typeSize = (ULONG)TypeInfo::get( moduleName, typeName ).size();
|
typeSize = (ULONG)TypeInfo::get( moduleName, typeName ).size();
|
||||||
}
|
}
|
||||||
|
catch( std::exception &e )
|
||||||
catch( std::exception &e )
|
{
|
||||||
{
|
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd error: %s\n", e.what() );
|
||||||
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd error: %s\n", e.what() );
|
}
|
||||||
}
|
catch(...)
|
||||||
catch(...)
|
{
|
||||||
{
|
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" );
|
||||||
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" );
|
}
|
||||||
}
|
|
||||||
|
return typeSize;
|
||||||
return typeSize;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -55,38 +54,37 @@ sizeofType( const std::string &moduleName, const std::string &typeName )
|
|||||||
boost::python::object
|
boost::python::object
|
||||||
containingRecord( ULONG64 address, const std::string &moduleName, const std::string &typeName, const std::string &fieldName )
|
containingRecord( ULONG64 address, const std::string &moduleName, const std::string &typeName, const std::string &fieldName )
|
||||||
{
|
{
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
ULONG64 moduleBase;
|
ULONG64 moduleBase;
|
||||||
|
|
||||||
hres = dbgExt->symbols->GetModuleByModuleName( moduleName.c_str(), 0, NULL, &moduleBase );
|
hres = dbgExt->symbols->GetModuleByModuleName( moduleName.c_str(), 0, NULL, &moduleBase );
|
||||||
if ( FAILED( hres ) )
|
if ( FAILED( hres ) )
|
||||||
throw DbgException( "IDebugSymbol::GetModuleByModuleName failed" );
|
throw DbgException( "IDebugSymbol::GetModuleByModuleName failed" );
|
||||||
|
|
||||||
ULONG typeId;
|
ULONG typeId;
|
||||||
hres = dbgExt->symbols->GetTypeId( moduleBase, typeName.c_str(), &typeId );
|
hres = dbgExt->symbols->GetTypeId( moduleBase, typeName.c_str(), &typeId );
|
||||||
if ( FAILED( hres ) )
|
if ( FAILED( hres ) )
|
||||||
throw DbgException( "IDebugSymbol::GetTypeId failed" );
|
throw DbgException( "IDebugSymbol::GetTypeId failed" );
|
||||||
|
|
||||||
ULONG fieldTypeId;
|
ULONG fieldTypeId;
|
||||||
ULONG fieldOffset;
|
ULONG fieldOffset;
|
||||||
hres = dbgExt->symbols3->GetFieldTypeAndOffset( moduleBase, typeId, fieldName.c_str(), &fieldTypeId, &fieldOffset );
|
hres = dbgExt->symbols3->GetFieldTypeAndOffset( moduleBase, typeId, fieldName.c_str(), &fieldTypeId, &fieldOffset );
|
||||||
|
|
||||||
return TypeInfo::get( moduleName, typeName ).load( address - fieldOffset );
|
return TypeInfo::get( moduleName, typeName ).load( address - fieldOffset );
|
||||||
}
|
}
|
||||||
|
catch( std::exception &e )
|
||||||
catch( std::exception &e )
|
{
|
||||||
{
|
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd error: %s\n", e.what() );
|
||||||
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd error: %s\n", e.what() );
|
}
|
||||||
}
|
catch(...)
|
||||||
catch(...)
|
{
|
||||||
{
|
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" );
|
||||||
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" );
|
}
|
||||||
}
|
|
||||||
|
return boost::python::object();
|
||||||
return boost::python::object();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -96,13 +94,7 @@ getTypeClass( const std::string &moduleName, const std::string &typeName )
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
boost::shared_ptr<typeClass> ptr(
|
return TypeInfo::get( moduleName, typeName ).build();
|
||||||
new typeClass( TypeInfo::get( moduleName, typeName ))
|
|
||||||
);
|
|
||||||
boost::python::object var( ptr );
|
|
||||||
ptr->setPyObj(var);
|
|
||||||
|
|
||||||
return var;
|
|
||||||
}
|
}
|
||||||
catch( std::exception &e )
|
catch( std::exception &e )
|
||||||
{
|
{
|
||||||
@ -232,14 +224,14 @@ TypeInfo::TypeInfoMap TypeInfo::g_typeInfoCache;
|
|||||||
|
|
||||||
const TypeInfo&
|
const TypeInfo&
|
||||||
TypeInfo::get( const std::string &moduleName, const std::string &typeName )
|
TypeInfo::get( const std::string &moduleName, const std::string &typeName )
|
||||||
{
|
{
|
||||||
TypeInfoMap::iterator findIt = g_typeInfoCache.find( TypeName( moduleName, typeName ) );
|
TypeInfoMap::iterator findIt = g_typeInfoCache.find( TypeName( moduleName, typeName ) );
|
||||||
|
|
||||||
if ( findIt != g_typeInfoCache.end() )
|
if ( findIt != g_typeInfoCache.end() )
|
||||||
return findIt->second;
|
return findIt->second;
|
||||||
|
|
||||||
TypeInfo typeInfo( moduleName, typeName );
|
TypeInfo typeInfo( moduleName, typeName );
|
||||||
|
|
||||||
return g_typeInfoCache.insert( std::make_pair( TypeName( moduleName, typeName ), typeInfo) ).first->second;
|
return g_typeInfoCache.insert( std::make_pair( TypeName( moduleName, typeName ), typeInfo) ).first->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,41 +256,41 @@ TypeInfo::setupBaseType()
|
|||||||
TypeInfo::TypeInfo( const std::string &moduleName, const std::string &typeName )
|
TypeInfo::TypeInfo( const std::string &moduleName, const std::string &typeName )
|
||||||
{
|
{
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
m_typeName = typeName;
|
m_typeName = typeName;
|
||||||
m_size = 0;
|
m_size = 0;
|
||||||
m_baseType = false;
|
m_baseType = false;
|
||||||
m_pointer = false;
|
m_pointer = false;
|
||||||
|
m_offset = 0;
|
||||||
try {
|
try {
|
||||||
|
|
||||||
if ( typeName.find("*") < typeName.size() )
|
if ( typeName.find("*") < typeName.size() )
|
||||||
{
|
{
|
||||||
m_pointer = true;
|
m_pointer = true;
|
||||||
m_size = ptrSize();
|
m_size = ptrSize();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_baseType = isBaseType( typeName );
|
m_baseType = isBaseType( typeName );
|
||||||
if ( m_baseType )
|
if ( m_baseType )
|
||||||
{
|
{
|
||||||
setupBaseType();
|
setupBaseType();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG64 moduleBase = 0;
|
ULONG64 moduleBase = 0;
|
||||||
hres = dbgExt->symbols->GetModuleByModuleName( moduleName.c_str(), 0, NULL, &moduleBase );
|
hres = dbgExt->symbols->GetModuleByModuleName( moduleName.c_str(), 0, NULL, &moduleBase );
|
||||||
if ( FAILED( hres ) )
|
if ( FAILED( hres ) )
|
||||||
throw DbgException( "IDebugSymbol::GetModuleByModuleName failed" );
|
throw DbgException( "IDebugSymbol::GetModuleByModuleName failed" );
|
||||||
|
|
||||||
ULONG typeId = 0;
|
ULONG typeId = 0;
|
||||||
hres = dbgExt->symbols->GetTypeId( moduleBase, m_typeName.c_str(), &typeId );
|
hres = dbgExt->symbols->GetTypeId( moduleBase, m_typeName.c_str(), &typeId );
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException( "IDebugSymbol::GetTypeId failed" );
|
|
||||||
|
|
||||||
hres = dbgExt->symbols->GetTypeSize( moduleBase, typeId, &m_size );
|
|
||||||
if ( FAILED( hres ) )
|
if ( FAILED( hres ) )
|
||||||
throw DbgException( "IDebugSymbol::GetTypeSize failed" );
|
throw DbgException( "IDebugSymbol::GetTypeId failed" );
|
||||||
|
|
||||||
|
hres = dbgExt->symbols->GetTypeSize( moduleBase, typeId, &m_size );
|
||||||
|
if ( FAILED( hres ) )
|
||||||
|
throw DbgException( "IDebugSymbol::GetTypeSize failed" );
|
||||||
|
|
||||||
for ( ULONG i = 0; ; ++i )
|
for ( ULONG i = 0; ; ++i )
|
||||||
{
|
{
|
||||||
@ -311,41 +303,76 @@ TypeInfo::TypeInfo( const std::string &moduleName, const std::string &typeName
|
|||||||
ULONG fieldTypeId;
|
ULONG fieldTypeId;
|
||||||
ULONG fieldOffset;
|
ULONG fieldOffset;
|
||||||
hres = dbgExt->symbols3->GetFieldTypeAndOffset( moduleBase, typeId, fieldName, &fieldTypeId, &fieldOffset );
|
hres = dbgExt->symbols3->GetFieldTypeAndOffset( moduleBase, typeId, fieldName, &fieldTypeId, &fieldOffset );
|
||||||
|
|
||||||
if ( FAILED( hres ) )
|
if ( FAILED( hres ) )
|
||||||
throw DbgException( "IDebugSymbol3::GetFieldTypeAndOffset failed" );
|
throw DbgException( "IDebugSymbol3::GetFieldTypeAndOffset failed" );
|
||||||
|
|
||||||
ULONG fieldSize;
|
ULONG fieldSize;
|
||||||
hres = dbgExt->symbols->GetTypeSize( moduleBase, fieldTypeId, &fieldSize );
|
hres = dbgExt->symbols->GetTypeSize( moduleBase, fieldTypeId, &fieldSize );
|
||||||
if ( FAILED( hres ) )
|
if ( FAILED( hres ) )
|
||||||
throw DbgException( "IDebugSymbol::GetTypeSize failed" );
|
throw DbgException( "IDebugSymbol::GetTypeSize failed" );
|
||||||
|
|
||||||
char fieldTypeName[100];
|
char fieldTypeName[100];
|
||||||
hres = dbgExt->symbols->GetTypeName( moduleBase, fieldTypeId, fieldTypeName, sizeof(fieldTypeName), NULL );
|
hres = dbgExt->symbols->GetTypeName( moduleBase, fieldTypeId, fieldTypeName, sizeof(fieldTypeName), NULL );
|
||||||
|
|
||||||
std::string fieldTypeNameStr( fieldTypeName );
|
std::string fieldTypeNameStr( fieldTypeName );
|
||||||
if ( fieldTypeNameStr == "__unnamed"
|
if ( fieldTypeNameStr == "__unnamed"
|
||||||
|| fieldTypeNameStr.find("<unnamed-tag>") < fieldTypeNameStr.size() )
|
|| fieldTypeNameStr.find("<unnamed-tag>") < fieldTypeNameStr.size() )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
m_fields.push_back( TypeField( fieldName, get(moduleName, fieldTypeName), fieldSize, fieldOffset ) );
|
m_fields.push_back( TypeField( fieldName, get(moduleName, fieldTypeName), fieldSize, fieldOffset ) );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
catch( std::exception &e )
|
||||||
|
{
|
||||||
|
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd error: %s\n", e.what() );
|
||||||
|
}
|
||||||
|
catch(...)
|
||||||
|
{
|
||||||
|
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" );
|
||||||
}
|
}
|
||||||
catch( std::exception &e )
|
|
||||||
{
|
|
||||||
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd error: %s\n", e.what() );
|
|
||||||
}
|
|
||||||
catch(...)
|
|
||||||
{
|
|
||||||
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
boost::python::object
|
boost::python::object
|
||||||
TypeInfo::load( ULONG64 addr ) const
|
TypeInfo::build( ULONG offset /* = 0 */ ) const
|
||||||
|
{
|
||||||
|
boost::shared_ptr<typeClass> ptr( new typeClass( *this ) );
|
||||||
|
boost::python::object var( ptr );
|
||||||
|
ptr->setPyObj( var );
|
||||||
|
ptr->getTypeInfo().setOffset(offset);
|
||||||
|
|
||||||
|
TypeFieldList::const_iterator field = m_fields.begin();
|
||||||
|
for ( field = m_fields.begin(); field != m_fields.end(); ++field )
|
||||||
|
{
|
||||||
|
|
||||||
|
if ( field->size == field->type.size() )
|
||||||
|
{
|
||||||
|
var.attr( field->name.c_str() ) =
|
||||||
|
field->type.build( offset + field->offset );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
boost::python::dict arr;
|
||||||
|
|
||||||
|
for ( unsigned int i = 0; i < field->size / field->type.size(); ++i )
|
||||||
|
{
|
||||||
|
const ULONG locOffset = field->offset + i * (ULONG)field->type.size();
|
||||||
|
arr[i] = field->type.build( offset + locOffset );
|
||||||
|
}
|
||||||
|
|
||||||
|
var.attr( field->name.c_str() ) = arr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return var;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
boost::python::object
|
||||||
|
TypeInfo::load( ULONG64 addr, ULONG offset /* = 0 */ ) const
|
||||||
{
|
{
|
||||||
if ( !isOffsetValid( addr) )
|
if ( !isOffsetValid( addr) )
|
||||||
return boost::python::object();
|
return boost::python::object();
|
||||||
@ -355,10 +382,11 @@ TypeInfo::load( ULONG64 addr ) const
|
|||||||
|
|
||||||
if ( m_baseType )
|
if ( m_baseType )
|
||||||
return loadBaseType( addr );
|
return loadBaseType( addr );
|
||||||
|
|
||||||
boost::shared_ptr<typedVarClass> ptr( new typedVarClass( *this, addr ) );
|
boost::shared_ptr<typedVarClass> ptr( new typedVarClass( *this, addr ) );
|
||||||
boost::python::object var( ptr );
|
boost::python::object var( ptr );
|
||||||
ptr->setPyObj( var );
|
ptr->setPyObj( var );
|
||||||
|
ptr->getTypeInfo().setOffset(offset);
|
||||||
|
|
||||||
TypeFieldList::const_iterator field = m_fields.begin();
|
TypeFieldList::const_iterator field = m_fields.begin();
|
||||||
for ( field = m_fields.begin(); field != m_fields.end(); ++field )
|
for ( field = m_fields.begin(); field != m_fields.end(); ++field )
|
||||||
@ -366,19 +394,22 @@ TypeInfo::load( ULONG64 addr ) const
|
|||||||
|
|
||||||
if ( field->size == field->type.size() )
|
if ( field->size == field->type.size() )
|
||||||
{
|
{
|
||||||
var.attr( field->name.c_str() ) = field->type.load( addr + field->offset );
|
var.attr( field->name.c_str() ) =
|
||||||
|
field->type.load( addr + field->offset, offset + field->offset );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
boost::python::dict arr;
|
boost::python::dict arr;
|
||||||
|
|
||||||
for ( unsigned int i = 0; i < field->size / field->type.size(); ++i )
|
for ( unsigned int i = 0; i < field->size / field->type.size(); ++i )
|
||||||
arr[i] = field->type.load( addr + field->offset + i * field->type.size() );
|
{
|
||||||
|
const ULONG locOffset = field->offset + i * (ULONG)field->type.size();
|
||||||
var.attr( field->name.c_str() ) = arr;
|
arr[i] = field->type.load( addr + locOffset, offset + locOffset );
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
var.attr( field->name.c_str() ) = arr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return var;
|
return var;
|
||||||
}
|
}
|
||||||
@ -392,20 +423,20 @@ isBaseType( const std::string &typeName )
|
|||||||
{
|
{
|
||||||
if ( typeName == basicTypeNames[i] )
|
if ( typeName == basicTypeNames[i] )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if ( typeName == ( std::string( basicTypeNames[i] ) + "*" ) )
|
if ( typeName == ( std::string( basicTypeNames[i] ) + "*" ) )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if ( typeName == ( std::string( basicTypeNames[i] ) + "[]" ) )
|
if ( typeName == ( std::string( basicTypeNames[i] ) + "[]" ) )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if ( typeName == ( std::string( basicTypeNames[i] ) + "*[]" ) )
|
if ( typeName == ( std::string( basicTypeNames[i] ) + "*[]" ) )
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
boost::python::object
|
boost::python::object
|
||||||
@ -415,17 +446,17 @@ TypeInfo::loadBaseType( ULONG64 address ) const
|
|||||||
{
|
{
|
||||||
if ( m_typeName == basicTypeNames[i] )
|
if ( m_typeName == basicTypeNames[i] )
|
||||||
return basicTypeLoaders[i]( address, m_size );
|
return basicTypeLoaders[i]( address, m_size );
|
||||||
|
|
||||||
if ( m_typeName == ( std::string( basicTypeNames[i] ) + "*" ) )
|
if ( m_typeName == ( std::string( basicTypeNames[i] ) + "*" ) )
|
||||||
return valueLoader<void*>( address, ptrSize() );
|
return valueLoader<void*>( address, ptrSize() );
|
||||||
|
|
||||||
if ( m_typeName == ( std::string( basicTypeNames[i] ) + "[]" ) )
|
if ( m_typeName == ( std::string( basicTypeNames[i] ) + "[]" ) )
|
||||||
return basicTypeLoaders[i]( address, m_size );
|
return basicTypeLoaders[i]( address, m_size );
|
||||||
|
|
||||||
if ( m_typeName == ( std::string( basicTypeNames[i] ) + "*[]" ) )
|
if ( m_typeName == ( std::string( basicTypeNames[i] ) + "*[]" ) )
|
||||||
return valueLoader<void*>( address, ptrSize() );
|
return valueLoader<void*>( address, ptrSize() );
|
||||||
}
|
}
|
||||||
|
|
||||||
return boost::python::object();
|
return boost::python::object();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -444,16 +475,16 @@ valueLoader( ULONG64 address, ULONG size )
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
boost::python::dict arr;
|
boost::python::dict arr;
|
||||||
|
|
||||||
for ( unsigned int i = 0; i < size / sizeof(valType); ++i )
|
for ( unsigned int i = 0; i < size / sizeof(valType); ++i )
|
||||||
{
|
{
|
||||||
valType v = 0;
|
valType v = 0;
|
||||||
if ( !loadMemory( address + i * sizeof(valType), &v, sizeof(v) ) )
|
if ( !loadMemory( address + i * sizeof(valType), &v, sizeof(v) ) )
|
||||||
return boost::python::object();
|
return boost::python::object();
|
||||||
|
|
||||||
arr[i] = boost::python::long_( (unsigned __int64)v );
|
arr[i] = boost::python::long_( (unsigned __int64)v );
|
||||||
}
|
}
|
||||||
|
|
||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -466,14 +497,17 @@ std::string typeClass::print() const
|
|||||||
{
|
{
|
||||||
stringstream sstr;
|
stringstream sstr;
|
||||||
|
|
||||||
sstr << getTypeInfo().name() << std::endl;
|
sstr << getTypeInfo().name() << " ";
|
||||||
|
printSelf(sstr);
|
||||||
|
sstr << std::endl;
|
||||||
|
|
||||||
TypeInfo::TypeFieldList::const_iterator itField =
|
TypeInfo::TypeFieldList::const_iterator itField =
|
||||||
getTypeInfo().getFields().begin();
|
getTypeInfo().getFields().begin();
|
||||||
while (itField != getTypeInfo().getFields().end())
|
while (itField != getTypeInfo().getFields().end())
|
||||||
{
|
{
|
||||||
sstr << "\t" << hex << "+" << itField->offset;
|
sstr << "\t" << hex << "+" << itField->offset << " ";
|
||||||
sstr << " " << itField->name << " ";
|
sstr << itField->type.name() << " ";
|
||||||
|
sstr << itField->name << " ";
|
||||||
|
|
||||||
printField(*itField, sstr);
|
printField(*itField, sstr);
|
||||||
|
|
||||||
@ -495,7 +529,7 @@ typedVarClass::printField(const TypeInfo::TypeField &field, stringstream &sstr)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
boost::python::object attr = getPyObj().attr( field.name.c_str() );
|
boost::python::object attr = getPyObj().attr( field.name.c_str() );
|
||||||
|
|
||||||
if ( field.size == field.type.size() )
|
if ( field.size == field.type.size() )
|
||||||
{
|
{
|
||||||
if ( attr.ptr() == Py_None )
|
if ( attr.ptr() == Py_None )
|
||||||
@ -505,9 +539,9 @@ typedVarClass::printField(const TypeInfo::TypeField &field, stringstream &sstr)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
unsigned __int64 val = boost::python::extract<unsigned __int64>( attr );
|
unsigned __int64 val = boost::python::extract<unsigned __int64>( attr );
|
||||||
|
|
||||||
sstr << hex << "0x" << val;
|
sstr << hex << "0x" << val;
|
||||||
|
|
||||||
if ( field.type.name() == "char*" )
|
if ( field.type.name() == "char*" )
|
||||||
{
|
{
|
||||||
char buf[0x100];
|
char buf[0x100];
|
||||||
@ -522,20 +556,20 @@ typedVarClass::printField(const TypeInfo::TypeField &field, stringstream &sstr)
|
|||||||
if ( loadWStrToBuffer( val, wbuf, sizeof(wbuf) ) )
|
if ( loadWStrToBuffer( val, wbuf, sizeof(wbuf) ) )
|
||||||
{
|
{
|
||||||
char mbBuf[0x100] = { 0 };
|
char mbBuf[0x100] = { 0 };
|
||||||
|
|
||||||
WideCharToMultiByte( CP_ACP, 0, wbuf, wcslen(wbuf)+1, mbBuf, sizeof(mbBuf), NULL, NULL );
|
WideCharToMultiByte( CP_ACP, 0, wbuf, wcslen(wbuf)+1, mbBuf, sizeof(mbBuf), NULL, NULL );
|
||||||
|
|
||||||
sstr << " (" << mbBuf << " )";
|
sstr << " (" << mbBuf << " )";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
sstr << " ( read string error )";
|
sstr << " ( read string error )";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sstr << dec << " ( " << val << " )";
|
sstr << dec << " ( " << val << " )";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for ( size_t i = 0; i < field.size/field.type.size(); ++i )
|
for ( size_t i = 0; i < field.size/field.type.size(); ++i )
|
||||||
|
@ -38,11 +38,11 @@ public:
|
|||||||
|
|
||||||
template< typename TTypeInfo>
|
template< typename TTypeInfo>
|
||||||
struct TypeFieldT {
|
struct TypeFieldT {
|
||||||
ULONG size;
|
ULONG size;
|
||||||
ULONG offset;
|
ULONG offset;
|
||||||
TTypeInfo type;
|
TTypeInfo type;
|
||||||
std::string name;
|
std::string name;
|
||||||
|
|
||||||
TypeFieldT( const std::string &name_, const TTypeInfo &type_, ULONG size_, ULONG offset_ ) :
|
TypeFieldT( const std::string &name_, const TTypeInfo &type_, ULONG size_, ULONG offset_ ) :
|
||||||
name( name_ ),
|
name( name_ ),
|
||||||
size( size_ ),
|
size( size_ ),
|
||||||
@ -65,12 +65,12 @@ public:
|
|||||||
|
|
||||||
if ( typeName.module < module )
|
if ( typeName.module < module )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if ( typeName.module > module )
|
if ( typeName.module > module )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return typeName.symbol < symbol;
|
return typeName.symbol < symbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -85,46 +85,55 @@ public:
|
|||||||
TypeInfo() :
|
TypeInfo() :
|
||||||
m_size( 0 ),
|
m_size( 0 ),
|
||||||
m_baseType( false ),
|
m_baseType( false ),
|
||||||
m_pointer( false )
|
m_pointer( false ),
|
||||||
|
m_offset(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
TypeInfo( const std::string &moduleName, const std::string &typeName );
|
TypeInfo( const std::string &moduleName, const std::string &typeName );
|
||||||
|
|
||||||
boost::python::object
|
boost::python::object
|
||||||
load( ULONG64 addr ) const;
|
load( ULONG64 addr, ULONG offset = 0 ) const;
|
||||||
|
|
||||||
|
boost::python::object
|
||||||
|
build( ULONG offset = 0 ) const;
|
||||||
|
|
||||||
|
|
||||||
ULONG64
|
ULONG64
|
||||||
size() const
|
size() const
|
||||||
{
|
{
|
||||||
return m_size;
|
return m_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string&
|
const std::string&
|
||||||
name() const
|
name() const
|
||||||
{
|
{
|
||||||
return m_typeName;
|
return m_typeName;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const TypeInfo&
|
static const TypeInfo&
|
||||||
get( const std::string &moduleName, const std::string &typeName );
|
get( const std::string &moduleName, const std::string &typeName );
|
||||||
|
|
||||||
const TypeFieldList&
|
const TypeFieldList&
|
||||||
getFields() const {
|
getFields() const {
|
||||||
return m_fields;
|
return m_fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
isComplex() const {
|
isComplex() const {
|
||||||
return !m_baseType;
|
return !m_baseType;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
isPtr() const {
|
isPtr() const {
|
||||||
return m_pointer;
|
return m_pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
// field offset getter/setter
|
||||||
|
void setOffset(ULONG offset) { m_offset = offset; }
|
||||||
|
ULONG getOffset() const { return m_offset; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
static TypeInfoMap g_typeInfoCache;
|
static TypeInfoMap g_typeInfoCache;
|
||||||
|
|
||||||
boost::python::object
|
boost::python::object
|
||||||
@ -134,7 +143,7 @@ private:
|
|||||||
ptrLoader( ULONG64 addr ) const {
|
ptrLoader( ULONG64 addr ) const {
|
||||||
return boost::python::object( loadPtrByPtr( addr ) );
|
return boost::python::object( loadPtrByPtr( addr ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
setupBaseType();
|
setupBaseType();
|
||||||
|
|
||||||
@ -145,6 +154,7 @@ private:
|
|||||||
TypeFieldList m_fields;
|
TypeFieldList m_fields;
|
||||||
std::string m_typeName;
|
std::string m_typeName;
|
||||||
ULONG m_size;
|
ULONG m_size;
|
||||||
|
ULONG m_offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -163,9 +173,10 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sizeof(TYPE)
|
||||||
ULONG size() const
|
ULONG size() const
|
||||||
{
|
{
|
||||||
return m_typeInfo.size();
|
return (ULONG)m_typeInfo.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setPyObj( const boost::python::object &obj )
|
void setPyObj( const boost::python::object &obj )
|
||||||
@ -173,6 +184,7 @@ public:
|
|||||||
m_pyobj = obj;
|
m_pyobj = obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TypeInfo getter
|
||||||
TypeInfo &getTypeInfo()
|
TypeInfo &getTypeInfo()
|
||||||
{
|
{
|
||||||
return m_typeInfo;
|
return m_typeInfo;
|
||||||
@ -182,6 +194,7 @@ public:
|
|||||||
return m_typeInfo;
|
return m_typeInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// boost::python::object getter
|
||||||
boost::python::object &getPyObj()
|
boost::python::object &getPyObj()
|
||||||
{
|
{
|
||||||
return m_pyobj;
|
return m_pyobj;
|
||||||
@ -200,6 +213,14 @@ public:
|
|||||||
{
|
{
|
||||||
// no data - nothing print
|
// no data - nothing print
|
||||||
}
|
}
|
||||||
|
virtual void printSelf(
|
||||||
|
std::stringstream &sstr
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
// no data - nothing print
|
||||||
|
}
|
||||||
|
|
||||||
|
ULONG getOffset() const { return m_typeInfo.getOffset(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TypeInfo m_typeInfo;
|
TypeInfo m_typeInfo;
|
||||||
@ -226,7 +247,13 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void
|
virtual void
|
||||||
printField(const TypeInfo::TypeField &field, std::stringstream &sstr) const override;
|
printField( const TypeInfo::TypeField &field, std::stringstream &sstr ) const override;
|
||||||
|
|
||||||
|
virtual void
|
||||||
|
printSelf( std::stringstream &sstr ) const override
|
||||||
|
{
|
||||||
|
sstr << std::hex << "0x" << getAddress() << std::dec << " ";
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user