mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-20 03:23:23 +08:00
[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:
parent
8c14fd3208
commit
379e97abf3
@ -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" );
|
||||||
|
|
||||||
|
@ -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 );
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -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:
|
||||||
|
|
||||||
|
@ -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
35
pykd/typedvar.h
Normal 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
61
pykd/typeinfo.cpp
Normal 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
|
@ -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
|
||||||
|
@ -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
29
test/scripts/typedvar.py
Normal 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() )
|
@ -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() )
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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"
|
||||||
>
|
>
|
||||||
|
Loading…
Reference in New Issue
Block a user