mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-21 12:53: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 "dbgcmd.h"
|
||||
#include "dbgevent.h"
|
||||
#include "typeinfo.h"
|
||||
#include "typedvar.h"
|
||||
|
||||
using namespace pykd;
|
||||
|
||||
@ -125,6 +127,19 @@ BOOST_PYTHON_MODULE( pykd )
|
||||
.def( "field", &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 )
|
||||
.def("begin", &pykd::Module::getBase,
|
||||
"Return start address of the module" )
|
||||
@ -146,6 +161,10 @@ 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::getTypedVarByName,
|
||||
"Return a typedVar class instance" )
|
||||
.def("__getattr__", &pykd::Module::getSymbol,
|
||||
"Return address of the symbol" );
|
||||
|
||||
|
@ -153,14 +153,27 @@ Module::reloadSymbols()
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
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
|
||||
return TypeInfo( typeSym );
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TypedVar
|
||||
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 "diawrapper.h"
|
||||
#include "typeinfo.h"
|
||||
#include "typedvar.h"
|
||||
|
||||
namespace pykd {
|
||||
|
||||
@ -66,7 +67,11 @@ public:
|
||||
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:
|
||||
|
||||
|
@ -437,6 +437,10 @@
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\typeinfo.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
@ -499,6 +503,10 @@
|
||||
RelativePath=".\stdafx.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\typedvar.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
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
|
||||
|
||||
#include "dbgobj.h"
|
||||
#include <string>
|
||||
|
||||
#include "diawrapper.h"
|
||||
|
||||
namespace pykd {
|
||||
@ -11,9 +12,11 @@ class TypeInfo {
|
||||
|
||||
public:
|
||||
|
||||
TypeInfo( pyDia::SymbolPtr dia ) :
|
||||
m_dia( dia ),
|
||||
m_offset( 0 )
|
||||
TypeInfo( pyDia::GlobalScopePtr &diaScope, const std::string &symName );
|
||||
|
||||
TypeInfo( pyDia::SymbolPtr &diaType ) :
|
||||
m_offset( 0 ),
|
||||
m_dia( diaType )
|
||||
{}
|
||||
|
||||
TypeInfo
|
||||
@ -25,20 +28,16 @@ public:
|
||||
}
|
||||
|
||||
std::string
|
||||
getName() {
|
||||
return m_dia->isBasicType() ?
|
||||
m_dia->getBasicTypeName( m_dia->getBaseType() ) :
|
||||
m_dia->getName();
|
||||
}
|
||||
getName();
|
||||
|
||||
ULONG
|
||||
getOffset() {
|
||||
return m_offset;
|
||||
}
|
||||
|
||||
ULONG64
|
||||
ULONG
|
||||
getSize() {
|
||||
return m_dia->getSize();
|
||||
return (ULONG)m_dia->getSize();
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -19,6 +19,7 @@ import diatest
|
||||
import dbgcmd
|
||||
import clienttest
|
||||
import eventtest
|
||||
import typedvar
|
||||
|
||||
def getTestSuite( singleName = "" ):
|
||||
if singleName == "":
|
||||
@ -27,6 +28,7 @@ def getTestSuite( singleName = "" ):
|
||||
unittest.TestLoader().loadTestsFromTestCase( moduletest.ModuleTest ),
|
||||
unittest.TestLoader().loadTestsFromTestCase( diatest.DiaTest ),
|
||||
unittest.TestLoader().loadTestsFromTestCase( typeinfo.TypeInfoTest ),
|
||||
unittest.TestLoader().loadTestsFromTestCase( typedvar.TypedVarTest ),
|
||||
unittest.TestLoader().loadTestsFromTestCase( dbgcmd.DbgcmdTest ),
|
||||
unittest.TestLoader().loadTestsFromTestCase( clienttest.DbgClientTest ),
|
||||
unittest.TestLoader().loadTestsFromTestCase( eventtest.EventTest )
|
||||
@ -48,5 +50,6 @@ if __name__ == "__main__":
|
||||
target.module.reload();
|
||||
|
||||
suite = getTestSuite()
|
||||
#suite = getTestSuite( "typedvar.TypedVarTest.testCtor" )
|
||||
|
||||
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() )
|
@ -30,6 +30,14 @@ class TypeInfoTest( unittest.TestCase ):
|
||||
self.assertEqual( "classChild", ti1.name() )
|
||||
self.assertEqual( "Int", ti1.m_childField.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 ):
|
||||
ti1 = target.module.type( "structTest" )
|
||||
|
@ -48,6 +48,11 @@ struct structTest {
|
||||
|
||||
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 {
|
||||
public:
|
||||
int m_childField;
|
||||
@ -79,6 +84,9 @@ void FuncWithName0()
|
||||
std::cout << g_ulonglongValue;
|
||||
|
||||
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)
|
||||
|
@ -436,6 +436,10 @@
|
||||
RelativePath="..\scripts\target.py"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\scripts\typedvar.py"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\scripts\typeinfo.py"
|
||||
>
|
||||
|
Loading…
Reference in New Issue
Block a user