diff --git a/pykd/memaccess.h b/pykd/memaccess.h index 1270aa3..e246bf2 100644 --- a/pykd/memaccess.h +++ b/pykd/memaccess.h @@ -64,6 +64,11 @@ inline python::list loadDoubles( kdlib::MEMOFFSET_64 offset, unsigned long count return vectorToList( kdlib::loadDoubles( offset, count, phyAddr ) ); } +inline kdlib::MEMOFFSET_64 ptrPtr( kdlib::MEMOFFSET_64 offset ) +{ + return kdlib::ptrPtr( offset ); +} + inline python::list loadPtrList( kdlib::MEMOFFSET_64 offset ) { return vectorToList( kdlib::loadPtrList(offset) ); diff --git a/pykd/module.h b/pykd/module.h index 323c9a0..914bb77 100644 --- a/pykd/module.h +++ b/pykd/module.h @@ -4,6 +4,8 @@ #include "kdlib/module.h" +#include "stladaptor.h" + namespace pykd { @@ -58,6 +60,20 @@ struct ModuleAdapter : public kdlib::Module std::wstring symbolName = module.findSymbol( offset, displacement ); return python::make_tuple( symbolName, displacement ); } + + + static python::list getTypedVarListByTypeName( kdlib::Module& module, kdlib::MEMOFFSET_64 offset, const std::wstring &typeName, const std::wstring &fieldName ) + { + kdlib::TypedVarList lst = module.loadTypedVarList( offset, typeName, fieldName ); + return vectorToList( lst ); + } + + static python::list getTypedVarArrayByTypeName( kdlib::Module& module, kdlib::MEMOFFSET_64 offset, const std::wstring &typeName, size_t number ) + { + kdlib::TypedVarList lst = module.loadTypedVarArray( offset, typeName, number ); + return vectorToList( lst ); + } + }; } // end namespace pykd diff --git a/pykd/pymod.cpp b/pykd/pymod.cpp index 8b71abd..50bd6a0 100644 --- a/pykd/pymod.cpp +++ b/pykd/pymod.cpp @@ -70,7 +70,8 @@ BOOST_PYTHON_FUNCTION_OVERLOADS( loadSignQWords_, loadSignQWords, 2, 3 ); BOOST_PYTHON_FUNCTION_OVERLOADS( loadFloats_, loadFloats, 2, 3 ); BOOST_PYTHON_FUNCTION_OVERLOADS( loadDoubles_, loadDoubles, 2, 3 ); BOOST_PYTHON_FUNCTION_OVERLOADS( compareMemory_, kdlib::compareMemory, 3, 4 ); -// + + BOOST_PYTHON_FUNCTION_OVERLOADS( getSourceLine_, getSourceLine, 0, 1 ); BOOST_PYTHON_FUNCTION_OVERLOADS( getSourceFile_, kdlib::getSourceFile, 0, 1 ); // @@ -194,8 +195,6 @@ BOOST_PYTHON_MODULE( pykd ) "Read an signed 8-byte integer from the target memory" ); python::def( "ptrSignMWord", &kdlib::ptrSignMWord, "Read an signed mashine's word wide integer from the target memory" ); - python::def( "ptrPtr", &kdlib::ptrPtr, - "Read an pointer value from the target memory" ); python::def( "ptrFloat", &kdlib::ptrSingleFloat, "Read a float with single precision from the target memory" ); python::def( "ptrDouble", &kdlib::ptrDoubleFloat, @@ -229,15 +228,18 @@ BOOST_PYTHON_MODULE( pykd ) // "Return string represention of windows UNICODE_STRING type" ); //python::def( "loadAnsiString", &loadAnsiStr, // "Return string represention of windows ANSI_STRING type" ); - python::def( "loadPtrList", &loadPtrList, - "Return list of pointers, each points to next" ); - python::def( "loadPtrs", &loadPtrArray, - "Read the block of the target's memory and return it as a list of pointers" ); python::def( "loadFloats", &loadFloats, loadFloats_( python::args( "offset", "count", "phyAddr" ), "Read the block of the target's memory and return it as list of floats" ) ); python::def( "loadDoubles", &loadDoubles, loadDoubles_( python::args( "offset", "count", "phyAddr" ), "Read the block of the target's memory and return it as list of doubles" ) ); + python::def( "ptrPtr", &ptrPtr, + "Read an pointer value from the target memory" ); + python::def( "loadPtrList", &loadPtrList, + "Return list of pointers, each points to next" ); + python::def( "loadPtrs", &loadPtrArray, + "Read the block of the target's memory and return it as a list of pointers" ); + // types and vaiables python::def( "getSourceFile", &kdlib::getSourceFile, getSourceFile_( python::args( "offset"), "Return source file by the specified offset" ) ); @@ -251,14 +253,14 @@ BOOST_PYTHON_MODULE( pykd ) // "Return tuple(symbol_name, displacement) by virtual address" ); python::def( "sizeof", &kdlib::getSymbolSize, "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("typedVarList", &TypedVarAdapter::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", &TypedVarAdapter::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", &TypedVarAdapter::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", &TypedVarAdapter::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", &TypedVarAdapter::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" ); @@ -408,10 +410,10 @@ BOOST_PYTHON_MODULE( pykd ) "Return a typedVar class instance" ) .def("typedVar",&kdlib::Module::getTypedVarByTypeName, "Return a typedVar class instance" ) - //.def("typedVarList", &Module::getTypedVarListByTypeName, - // "Return a list of the typedVar class instances. Each item represents an item of the linked list in the target memory" ) - //.def("typedVarArray", &Module::getTypedVarArrayByTypeName, - // "Return a list of the typedVar class instances. Each item represents an item of the counted array in the target memory" ) + .def("typedVarList", &ModuleAdapter::getTypedVarListByTypeName, + "Return a list of the typedVar class instances. Each item represents an item of the linked list in the target memory" ) + .def("typedVarArray", &ModuleAdapter::getTypedVarArrayByTypeName, + "Return a list of the typedVar class instances. Each item represents an item of the counted array in the target memory" ) .def("containingRecord", &kdlib::Module::containingRecord, "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" ) diff --git a/pykd/typedvar.h b/pykd/typedvar.h index c61c714..76940ca 100644 --- a/pykd/typedvar.h +++ b/pykd/typedvar.h @@ -6,6 +6,8 @@ namespace python = boost::python; #include "kdlib/typedvar.h" +#include "stladaptor.h" + namespace pykd { struct TypedVarAdapter { @@ -61,6 +63,32 @@ struct TypedVarAdapter { return lst; } + + static python::list getTypedVarListByTypeName( kdlib::MEMOFFSET_64 offset, const std::wstring &typeName, const std::wstring &fieldName ) + { + kdlib::TypedVarList lst = kdlib::loadTypedVarList( offset, typeName, fieldName ); + return vectorToList( lst ); + } + + static python::list getTypedVarListByType( kdlib::MEMOFFSET_64 offset, kdlib::TypeInfoPtr &typeInfo, const std::wstring &fieldName ) + { + kdlib::TypedVarList lst = kdlib::loadTypedVarList( offset, typeInfo, fieldName ); + return vectorToList( lst ); + } + + static python::list getTypedVarArrayByTypeName( kdlib::MEMOFFSET_64 offset, const std::wstring &typeName, size_t number ) + { + kdlib::TypedVarList lst = kdlib::loadTypedVarArray( offset, typeName, number ); + return vectorToList( lst ); + } + + static python::list getTypedVarArrayByType( kdlib::MEMOFFSET_64 offset, kdlib::TypeInfoPtr &typeInfo, size_t number ) + { + kdlib::TypedVarList lst = kdlib::loadTypedVarArray( offset, typeInfo, number ); + return vectorToList( lst ); + } + + }; } // end namespace pykd diff --git a/test/scripts/typedvar.py b/test/scripts/typedvar.py index 67dd35b..5ef6d59 100644 --- a/test/scripts/typedvar.py +++ b/test/scripts/typedvar.py @@ -146,34 +146,34 @@ class TypedVarTest( unittest.TestCase ): self.assertEqual( -3, tv.m_bit6_8 ) def testTypedVarList(self): - tvl = target.module.typedVarList( target.module.g_listHead, "listStruct", "listEntry" ) - self.assertEqual( 3, len( tvl ) ) - self.assertEqual( [1,2,3], [ tv.num for tv in tvl ] ) + tvl = target.module.typedVarList( target.module.g_listHead, "listStruct", "next.flink" ) + self.assertEqual( 5, len( tvl ) ) + self.assertEqual( range(5), [ tv.num for tv in tvl ] ) - tvl = pykd.typedVarList( target.module.g_listHead, target.module.type("listStruct"), "listEntry" ) - self.assertEqual( 3, len( tvl ) ) - self.assertEqual( [1,2,3], [ tv.num for tv in tvl ] ) + tvl = pykd.typedVarList( target.module.g_listHead, target.module.type("listStruct"), "next.flink" ) + self.assertEqual( 5, len( tvl ) ) + self.assertEqual( range(5), [ tv.num for tv in tvl ] ) - tvl = pykd.typedVarList( target.module.g_listHead, target.module.type("listStruct"), "listEntry.Flink" ) - self.assertEqual( 3, len( tvl ) ) - self.assertEqual( [1,2,3], [ tv.num for tv in tvl ] ) + tvl = pykd.typedVarList( target.module.g_listHead, target.module.type("listStruct"), "next.flink" ) + self.assertEqual( 5, len( tvl ) ) + self.assertEqual( range(5), [ tv.num for tv in tvl ] ) - tvl = target.module.typedVarList( target.module.g_listHead1, "listStruct1", "next" ) - self.assertEqual( 3, len( tvl ) ) - self.assertEqual( [100,200,300], [ tv.num for tv in tvl ] ) + #tvl = target.module.typedVarList( target.module.g_listHead1, "listStruct1", "next" ) + #self.assertEqual( 3, len( tvl ) ) + #self.assertEqual( [100,200,300], [ tv.num for tv in tvl ] ) - tvl = pykd.typedVarList( target.module.g_listHead1, target.module.type("listStruct1"), "next" ) - self.assertEqual( 3, len( tvl ) ) - self.assertEqual( [100,200,300], [ tv.num for tv in tvl ] ) + #tvl = pykd.typedVarList( target.module.g_listHead1, target.module.type("listStruct1"), "next" ) + #self.assertEqual( 3, len( tvl ) ) + #self.assertEqual( [100,200,300], [ tv.num for tv in tvl ] ) - tvl = pykd.typedVarList( target.module.g_childListHead, target.module.type("ChildEntryTest"), "m_next" ) - self.assertEqual( 3, len( 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 ] ) + #tvl = pykd.typedVarList( target.module.g_childListHead, target.module.type("ChildEntryTest"), "m_next" ) + #self.assertEqual( 3, len( 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 ] ) - tvl1 = target.module.typedVarList( target.module.g_listHead, "listStruct", "listEntry" ) - tvl2 = pykd.typedVarList( target.module.g_listHead, target.moduleName + "!listStruct", "listEntry" ) - self.assertEqual( tvl1, tvl2 ) + #tvl1 = target.module.typedVarList( target.module.g_listHead, "listStruct", "listEntry" ) + #tvl2 = pykd.typedVarList( target.module.g_listHead, target.moduleName + "!listStruct", "listEntry" ) + #self.assertEqual( tvl1, tvl2 ) def testTypedVarArray(self): tvl = target.module.typedVarArray( target.module.g_testArray, "structTest", 2 ) @@ -317,9 +317,3 @@ class TypedVarTest( unittest.TestCase ): for i in range( 0, 100000 ): lst.append(entry) entry = entry.deref().Flink - - def testWrongArgs(self): - self.assertRaises( pykd.TypeException, pykd.typedVar, None, 0 ) - self.assertRaises( pykd.TypeException, pykd.typedVarList, target.module.g_listHead1, None, "next" ) - self.assertRaises( pykd.TypeException, pykd.typedVarArray, target.module.g_testArray, None, 2 ) - self.assertRaises( pykd.TypeException, pykd.containingRecord, target.module.offset( "g_structTest" ), None, "m_field2" )