[0.1.x] added : typedVar class

git-svn-id: https://pykd.svn.codeplex.com/svn@70618 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
SND\kernelnet_cp 2011-10-19 08:13:02 +00:00 committed by Mikhail I. Izmestev
parent 8c14fd3208
commit 379e97abf3
12 changed files with 217 additions and 25 deletions

View File

@ -13,6 +13,8 @@
#include "dbgpath.h" #include "dbgpath.h"
#include "dbgcmd.h" #include "dbgcmd.h"
#include "dbgevent.h" #include "dbgevent.h"
#include "typeinfo.h"
#include "typedvar.h"
using namespace pykd; using namespace pykd;
@ -125,6 +127,19 @@ BOOST_PYTHON_MODULE( pykd )
.def( "field", &pykd::TypeInfo::getField ) .def( "field", &pykd::TypeInfo::getField )
.def( "__getattr__", &pykd::TypeInfo::getField ); .def( "__getattr__", &pykd::TypeInfo::getField );
python::class_<pykd::TypedVar>("typedVar",
"Class of non-primitive type object, child class of typeClass. Data from target is copied into object instance",
python::no_init )
.def("getAddress", &pykd::TypedVar::getAddress,
"Return virtual address" )
.def("sizeof", &pykd::TypedVar::getSize,
"Return size of a variable in the target memory" );
//.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_<pykd::Module>("module", "Class representing executable module", python::no_init ) python::class_<pykd::Module>("module", "Class representing executable module", python::no_init )
.def("begin", &pykd::Module::getBase, .def("begin", &pykd::Module::getBase,
"Return start address of the module" ) "Return start address of the module" )
@ -146,6 +161,10 @@ BOOST_PYTHON_MODULE( pykd )
"Return rva of the symbol" ) "Return rva of the symbol" )
.def("type", &pykd::Module::getTypeByName, .def("type", &pykd::Module::getTypeByName,
"Return typeInfo class by type name" ) "Return typeInfo class by type name" )
.def("typedVar", &pykd::Module::getTypedVarByAddr,
"Return a typedVar class instance" )
.def("typedVar",&pykd::Module::getTypedVarByName,
"Return a typedVar class instance" )
.def("__getattr__", &pykd::Module::getSymbol, .def("__getattr__", &pykd::Module::getSymbol,
"Return address of the symbol" ); "Return address of the symbol" );

View File

@ -153,14 +153,27 @@ Module::reloadSymbols()
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
TypeInfo TypeInfo
Module::getTypeByName( const std::string typeName ) Module::getTypeByName( const std::string &typeName )
{ {
pyDia::SymbolPtr typeSym = m_dia->getChildByName( typeName ); return TypeInfo( m_dia, typeName );
}
if ( typeSym->getSymTag() == SymTagData ) ///////////////////////////////////////////////////////////////////////////////////
return TypeInfo( typeSym->getType() );
else TypedVar
return TypeInfo( typeSym ); Module::getTypedVarByAddr( const std::string &typeName, ULONG64 addr )
{
return TypedVar( TypeInfo( m_dia, typeName ), addr );
}
///////////////////////////////////////////////////////////////////////////////////
TypedVar
Module::getTypedVarByName( const std::string &symName )
{
pyDia::SymbolPtr typeSym = m_dia->getChildByName( symName );
return TypedVar( TypeInfo( typeSym->getType() ), typeSym->getRva() + m_base );
} }
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////

View File

@ -5,6 +5,7 @@
#include "dbgobj.h" #include "dbgobj.h"
#include "diawrapper.h" #include "diawrapper.h"
#include "typeinfo.h" #include "typeinfo.h"
#include "typedvar.h"
namespace pykd { namespace pykd {
@ -66,7 +67,11 @@ public:
return sym->getRva(); return sym->getRva();
} }
TypeInfo getTypeByName( const std::string typeName ); TypeInfo getTypeByName( const std::string &typeName );
TypedVar getTypedVarByAddr( const std::string &typeName, ULONG64 addr );
TypedVar getTypedVarByName( const std::string &symName );
private: private:

View File

@ -437,6 +437,10 @@
/> />
</FileConfiguration> </FileConfiguration>
</File> </File>
<File
RelativePath=".\typeinfo.cpp"
>
</File>
</Filter> </Filter>
<Filter <Filter
Name="Header Files" Name="Header Files"
@ -499,6 +503,10 @@
RelativePath=".\stdafx.h" RelativePath=".\stdafx.h"
> >
</File> </File>
<File
RelativePath=".\typedvar.h"
>
</File>
<File <File
RelativePath=".\typeinfo.h" RelativePath=".\typeinfo.h"
> >

