From d095c9dac0037d1b4d17a12f5efd9e47d10c260b Mon Sep 17 00:00:00 2001 From: "SND\\kernelnet_cp" Date: Mon, 7 Nov 2011 06:46:53 +0000 Subject: [PATCH] [0.1.x] added : pointer fields output for typedVar class git-svn-id: https://pykd.svn.codeplex.com/svn@71146 9b283d60-5439-405e-af05-b73fd8c4d996 --- pykd/dbgext.cpp | 17 ++++++++++------- pykd/module.cpp | 37 +++++++++++++++++++++++++++++++++++- pykd/module.h | 6 +++++- pykd/typedvar.cpp | 32 +++++++++++++++++++++++++++++-- pykd/typedvar.h | 25 ++++++++++++++++++++++++ test/scripts/typedvar.py | 19 +++++++++++++++--- test/scripts/typeinfo.py | 2 +- test/targetapp/targetapp.cpp | 4 +++- 8 files changed, 126 insertions(+), 16 deletions(-) diff --git a/pykd/dbgext.cpp b/pykd/dbgext.cpp index 9d02a86..269149b 100644 --- a/pykd/dbgext.cpp +++ b/pykd/dbgext.cpp @@ -282,15 +282,14 @@ BOOST_PYTHON_MODULE( pykd ) "Return virtual address" ) .def("sizeof", &TypedVar::getSize, "Return size of a variable in the target memory" ) + .def("offset", &TypedVar::getOffset, + "Return offset to parent" ) + .def("field", &TypedVar::getField, + "Return field of structure as an object attribute" ) .def("__getattr__", &TypedVar::getField, "Return field of structure as an object attribute" ) .def( "__str__", &TypedVar::print ); - //.def("data", &pykd::TypedVar::data, - // "Return raw string object with data stream" ); - //.def("__getattr__", &pykd::TypedVar::getFieldWrap, - // "Return field of structure as an object attribute" ); - python::class_("module", "Class representing executable module", python::no_init ) .def("begin", &pykd::Module::getBase, "Return start address of the module" ) @@ -312,10 +311,14 @@ BOOST_PYTHON_MODULE( pykd ) "Return rva of the symbol" ) .def("type", &pykd::Module::getTypeByName, "Return typeInfo class by type name" ) - .def("typedVar", &pykd::Module::getTypedVarByAddr, - "Return a typedVar class instance" ) + //.def("typedVar", &pykd::Module::getTypedVarByAddr, + // "Return a typedVar class instance" ) .def("typedVar",&pykd::Module::getTypedVarByName, "Return a typedVar class instance" ) + .def("typedVar",&pykd::Module::getTypedVarByType, + "Return a typedVar class instance" ) + .def("typedVar",&pykd::Module::getTypedVarByTypeName, + "Return a typedVar class instance" ) .def("__getattr__", &pykd::Module::getSymbol, "Return address of the symbol" ); diff --git a/pykd/module.cpp b/pykd/module.cpp index 8bc9fa4..5bb1f13 100644 --- a/pykd/module.cpp +++ b/pykd/module.cpp @@ -161,13 +161,21 @@ Module::getTypeByName( const std::string &typeName ) /////////////////////////////////////////////////////////////////////////////////// TypedVar -Module::getTypedVarByAddr( const std::string &typeName, ULONG64 addr ) +Module::getTypedVarByTypeName( const std::string &typeName, ULONG64 addr ) { return TypedVar( TypeInfo( m_dia, typeName ), addr ); } /////////////////////////////////////////////////////////////////////////////////// +TypedVar +Module::getTypedVarByType( const TypeInfo &typeInfo, ULONG64 addr ) +{ + return TypedVar( typeInfo, addr ); +} + +/////////////////////////////////////////////////////////////////////////////////// + TypedVar Module::getTypedVarByName( const std::string &symName ) { @@ -178,5 +186,32 @@ Module::getTypedVarByName( const std::string &symName ) /////////////////////////////////////////////////////////////////////////////////// +//TypedVar +//Module::getTypedVarByAddr( ULONG64 addr ) +//{ +// addr = addr64(addr); +// +// if ( addr < m_base || addr > getEnd() ) +// throw DbgException("address is out of the module space" ); +// +// ULONG rva = (ULONG)(addr - m_base); +// +// for( ULONG i = 0; i < m_dia->getChildCount(); i++ ) +// { +// pyDia::SymbolPtr typeSym = m_dia->getChildByIndex(i); +// +// std::string name = m_dia->getName(); +// +// if ( typeSym->getSymTag() == SymTagData && typeSym->getRva() == rva ) +// { +// return TypedVar( TypeInfo( typeSym->getType() ), typeSym->getRva() + m_base ); +// } +// } +// +// throw DbgException("failed to find type info for this offset" ); +//} + +/////////////////////////////////////////////////////////////////////////////////// + }; // end of namespace pykd diff --git a/pykd/module.h b/pykd/module.h index 56a366a..cf38870 100644 --- a/pykd/module.h +++ b/pykd/module.h @@ -69,7 +69,11 @@ public: TypeInfo getTypeByName( const std::string &typeName ); - TypedVar getTypedVarByAddr( const std::string &typeName, ULONG64 addr ); + TypedVar getTypedVarByTypeName( const std::string &typeName, ULONG64 addr ); + + TypedVar getTypedVarByType( const TypeInfo &typeInfo, ULONG64 addr ); + + TypedVar getTypedVarByAddr( ULONG64 addr ); TypedVar getTypedVarByName( const std::string &symName ); diff --git a/pykd/typedvar.cpp b/pykd/typedvar.cpp index 4afc15e..fcc065b 100644 --- a/pykd/typedvar.cpp +++ b/pykd/typedvar.cpp @@ -37,9 +37,22 @@ TypedVar::getField( const std::string &fieldName ) if ( fieldType.isBasicType() ) { tv.reset( new BasicTypedVar( m_client, fieldType, m_offset + fieldType.getOffset() ) ); + return tv; } - else - throw DbgException( "can not get field" ); + + if ( fieldType.isPointer() ) + { + tv.reset( new PtrTypedVar( m_client, fieldType, m_offset + fieldType.getOffset() ) ); + return tv; + } + + if ( fieldType.isUserDefined() ) + { + tv.reset( new TypedVar( m_client, fieldType, m_offset + fieldType.getOffset() ) ); + return tv; + } + + throw DbgException( "can not get field" ); return tv; } @@ -62,4 +75,19 @@ BasicTypedVar::getValue() const /////////////////////////////////////////////////////////////////////////////////// +ULONG64 +PtrTypedVar::getValue() const +{ + HRESULT hres; + ULONG64 val = 0; + + hres = m_dataSpaces->ReadPointersVirtual( 1, m_offset, &val ); + if ( FAILED( hres ) ) + throw MemoryException( m_offset, false ); + + return val; +} + +/////////////////////////////////////////////////////////////////////////////////// + } // end pykd namespace \ No newline at end of file diff --git a/pykd/typedvar.h b/pykd/typedvar.h index 6e63950..cdd59c7 100644 --- a/pykd/typedvar.h +++ b/pykd/typedvar.h @@ -30,6 +30,10 @@ public: return m_size; } + ULONG getOffset() { + return m_typeInfo.getOffset(); + } + TypeInfo getType() const { return m_typeInfo; @@ -81,4 +85,25 @@ public: /////////////////////////////////////////////////////////////////////////////////// +class PtrTypedVar : public TypedVar { + +public: + + PtrTypedVar ( IDebugClient4 *client, const TypeInfo& typeInfo, ULONG64 offset ) : TypedVar(client, typeInfo, offset){} + + TypedVarPtr + virtual getField( const std::string &fieldName ) { + throw DbgException("no fields"); + } + + virtual std::string print() { + return "PtrTypedVar"; + } + + virtual ULONG64 getValue() const; + +}; + +/////////////////////////////////////////////////////////////////////////////////// + } // namespace pykd diff --git a/test/scripts/typedvar.py b/test/scripts/typedvar.py index aaf6f52..6770827 100644 --- a/test/scripts/typedvar.py +++ b/test/scripts/typedvar.py @@ -18,13 +18,26 @@ class TypedVarTest( unittest.TestCase ): def testGetSize( self ): tv1 = target.module.typedVar( "structTest", target.module.g_structTest ) - self.assertEqual( 16, tv1.sizeof() ) + self.assertEqual( 20, tv1.sizeof() ) #tv2 = target.module.typedVar( "structTest[2]", target.module.g_testArray ) #self.assertEqual( tv1.sizeof()*2, tv2.sizeof() ) def testStruct(self): tv1 = target.module.typedVar( "structTest", target.module.g_structTest ) - self.assertEqual( 0, tv1.m_field0 + 0 ) + self.assertEqual( 0, tv1.m_field0 ) self.assertEqual( 500, tv1.m_field1 ) self.assertEqual( True, tv1.m_field2 ) - self.assertEqual( 1, tv1.m_field3 ) \ No newline at end of file + self.assertEqual( 1, tv1.m_field3 ) + + def testPtrField(self): + tv = target.module.typedVar( "g_structTest" ) + self.assertEqual( 0, tv.m_field4 ) + + tv1 = target.module.typedVar( "g_structTest1" ) + self.assertEqual( tv.getAddress(), tv1.m_field4 ) + + def testFieldOffset(self): + tv = target.module.typedVar( "g_structTest" ) + self.assertEqual( 0, tv.m_field0.offset() ) + self.assertEqual( 4, tv.m_field1.offset() ) + self.assertEqual( 16, tv.m_field4.offset() ) diff --git a/test/scripts/typeinfo.py b/test/scripts/typeinfo.py index 3053c76..35fa52f 100644 --- a/test/scripts/typeinfo.py +++ b/test/scripts/typeinfo.py @@ -48,5 +48,5 @@ class TypeInfoTest( unittest.TestCase ): def testSize( self ): ti1 = target.module.type( "structTest" ) - self.assertEqual( 16, ti1.size() ) + self.assertEqual( 20, ti1.size() ) diff --git a/test/targetapp/targetapp.cpp b/test/targetapp/targetapp.cpp index b1b4972..f51e8bb 100644 --- a/test/targetapp/targetapp.cpp +++ b/test/targetapp/targetapp.cpp @@ -44,9 +44,11 @@ struct structTest { ULONGLONG m_field1; bool m_field2; USHORT m_field3; + structTest* m_field4; }; -structTest g_structTest = { 0, 500, true, 1 }; +structTest g_structTest = { 0, 500, true, 1, NULL }; +structTest g_structTest1 = { 0, 500, true, 1, &g_structTest }; structTest g_testArray[2] = { { 0, 500, true, 1 }, { 2, 1500, false, 1 } };