From efdf59111b8d634f6115438b00ba32c56ebcccfe Mon Sep 17 00:00:00 2001 From: "SND\\kernelnet_cp" Date: Fri, 14 Jan 2011 17:58:28 +0000 Subject: [PATCH] [[+] added : __str__ method for typedVar class, so it can be outputed by print operator git-svn-id: https://pykd.svn.codeplex.com/svn@60159 9b283d60-5439-405e-af05-b73fd8c4d996 --- pykd/dbgext.cpp | 6 +- pykd/dbgtype.cpp | 72 ++++++++++++++++---- pykd/dbgtype.h | 166 ++++++++++++++++++++++++++------------------- pykd/pykd.def | 2 +- snippets/reload.py | 2 +- 5 files changed, 162 insertions(+), 86 deletions(-) diff --git a/pykd/dbgext.cpp b/pykd/dbgext.cpp index 64d478c..aa3a352 100644 --- a/pykd/dbgext.cpp +++ b/pykd/dbgext.cpp @@ -145,9 +145,10 @@ BOOST_PYTHON_MODULE( pykd ) boost::python::def( "setCurrentProcess", &setCurrentProcess ); boost::python::def( "getProcessorMode", &getProcessorMode ); boost::python::def( "setProcessorMode", &setProcessorMode ); - boost::python::class_( "typedVarClass" ) + boost::python::class_ >( "typedVarClass" ) .def("getAddress", &typedVarClass::getAddress ) - .def("sizeof", &typedVarClass::size ); + .def("sizeof", &typedVarClass::size ) + .def("__str__", &typedVarClass::print); boost::python::class_( "dbgModuleClass" ) .def("begin", &dbgModuleClass::getBegin ) .def("end", &dbgModuleClass::getEnd ) @@ -478,3 +479,4 @@ pythonpath( PDEBUG_CLIENT4 client, PCSTR args ) } ///////////////////////////////////////////////////////////////////////////////// + diff --git a/pykd/dbgtype.cpp b/pykd/dbgtype.cpp index de50107..6b2db4e 100644 --- a/pykd/dbgtype.cpp +++ b/pykd/dbgtype.cpp @@ -1,6 +1,6 @@ #include "stdafx.h" -#include +#include #include "dbgext.h" #include "dbgtype.h" @@ -285,7 +285,7 @@ TypeInfo::TypeInfo( const std::string &moduleName, const std::string &typeName || fieldTypeNameStr.find("") < fieldTypeNameStr.size() ) continue; - m_fields.insert( make_pair( fieldName, TypeField( get(moduleName, fieldTypeName), fieldSize, fieldOffset ) ) ); + m_fields.push_back( TypeField( fieldName, get(moduleName, fieldTypeName), fieldSize, fieldOffset ) ); } } @@ -310,25 +310,30 @@ TypeInfo::load( ULONG64 addr ) const if ( m_baseType ) return loadBaseType( addr ); - boost::python::object var( typedVarClass( addr, m_size ) ); + boost::shared_ptr ptr( new typedVarClass( *this, addr, m_size ) ); + boost::python::object var( ptr ); + ptr->setPyObj( var ); - TypeFieldMap::const_iterator it = m_fields.begin(); - for ( it = m_fields.begin(); it != m_fields.end(); ++it ) + TypeFieldList::const_iterator field = m_fields.begin(); + for ( field = m_fields.begin(); field != m_fields.end(); ++field ) { - const TypeField &field = it->second; - - if ( field.size == field.type.size() ) + + if ( field->size == field->type.size() ) { - var.attr( it->first.c_str() ) = field.type.load( addr + field.offset ); + var.attr( field->name.c_str() ) = field->type.load( addr + field->offset ); + +// boost::python::object obj = var.attr( field->name.c_str() ); + + //int a; } else { boost::python::dict arr; - for ( unsigned int i = 0; i < field.size / field.type.size(); ++i ) - arr[i] = field.type.load( addr + field.offset + i * field.type.size() ); + for ( unsigned int i = 0; i < field->size / field->type.size(); ++i ) + arr[i] = field->type.load( addr + field->offset + i * field->type.size() ); - var.attr( it->first.c_str() ) = arr; + var.attr( field->name.c_str() ) = arr; } } @@ -413,3 +418,46 @@ valueLoader( ULONG64 address, ULONG size ) } ///////////////////////////////////////////////////////////////////////////////// + +std::string +typedVarClass::print() const +{ + stringstream sstr; + + for ( + TypeInfo::TypeFieldList::const_iterator field = m_typeInfo.getFields().begin(); + field != m_typeInfo.getFields().end(); + field++ ) + { + sstr << "\t" << hex << "+" << field->offset << " " << field->name << " "; + + if ( field->type.isComplex() ) + sstr << field->type.name(); + else + { + if ( field->size == field->type.size() ) + { + boost::python::object attr = m_pyobj.attr( field->name.c_str() ); + + if ( attr.ptr() == Py_None ) + { + sstr << "memory error"; + } + else + { + unsigned __int64 val = boost::python::extract( attr ); + + sstr << hex << "0x" << val << dec << " ( " << val << " )"; + } + } + } + + sstr << std::endl; + } + + return sstr.str(); +} + +///////////////////////////////////////////////////////////////////////////////// + + diff --git a/pykd/dbgtype.h b/pykd/dbgtype.h index 8774cc4..22c863c 100644 --- a/pykd/dbgtype.h +++ b/pykd/dbgtype.h @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -10,37 +11,7 @@ ///////////////////////////////////////////////////////////////////////////////// -class typedVarClass { -public: - - typedVarClass() - {} - - typedVarClass( ULONG64 addr, ULONG size ) : - m_addr( addr ), - m_size( size ) - {} - - ULONG64 - getAddress() const { - return m_addr; - } - - ULONG - size() const { - return m_size; - } - -private: - - ULONG64 m_addr; - - ULONG m_size; - -}; - -///////////////////////////////////////////////////////////////////////////////// boost::python::object loadTypedVar( const std::string &moduleName, const std::string &typeName, ULONG64 address ); @@ -59,6 +30,44 @@ sizeofType( const std::string &moduleName, const std::string &typeName ); class TypeInfo { +public: + + template< typename TTypeInfo> + struct TypeFieldT { + ULONG size; + ULONG offset; + TTypeInfo type; + std::string name; + + TypeFieldT( const std::string &name_, const TTypeInfo &type_, ULONG size_, ULONG offset_ ) : + name( name_ ), + size( size_ ), + offset( offset_ ), + type( type_ ) + {} + }; + + struct TypeName { + std::string module; + std::string symbol; + + TypeName( const std::string &module_, const std::string &symbol_ ) : + module( module_ ), + symbol( symbol_ ) + {} + + bool + operator < ( const TypeName &typeName ) const { + return ( typeName.module <= module ) && ( typeName.symbol < symbol ); + } + }; + + typedef TypeFieldT TypeField; + + typedef std::map TypeInfoMap; + + typedef std::list TypeFieldList; + public: TypeInfo() : @@ -85,48 +94,21 @@ public: } static const TypeInfo& - get( const std::string &moduleName, const std::string &typeName ); - + get( const std::string &moduleName, const std::string &typeName ); + + const TypeFieldList& + getFields() const { + return m_fields; + } + + bool + isComplex() const { + return !m_baseType; + } private: - - template< typename TTypeInfo> - struct TypeFieldT { - ULONG size; - ULONG offset; - TTypeInfo type; - - TypeFieldT( const TTypeInfo &type_, ULONG size_, ULONG offset_ ) : - size( size_ ), - offset( offset_ ), - type( type_ ) - {} - }; - - struct TypeName { - std::string module; - std::string symbol; - - TypeName( const std::string &module_, const std::string &symbol_ ) : - module( module_ ), - symbol( symbol_ ) - {} - - bool - operator < ( const TypeName &typeName ) const { - return ( typeName.module <= module ) && ( typeName.symbol < symbol ); - } - }; - - - - typedef TypeFieldT TypeField; - - typedef std::map TypeInfoMap; - - typedef std::map TypeFieldMap; - static TypeInfoMap g_typeInfoCache; + static TypeInfoMap g_typeInfoCache; boost::python::object loadBaseType( ULONG64 addr ) const; @@ -145,11 +127,55 @@ private: bool m_pointer; - TypeFieldMap m_fields; + TypeFieldList m_fields; std::string m_typeName; ULONG m_size; }; +///////////////////////////////////////////////////////////////////////////////// + +class typedVarClass { + +public: + + typedVarClass() + {} + + typedVarClass( const TypeInfo &typeInfo, ULONG64 addr, ULONG size ) : + m_typeInfo( typeInfo ), + m_addr( addr ), + m_size( size ) + {} + + ULONG64 + getAddress() const { + return m_addr; + } + + ULONG + size() const { + return m_size; + } + + std::string + print() const; + + void + setPyObj( const boost::python::object &obj ) { + m_pyobj = obj; + } + +private: + + ULONG64 m_addr; + + ULONG m_size; + + TypeInfo m_typeInfo; + + boost::python::object m_pyobj; +}; + ///////////////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/pykd/pykd.def b/pykd/pykd.def index c781c4f..3ed8bab 100644 --- a/pykd/pykd.def +++ b/pykd/pykd.def @@ -5,4 +5,4 @@ EXPORTS info py pycmd - pythonpath \ No newline at end of file + pythonpath diff --git a/snippets/reload.py b/snippets/reload.py index 2d41c45..89d98c4 100644 --- a/snippets/reload.py +++ b/snippets/reload.py @@ -17,7 +17,7 @@ def symreload(): if "" == getPdbFile( module.DllBase ): baseName = loadUnicodeString( module.BaseDllName.getAddress() ) - if baseName=="ntoskrnl.exe": baseName = "nt" + if baseName=="ntoskrnl.exe": baseName = "nt" reloadModule( " /u " + str(baseName) ) if __name__ == "__main__":