35
pykd/typedvar.h Normal file
View File

@ -0,0 +1,35 @@
#pragma once
#include "typeinfo.h"
namespace pykd {
///////////////////////////////////////////////////////////////////////////////////
class TypedVar {
public:
TypedVar ( const TypeInfo& typeInfo, ULONG64 offset ) :
m_typeInfo( typeInfo ),
m_offset( offset )
{}
ULONG64 getAddress() const {
return m_offset;
}
ULONG getSize() {
return m_typeInfo.getSize();
}
private:
TypeInfo m_typeInfo;
ULONG64 m_offset;
};
///////////////////////////////////////////////////////////////////////////////////
}; // namespace pykd

61
pykd/typeinfo.cpp Normal file
View File

@ -0,0 +1,61 @@
#include "stdafx.h"
#include "typeinfo.h"
namespace pykd {
///////////////////////////////////////////////////////////////////////////////////
TypeInfo::TypeInfo( pyDia::GlobalScopePtr &diaScope, const std::string &symName ) :
m_offset( 0 )
{
pyDia::SymbolPtr typeSym = diaScope->getChildByName( symName );
if ( typeSym->getSymTag() == SymTagData )
{
m_dia = typeSym->getType();
}
else
{
m_dia = typeSym;
}
}
///////////////////////////////////////////////////////////////////////////////////
std::string
TypeInfo::getName()
{
std::stringstream sstr;
pyDia::SymbolPtr diaptr = m_dia;
int symtag = diaptr->getSymTag();
while( symtag == SymTagArrayType || symtag == SymTagPointerType )
{
if ( symtag == SymTagArrayType )
{
sstr << '[' << diaptr->getCount() << ']';
}
else
{
sstr << '*';
}
diaptr = diaptr->getType();
symtag = diaptr->getSymTag();
}
std::string typeName = symtag == SymTagBaseType ?
diaptr->getBasicTypeName( diaptr->getBaseType() ) :
diaptr->getName();
typeName += sstr.str();
return typeName;
};
///////////////////////////////////////////////////////////////////////////////////
}; // end namespace pykd

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include "dbgobj.h" #include <string>
#include "diawrapper.h" #include "diawrapper.h"
namespace pykd { namespace pykd {
@ -11,10 +12,12 @@ class TypeInfo {
public: public:
TypeInfo( pyDia::SymbolPtr dia ) : TypeInfo( pyDia::GlobalScopePtr &diaScope, const std::string &symName );
m_dia( dia ),
m_offset( 0 ) TypeInfo( pyDia::SymbolPtr &diaType ) :
{} m_offset( 0 ),
m_dia( diaType )
{}
TypeInfo TypeInfo
getField( const std::string &fieldName ) { getField( const std::string &fieldName ) {
@ -25,20 +28,16 @@ public:
} }
std::string std::string
getName() { getName();
return m_dia->isBasicType() ?
m_dia->getBasicTypeName( m_dia->getBaseType() ) :
m_dia->getName();
}
ULONG ULONG
getOffset() { getOffset() {
return m_offset; return m_offset;
} }
ULONG64 ULONG
getSize() { getSize() {
return m_dia->getSize(); return (ULONG)m_dia->getSize();
} }
private: private:
@ -50,4 +49,4 @@ private:
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
}; // namespace pykd }; // namespace pykd

View File

@ -19,6 +19,7 @@ import diatest
import dbgcmd import dbgcmd
import clienttest import clienttest
import eventtest import eventtest
import typedvar
def getTestSuite( singleName = "" ): def getTestSuite( singleName = "" ):
if singleName == "": if singleName == "":
@ -27,6 +28,7 @@ def getTestSuite( singleName = "" ):
unittest.TestLoader().loadTestsFromTestCase( moduletest.ModuleTest ), unittest.TestLoader().loadTestsFromTestCase( moduletest.ModuleTest ),
unittest.TestLoader().loadTestsFromTestCase( diatest.DiaTest ), unittest.TestLoader().loadTestsFromTestCase( diatest.DiaTest ),
unittest.TestLoader().loadTestsFromTestCase( typeinfo.TypeInfoTest ), unittest.TestLoader().loadTestsFromTestCase( typeinfo.TypeInfoTest ),
unittest.TestLoader().loadTestsFromTestCase( typedvar.TypedVarTest ),
unittest.TestLoader().loadTestsFromTestCase( dbgcmd.DbgcmdTest ), unittest.TestLoader().loadTestsFromTestCase( dbgcmd.DbgcmdTest ),
unittest.TestLoader().loadTestsFromTestCase( clienttest.DbgClientTest ), unittest.TestLoader().loadTestsFromTestCase( clienttest.DbgClientTest ),
unittest.TestLoader().loadTestsFromTestCase( eventtest.EventTest ) unittest.TestLoader().loadTestsFromTestCase( eventtest.EventTest )
@ -48,5 +50,6 @@ if __name__ == "__main__":
target.module.reload(); target.module.reload();
suite = getTestSuite() suite = getTestSuite()
#suite = getTestSuite( "typedvar.TypedVarTest.testCtor" )
unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run( suite ) unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run( suite )

29
test/scripts/typedvar.py Normal file
View File

@ -0,0 +1,29 @@
#
#
#
import unittest
import target
import pykd
class TypedVarTest( unittest.TestCase ):
def testCtor( self ):
try: pykd.typedVar()
except RuntimeError: pass
try: pykd.typedVar( "structTest", target.module.g_structTest )
except RuntimeError: pass
tv = target.module.typedVar( "structTest", target.module.g_structTest )
tv = target.module.typedVar( "g_structTest" )
def testGetAddress( self ):
tv = target.module.typedVar( "structTest", target.module.g_structTest )
self.assertEqual( tv.getAddress(), target.module.g_structTest )
def testGetSize( self ):
tv1 = target.module.typedVar( "structTest", target.module.g_structTest )
self.assertEqual( 16, tv1.sizeof() )
#tv2 = target.module.typedVar( "structTest[]", target.module.g_testArray )
#self.assertEqual( tv1.sizeof()*2, tv2.sizeof() )

View File

@ -28,17 +28,25 @@ class TypeInfoTest( unittest.TestCase ):
def testName( self ): def testName( self ):
ti1 = target.module.type( "classChild" ) ti1 = target.module.type( "classChild" )
self.assertEqual( "classChild", ti1.name() ) self.assertEqual( "classChild", ti1.name() )
self.assertEqual( "Int", ti1.m_childField.name() ) self.assertEqual( "Int", ti1.m_childField.name() )
self.assertEqual( "structTest", ti1.m_childField3.name() ) self.assertEqual( "structTest", ti1.m_childField3.name() )
self.assertEqual( "structTest", target.module.type("g_structTest").name() )
def testArrayName( self ):
self.assertEqual( "structTest[2]", target.module.type("g_testArray").name() )
def testPtrName( self ):
self.assertEqual( "structTest*", target.module.type("g_structTestPtr").name() )
self.assertEqual( "structTest**", target.module.type("g_structTestPtrPtr").name() )
def testOffset( self ): def testOffset( self ):
ti1 = target.module.type( "structTest" ) ti1 = target.module.type( "structTest" )
self.assertEqual( 0, ti1.m_field0.offset() ) self.assertEqual( 0, ti1.m_field0.offset() )
self.assertEqual( 4, ti1.m_field1.offset() ) self.assertEqual( 4, ti1.m_field1.offset() )
self.assertEqual( 12, ti1.m_field2.offset() ) self.assertEqual( 12, ti1.m_field2.offset() )
self.assertEqual( 14, ti1.m_field3.offset() ) self.assertEqual( 14, ti1.m_field3.offset() )
def testSize( self ): def testSize( self ):
ti1 = target.module.type( "structTest" ) ti1 = target.module.type( "structTest" )
self.assertEqual( 16, ti1.size() ) self.assertEqual( 16, ti1.size() )

View File

@ -46,7 +46,12 @@ struct structTest {
USHORT m_field3; USHORT m_field3;
}; };
structTest g_structTest = { 0, 500, true, 1 }; structTest g_structTest = { 0, 500, true, 1 };
structTest g_testArray[2] = { { 0, 500, true, 1 }, { 2, 1500, false, 1 } };
structTest *g_structTestPtr = &g_structTest;
structTest **g_structTestPtrPtr = &g_structTestPtr;
class classChild : public classBase { class classChild : public classBase {
public: public:
@ -79,6 +84,9 @@ void FuncWithName0()
std::cout << g_ulonglongValue; std::cout << g_ulonglongValue;
std::cout << g_structTest.m_field0; std::cout << g_structTest.m_field0;
std::cout << g_testArray[1].m_field3;
std::cout << g_structTestPtr->m_field3;
std::cout << (*g_structTestPtrPtr)->m_field3;
} }
void FuncWithName1(int a) void FuncWithName1(int a)

View File

@ -436,6 +436,10 @@
RelativePath="..\scripts\target.py" RelativePath="..\scripts\target.py"
> >
</File> </File>
<File
RelativePath="..\scripts\typedvar.py"
>
</File>
<File <File
RelativePath="..\scripts\typeinfo.py" RelativePath="..\scripts\typeinfo.py"
> >