diff --git a/pykd/pykdver.h b/pykd/pykdver.h index 1e29be6..4c9caf4 100644 --- a/pykd/pykdver.h +++ b/pykd/pykdver.h @@ -2,7 +2,7 @@ #define PYKD_VERSION_MAJOR 0 #define PYKD_VERSION_MINOR 3 #define PYKD_VERSION_SUBVERSION 2 -#define PYKD_VERSION_BUILDNO 2 +#define PYKD_VERSION_BUILDNO 3 #define __VER_STR2__(x) #x #define __VER_STR1__(x) __VER_STR2__(x) diff --git a/pykd/pymod.cpp b/pykd/pymod.cpp index 86c4659..55fd67a 100644 --- a/pykd/pymod.cpp +++ b/pykd/pymod.cpp @@ -21,6 +21,7 @@ #include "pytypeinfo.h" #include "pycpucontext.h" #include "pyprocess.h" +#include "pydataaccess.h" using namespace pykd; @@ -920,6 +921,7 @@ BOOST_PYTHON_MODULE( pykd ) #endif ; + python::class_, 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(pykd::getTypedVarByName) ) @@ -952,6 +954,8 @@ BOOST_PYTHON_MODULE( pykd ) "Return method of class as an object attribute" ) .def("deref",TypedVarAdapter::deref, "Return value by pointer" ) + .def("rawBytes", TypedVarAdapter::getRawBytes, + "Return list of bytes" ) .def("type", TypedVarAdapter::getType, "Return typeInfo instance" ) .def("castTo", TypedVarAdapter::castByName, @@ -1311,6 +1315,17 @@ BOOST_PYTHON_MODULE( pykd ) .def("__str__", pykd::printSyntheticSymbol, "Return object as a string"); + //python::class_("dataAccessor", + // "class for abstract representation of data storage",python::no_init) + // .def("readByte", &pykd::DataAccessor::readByte) + // ; + + //python::class_("objectAccessor", + // "class for data access to python objects", python::no_init) + // .def( python::init() ) + // //.def("readByte", &pykd::ListDataAccessor::readByte, "") + // ; + // C++ exception translation to python pykd::registerExceptions(); } diff --git a/pykd/pytypedvar.cpp b/pykd/pytypedvar.cpp index 9ff63fe..6b2f67e 100644 --- a/pykd/pytypedvar.cpp +++ b/pykd/pytypedvar.cpp @@ -7,6 +7,52 @@ namespace pykd { /////////////////////////////////////////////////////////////////////////////// +kdlib::TypedVarPtr getTypedVarByTypeName(const std::wstring &name, python::object& dataStorage) +{ + python::extract get_addr(dataStorage); + if ( get_addr.check() ) + { + kdlib::MEMOFFSET_64 offset = get_addr(); + AutoRestorePyState pystate; + return kdlib::loadTypedVar( name, offset ); + } + + std::vector byteArray; + + for (int i = 0; i < python::len(dataStorage); ++i) + { + byteArray.push_back( python::extract(dataStorage[i]) ); + } + + AutoRestorePyState pystate; + return kdlib::loadTypedVar( name, kdlib::getCacheAccessor(byteArray) ); +} + +/////////////////////////////////////////////////////////////////////////////// + +kdlib::TypedVarPtr getTypedVarByTypeInfo( const kdlib::TypeInfoPtr &typeInfo, python::object& dataStorage) +{ + python::extract get_addr(dataStorage); + if ( get_addr.check() ) + { + kdlib::MEMOFFSET_64 offset = get_addr(); + AutoRestorePyState pystate; + return kdlib::loadTypedVar(typeInfo, offset ); + } + + std::vector byteArray; + + for (int i = 0; i < python::len(dataStorage); ++i) + { + byteArray.push_back( python::extract(dataStorage[i]) ); + } + + AutoRestorePyState pystate; + return kdlib::loadTypedVar(typeInfo, kdlib::getCacheAccessor(byteArray) ); +} + +/////////////////////////////////////////////////////////////////////////////// + python::list getTypedVarListByTypeName( kdlib::MEMOFFSET_64 offset, const std::wstring &typeName, const std::wstring &fieldName ) { kdlib::TypedVarList lst; @@ -154,6 +200,23 @@ kdlib::TypedVarPtr TypedVarAdapter::getFieldAttr(kdlib::TypedVar& typedVar, cons /////////////////////////////////////////////////////////////////////////////// +python::list TypedVarAdapter::getRawBytes(kdlib::TypedVar& typedVar) +{ + + std::vector rawBytes; + + { + AutoRestorePyState pystate; + kdlib::DataAccessorPtr dataStream = kdlib::getCacheAccessor(typedVar.getSize()); + typedVar.writeBytes(dataStream); + dataStream->readBytes(rawBytes, typedVar.getSize()); + + } + + return vectorToList( rawBytes ); + } + +/////////////////////////////////////////////////////////////////////////////// } // namesapce pykd diff --git a/pykd/pytypedvar.h b/pykd/pytypedvar.h index 301e3f9..ad02661 100644 --- a/pykd/pytypedvar.h +++ b/pykd/pytypedvar.h @@ -14,11 +14,7 @@ namespace python = boost::python; namespace pykd { -inline kdlib::TypedVarPtr getTypedVarByTypeName( const std::wstring &name, kdlib::MEMOFFSET_64 addr ) -{ - AutoRestorePyState pystate; - return kdlib::loadTypedVar( name, addr ); -} +kdlib::TypedVarPtr getTypedVarByTypeName(const std::wstring &name, python::object& dataStorage); inline kdlib::TypedVarPtr getTypedVarByName( const std::wstring &name ) { @@ -26,11 +22,7 @@ inline kdlib::TypedVarPtr getTypedVarByName( const std::wstring &name ) return kdlib::loadTypedVar( name ); } -inline kdlib::TypedVarPtr getTypedVarByTypeInfo( const kdlib::TypeInfoPtr &typeInfo, kdlib::MEMOFFSET_64 addr ) -{ - AutoRestorePyState pystate; - return kdlib::loadTypedVar( typeInfo, addr ); -} +kdlib::TypedVarPtr getTypedVarByTypeInfo( const kdlib::TypeInfoPtr &typeInfo, python::object& dataStorage); inline kdlib::TypedVarPtr getTypedVarWithPrototype( const std::wstring &name, const std::wstring &prototype) { @@ -38,6 +30,8 @@ inline kdlib::TypedVarPtr getTypedVarWithPrototype( const std::wstring &name, co return kdlib::loadTypedVar(name, prototype); } +kdlib::TypedVarPtr getTypedVarByTypeNameWithBuffer(const std::wstring& name, python::object &bytes); + python::list getTypedVarListByTypeName( kdlib::MEMOFFSET_64 offset, const std::wstring &typeName, const std::wstring &fieldName ); python::list getTypedVarListByType( kdlib::MEMOFFSET_64 offset, kdlib::TypeInfoPtr &typeInfo, const std::wstring &fieldName ); python::list getTypedVarArrayByTypeName( kdlib::MEMOFFSET_64 offset, const std::wstring &typeName, size_t number ); @@ -185,6 +179,8 @@ struct TypedVarAdapter { AutoRestorePyState pystate; return typedVar.castTo(typeInfo); } + + static python::list getRawBytes(kdlib::TypedVar& typedVar); }; } // end namespace pykd diff --git a/test/scripts/typedvar.py b/test/scripts/typedvar.py index 3373295..9b6d146 100644 --- a/test/scripts/typedvar.py +++ b/test/scripts/typedvar.py @@ -419,4 +419,10 @@ class TypedVarTest( unittest.TestCase ): addr = pykd.getOffset("g_structTest") self.assertTrue( None != target.module.type( "structTest" ).getTypedVar(addr) ) - \ No newline at end of file + def testByteSequence(self): + self.assertEqual( 0x44332211, pykd.typedVar("UInt4B", [0x11, 0x22, 0x33, 0x44]) ) + self.assertEqual( -1, pykd.typedVar( pykd.baseTypes.Int4B, [0xFF, 0xFF, 0xFF, 0xFF] ) ) + + def testRawBytes(self): + self.assertEqual( [ 0x55, 0x55, 0, 0], target.module.typedVar( "ulongConst" ).rawBytes() ) + \ No newline at end of file