[0.1.x] added : module.typedVarList method ( insread of global typedVarList routine )

git-svn-id: https://pykd.svn.codeplex.com/svn@72361 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
SND\kernelnet_cp 2011-12-15 10:34:03 +00:00 committed by Mikhail I. Izmestev
parent 8b43bd9e8e
commit 4b207aa77c
9 changed files with 248 additions and 64 deletions

View File

@ -172,8 +172,6 @@ public:
ULONG64 ptrPtr( ULONG64 offset );
void readMemory( ULONG64 address, PVOID buffer, ULONG length, bool phyAddr = FALSE );
python::object getRegByName( const std::wstring &regName );
python::object getRegByIndex( ULONG index );
@ -182,7 +180,6 @@ public:
void waitForEvent();
void writeMemory( ULONG64 address, PVOID buffer, ULONG length, bool phyAddr = FALSE );
public:

View File

@ -78,6 +78,7 @@ BOOST_PYTHON_FUNCTION_OVERLOADS( loadSignWords_, loadSignWords, 2, 3 );
BOOST_PYTHON_FUNCTION_OVERLOADS( loadSignDWords_, loadSignDWords, 2, 3 );
BOOST_PYTHON_FUNCTION_OVERLOADS( loadSignQWords_, loadSignQWords, 2, 3 );
BOOST_PYTHON_FUNCTION_OVERLOADS( compareMemory_, compareMemory, 3, 4 );
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( DebugClient_loadChars, DebugClient::loadChars, 2, 3 );
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( DebugClient_loadWChars, DebugClient::loadWChars, 2, 3 );
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( DebugClient_loadBytes, DebugClient::loadBytes, 2, 3 );
@ -337,11 +338,11 @@ BOOST_PYTHON_MODULE( pykd )
"Read an unsigned 1-byte integer from the target memory" );
python::def( "ptrWord", &ptrWord,
"Read an unsigned 2-byte integer from the target memory" );
python::def( "ptrDWord", &ptrDWord,
python::def( "ptrDWord", (ULONG64(*)(ULONG64))&ptrDWord,
"Read an unsigned 4-byte integer from the target memory" );
python::def( "ptrQWord", &ptrQWord,
python::def( "ptrQWord", (ULONG64(*)(ULONG64))&ptrQWord,
"Read an unsigned 8-byte integer from the target memory" );
python::def( "ptrMWord", &ptrMWord,
python::def( "ptrMWord", (ULONG64(*)(ULONG64))&ptrMWord,
"Read an unsigned mashine's word wide integer from the target memory" );
python::def( "ptrSignByte", &ptrSignByte,
"Read an signed 1-byte integer from the target memory" );
@ -353,9 +354,8 @@ BOOST_PYTHON_MODULE( pykd )
"Read an signed 8-byte integer from the target memory" );
python::def( "ptrSignMWord", &ptrSignMWord,
"Read an signed mashine's word wide integer from the target memory" );
python::def( "ptrPtr", &ptrPtr,
python::def( "ptrPtr", (ULONG64(*)(ULONG64))&ptrPtr,
"Read an pointer value from the target memory" );
boost::python::def( "addSynSymbol", &addSyntheticSymbol,
"Add new synthetic symbol for virtual address" );
boost::python::def( "delAllSynSymbols", &delAllSyntheticSymbols,
@ -447,7 +447,14 @@ BOOST_PYTHON_MODULE( pykd )
"Return a typedVar class instance" )
.def("typedVar",&Module::getTypedVarByTypeName,
"Return a typedVar class instance" )
.def("containingRecord", &Module::contaningRecord,
.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("typedVarList", &Module::getTypedVarListByType,
"Return a list of the typedVar class instances. Each item represents an item of the linked list in the target memory" )
.def("containingRecord", &Module::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" )
.def("containingRecord", &Module::containingRecordByType,
"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" )
.def("__getattr__", &Module::getSymbol,

View File

@ -26,7 +26,7 @@ DebugClient::loadArray( ULONG64 offset, ULONG count, bool phyAddr )
std::vector<T> buffer(count);
if (count)
readMemory( offset, &buffer[0], count*sizeof(T), phyAddr );
readMemory( m_dataSpaces, offset, &buffer[0], count*sizeof(T), phyAddr );
python::list lst;
@ -73,31 +73,70 @@ addr64( ULONG64 addr)
/////////////////////////////////////////////////////////////////////////////////////
void DebugClient::readMemory( ULONG64 address, PVOID buffer, ULONG length, bool phyAddr )
void
readMemory( IDebugDataSpaces4* dbgDataSpace, ULONG64 address, PVOID buffer, ULONG length, bool phyAddr = FALSE )
{
HRESULT hres;
if ( phyAddr == false )
{
hres = m_dataSpaces->ReadVirtual( address, buffer, length, NULL );
hres = dbgDataSpace->ReadVirtual( address, buffer, length, NULL );
}
else
{
hres = m_dataSpaces->ReadPhysical( address, buffer, length, NULL );
hres = dbgDataSpace->ReadPhysical( address, buffer, length, NULL );
}
if ( FAILED( hres ) )
throw MemoryException( address, phyAddr );
}
void readMemory( ULONG64 address, PVOID buffer, ULONG length, bool phyAddr )
{
return g_dbgClient->readMemory( address, buffer, length, phyAddr );
}
//void DebugClient::readMemory( ULONG64 address, PVOID buffer, ULONG length, bool phyAddr )
//{
// HRESULT hres;
//
// if ( phyAddr == false )
// {
// hres = m_dataSpaces->ReadVirtual( address, buffer, length, NULL );
// }
// else
// {
// hres = m_dataSpaces->ReadPhysical( address, buffer, length, NULL );
// }
//
// if ( FAILED( hres ) )
// throw MemoryException( address, phyAddr );
//}
//
//void readMemory( ULONG64 address, PVOID buffer, ULONG length, bool phyAddr )
//{
// return g_dbgClient->readMemory( address, buffer, length, phyAddr );
//}
/////////////////////////////////////////////////////////////////////////////////////
bool DebugClient::compareMemory( ULONG64 addr1, ULONG64 addr2, ULONG length, bool phyAddr )
//bool DebugClient::compareMemory( ULONG64 addr1, ULONG64 addr2, ULONG length, bool phyAddr )
//{
// bool result = false;
//
// addr1 = addr64( addr1 );
// addr2 = addr64( addr2 );
//
// std::vector<char> m1(length);
// std::vector<char> m2(length);
//
// readMemory( addr1, &m1[0], length, phyAddr );
// readMemory( addr2, &m2[0], length, phyAddr );
//
// return std::equal( m1.begin(), m1.end(), m2.begin() );
//}
//
//bool compareMemory( ULONG64 addr1, ULONG64 addr2, ULONG length, bool phyAddr )
//{
// return g_dbgClient->compareMemory( addr1, addr2, length, phyAddr );
//}
bool compareMemoryRange( IDebugDataSpaces4* dbgDataSpace, ULONG64 addr1, ULONG64 addr2, ULONG length, bool phyAddr )
{
bool result = false;
@ -107,17 +146,12 @@ bool DebugClient::compareMemory( ULONG64 addr1, ULONG64 addr2, ULONG length, boo
std::vector<char> m1(length);
std::vector<char> m2(length);
readMemory( addr1, &m1[0], length, phyAddr );
readMemory( addr2, &m2[0], length, phyAddr );
readMemory( dbgDataSpace, addr1, &m1[0], length, phyAddr );
readMemory( dbgDataSpace, addr2, &m2[0], length, phyAddr );
return std::equal( m1.begin(), m1.end(), m2.begin() );
}
bool compareMemory( ULONG64 addr1, ULONG64 addr2, ULONG length, bool phyAddr )
{
return g_dbgClient->compareMemory( addr1, addr2, length, phyAddr );
}
/////////////////////////////////////////////////////////////////////////////////////
std::string DebugClient::loadChars( ULONG64 address, ULONG number, bool phyAddr )
@ -127,7 +161,7 @@ std::string DebugClient::loadChars( ULONG64 address, ULONG number, bool phyAddr
ULONG bufferSize = (ULONG)( sizeof(std::vector<char>::value_type)*buffer.size() );
if (number)
readMemory( address, &buffer[0], bufferSize, phyAddr );
readMemory( m_dataSpaces, address, &buffer[0], bufferSize, phyAddr );
return std::string( buffer.begin(), buffer.end() );
}
@ -146,7 +180,7 @@ std::wstring DebugClient::loadWChars( ULONG64 address, ULONG number, bool phyAd
ULONG bufferSize = (ULONG)( sizeof(std::vector<wchar_t>::value_type)*buffer.size() );
if (number)
readMemory( address, &buffer[0], bufferSize, phyAddr );
readMemory( m_dataSpaces, address, &buffer[0], bufferSize, phyAddr );
return std::wstring( buffer.begin(), buffer.end() );
}
@ -316,7 +350,7 @@ ULONG64 DebugClient::ptrByte( ULONG64 offset )
{
unsigned char val = 0;
readMemory( offset, &val, sizeof(val), false );
readMemory( m_dataSpaces, offset, &val, sizeof(val), false );
return val;
}
@ -332,7 +366,7 @@ ULONG64 DebugClient::ptrWord( ULONG64 offset )
{
unsigned short val = 0;
readMemory( offset, &val, sizeof(val), false );
readMemory( m_dataSpaces, offset, &val, sizeof(val), false );
return val;
}
@ -344,31 +378,41 @@ ULONG64 ptrWord( ULONG64 offset )
/////////////////////////////////////////////////////////////////////////////////////
ULONG64 DebugClient::ptrDWord( ULONG64 offset )
ULONG64 ptrDWord( ULONG64 offset, IDebugDataSpaces4* dbgDataSpace )
{
unsigned long val = 0;
readMemory( offset, &val, sizeof(val), false );
readMemory( dbgDataSpace, offset, &val, sizeof(val), false );
return val;
}
ULONG64 DebugClient::ptrDWord( ULONG64 offset )
{
return pykd::ptrDWord( offset, m_dataSpaces );
}
ULONG64 ptrDWord( ULONG64 offset )
{
return g_dbgClient->ptrDWord( offset );
return g_dbgClient->ptrDWord( offset );
}
/////////////////////////////////////////////////////////////////////////////////////
ULONG64 DebugClient::ptrQWord( ULONG64 offset )
ULONG64 ptrQWord( ULONG64 offset, IDebugDataSpaces4* dbgDataSpace )
{
unsigned __int64 val = 0;
readMemory( offset, &val, sizeof(val), false );
readMemory( dbgDataSpace, offset, &val, sizeof(val), false );
return val;
}
ULONG64 DebugClient::ptrQWord( ULONG64 offset )
{
return pykd::ptrQWord( offset, m_dataSpaces );
}
ULONG64 ptrQWord( ULONG64 offset )
{
return g_dbgClient->ptrQWord( offset );
@ -376,6 +420,11 @@ ULONG64 ptrQWord( ULONG64 offset )
/////////////////////////////////////////////////////////////////////////////////////
ULONG64 ptrMWord( ULONG64 offset, IDebugDataSpaces4* dbgDataSpace )
{
return ptrSize() == 8 ? ptrQWord( offset, dbgDataSpace ) : ptrDWord(offset, dbgDataSpace);
}
ULONG64 DebugClient::ptrMWord( ULONG64 offset )
{
return ptrSize() == 8 ? ptrQWord( offset ) : ptrDWord(offset);
@ -386,14 +435,21 @@ ULONG64 ptrMWord( ULONG64 offset )
return g_dbgClient->ptrMWord( offset );
}
/////////////////////////////////////////////////////////////////////////////////////
ULONG64 ptrPtr( ULONG64 offset, IDebugDataSpaces4* dbgDataSpace )
{
return ptrMWord( offset, dbgDataSpace );
}
ULONG64 DebugClient::ptrPtr( ULONG64 offset )
{
return ptrMWord( offset );
return pykd::ptrPtr( offset, m_dataSpaces );
}
ULONG64 ptrPtr( ULONG64 offset )
{
return g_dbgClient->ptrMWord( offset );
return g_dbgClient->ptrPtr( offset );
}
/////////////////////////////////////////////////////////////////////////////////////
@ -402,7 +458,7 @@ LONG64 DebugClient::ptrSignByte( ULONG64 offset )
{
char val = 0;
readMemory( offset, &val, sizeof(val), false );
readMemory( m_dataSpaces, offset, &val, sizeof(val), false );
return val;
}
@ -418,7 +474,7 @@ LONG64 DebugClient::ptrSignWord( ULONG64 offset )
{
short val = 0;
readMemory( offset, &val, sizeof(val), false );
readMemory( m_dataSpaces, offset, &val, sizeof(val), false );
return val;
}
@ -434,7 +490,7 @@ LONG64 DebugClient::ptrSignDWord( ULONG64 offset )
{
long val = 0;
readMemory( offset, &val, sizeof(val), false );
readMemory( m_dataSpaces, offset, &val, sizeof(val), false );
return val;
}
@ -450,7 +506,7 @@ LONG64 DebugClient::ptrSignQWord( ULONG64 offset )
{
__int64 val = 0;
readMemory( offset, &val, sizeof(val), false );
readMemory( m_dataSpaces, offset, &val, sizeof(val), false );
return val;
}
@ -474,5 +530,17 @@ LONG64 ptrSignMWord( ULONG64 offset )
/////////////////////////////////////////////////////////////////////////////////////
bool DebugClient::compareMemory( ULONG64 addr1, ULONG64 addr2, ULONG length, bool phyAddr )
{
return compareMemoryRange( m_dataSpaces, addr1, addr2, length, phyAddr );
}
bool compareMemory( ULONG64 addr1, ULONG64 addr2, ULONG length, bool phyAddr )
{
return g_dbgClient->compareMemory( addr1, addr2, length, phyAddr );
}
/////////////////////////////////////////////////////////////////////////////////////
}; // end of pykd

View File

@ -1,5 +1,7 @@
#pragma once
#include <dbgeng.h>
namespace pykd {
///////////////////////////////////////////////////////////////////////////////////
@ -10,13 +12,13 @@ addr64( ULONG64 addr );
///////////////////////////////////////////////////////////////////////////////////
void
readMemory( ULONG64 address, PVOID buffer, ULONG length, BOOLEAN phyAddr = FALSE );
readMemory( IDebugDataSpaces4* dbgDataSpace, ULONG64 address, PVOID buffer, ULONG length, bool phyAddr = FALSE );
void
writeMemory( ULONG64 address, PVOID buffer, ULONG length, BOOLEAN phyAddr = FALSE );
writeMemory( IDebugDataSpaces4* dbgDataSpace, ULONG64 address, PVOID buffer, ULONG length, bool phyAddr = FALSE );
bool
compareMemory( ULONG64 addr1, ULONG64 addr2, ULONG length, bool phyAddr = FALSE );
compareMemoryRange( IDebugDataSpaces4* dbgDataSpace, ULONG64 addr1, ULONG64 addr2, ULONG length, bool phyAddr = FALSE );
///////////////////////////////////////////////////////////////////////////////////
@ -50,10 +52,16 @@ ULONG64 ptrWord( ULONG64 offset );
ULONG64 ptrDWord( ULONG64 offset );
ULONG64 ptrDWord( ULONG64 offset, IDebugDataSpaces4* dbgDataSpace );
ULONG64 ptrQWord( ULONG64 offset );
ULONG64 ptrQWord( ULONG64 offset, IDebugDataSpaces4* dbgDataSpace );
ULONG64 ptrMWord( ULONG64 offset );
ULONG64 ptrMWord( ULONG64 offset, IDebugDataSpaces4* dbgDataSpace );
LONG64 ptrSignByte( ULONG64 offset );
LONG64 ptrSignWord( ULONG64 offset );
@ -66,6 +74,11 @@ LONG64 ptrSignMWord( ULONG64 offset );
ULONG64 ptrPtr( ULONG64 offset );
ULONG64 ptrPtr( ULONG64 offset, IDebugDataSpaces4* dbgDataSpace );
bool
compareMemory( ULONG64 addr1, ULONG64 addr2, ULONG length, bool phyAddr = FALSE );
///////////////////////////////////////////////////////////////////////////////////
};

View File

@ -219,7 +219,7 @@ ULONG Module::getRvaByName(const std::string &symName)
///////////////////////////////////////////////////////////////////////////////////
TypedVarPtr Module::contaningRecord( ULONG64 address, const std::string &typeName, const std::string &fieldName )
TypedVarPtr Module::containingRecordByName( ULONG64 address, const std::string &typeName, const std::string &fieldName )
{
address = addr64(address);
@ -228,29 +228,51 @@ TypedVarPtr Module::contaningRecord( ULONG64 address, const std::string &typeNam
TypeInfoPtr fieldTypeInfo = typeInfo->getField( fieldName );
return TypedVar::getTypedVar( m_client, typeInfo, address - fieldTypeInfo->getOffset() );
}
///////////////////////////////////////////////////////////////////////////////////
TypedVarPtr Module::containingRecordByType( ULONG64 address, const TypeInfoPtr &typeInfo, const std::string &fieldName )
{
address = addr64(address);
TypeInfoPtr fieldTypeInfo = typeInfo->getField( fieldName );
return TypedVar::getTypedVar( m_client, typeInfo, address - fieldTypeInfo->getOffset() );
}
//HRESULT hres;
//ULONG64 moduleBase;
///////////////////////////////////////////////////////////////////////////////////
//hres = dbgExt->symbols->GetModuleByModuleName( moduleName.c_str(), 0, NULL, &moduleBase );
//if ( FAILED( hres ) )
// throw TypeException();
python::list Module::getTypedVarListByTypeName( ULONG64 listHeadAddress, const std::string &typeName, const std::string &listEntryName )
{
return getTypedVarListByType( listHeadAddress, getTypeByName( typeName ), listEntryName );
}
//ULONG typeId;
//hres = dbgExt->symbols->GetTypeId( moduleBase, typeName.c_str(), &typeId );
//if ( FAILED( hres ) )
// throw TypeException();
///////////////////////////////////////////////////////////////////////////////////
//ULONG fieldTypeId;
//ULONG fieldOffset;
//hres = dbgExt->symbols3->GetFieldTypeAndOffset( moduleBase, typeId, fieldName.c_str(), &fieldTypeId, &fieldOffset );
//if ( FAILED( hres ) )
// throw TypeException();
//
//TypedVar var( moduleName, typeName, address - fieldOffset );
//
//return boost::python::object( var );
python::list Module::getTypedVarListByType( ULONG64 listHeadAddress, const TypeInfoPtr &typeInfo, const std::string &listEntryName )
{
python::list lst;
listHeadAddress = addr64( listHeadAddress );
ULONG64 entryAddress = 0;
TypeInfoPtr fieldTypeInfo = typeInfo->getField( listEntryName );
if ( fieldTypeInfo->getName() == ( typeInfo->getName() + "*" ) )
{
for( entryAddress = ptrPtr( listHeadAddress ); entryAddress != listHeadAddress && entryAddress != NULL; entryAddress = ptrPtr( entryAddress + fieldTypeInfo->getOffset() ) )
lst.append( getTypedVarByType( typeInfo, entryAddress ) );
}
else
{
for( entryAddress = ptrPtr( listHeadAddress ); entryAddress != listHeadAddress && entryAddress != NULL; entryAddress = ptrPtr( entryAddress ) )
lst.append( containingRecordByType( entryAddress, typeInfo, listEntryName ) );
}
return lst;
}
///////////////////////////////////////////////////////////////////////////////////

View File

@ -68,7 +68,13 @@ public:
TypedVarPtr getTypedVarByName( const std::string &symName );
TypedVarPtr contaningRecord( ULONG64 addr, const std::string &typeName, const std::string &fieldName );
TypedVarPtr containingRecordByName( ULONG64 addr, const std::string &typeName, const std::string &fieldName );
TypedVarPtr containingRecordByType( ULONG64 addr, const TypeInfoPtr &typeInfo, const std::string &fieldName );
python::list getTypedVarListByTypeName( ULONG64 listHeadAddres, const std::string &typeName, const std::string &listEntryName );
python::list getTypedVarListByType( ULONG64 listHeadAddres, const TypeInfoPtr &typeInfo, const std::string &listEntryName );
private:

View File

@ -57,8 +57,11 @@ if __name__ == "__main__":
target.module = pykd.loadModule( target.moduleName )
target.module.reload();
pykd.go()
suite = getTestSuite()
#suite = getTestSuite( "typeinfo.TypeInfoTest.testCreateBySymbol" )
#suite = getTestSuite( "typedvar.TypedVarTest.testBitField" )
#suite = getTestSuite( "typeinfo.TypeInfoTest.testBitField" )
unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run( suite )

View File

@ -72,3 +72,21 @@ class TypedVarTest( unittest.TestCase ):
def testBitField(self):
tv = target.module.typedVar("g_structWithBits")
self.assertEqual( 4, tv.m_bit0_4 )
def testTypeVarList(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, target.module.type("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_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, target.module.type("listStruct1"), "next" )
self.assertEqual( 3, len( tvl ) )
self.assertEqual( [100,200,300], [ tv.num for tv in tvl ] )

View File

@ -109,6 +109,47 @@ struct3 g_struct3 = { { 0, 2 }, 3 };
__int64 g_bigValue = 0x8080808080808080;
static LIST_ENTRY g_listHead;
struct listStruct {
int num;
LIST_ENTRY listEntry;
};
listStruct g_listItem1 = { 1 };
listStruct g_listItem2 = { 2 };
listStruct g_listItem3 = { 3 };
struct listStruct1;
static listStruct1 *g_listHead1 = NULL;
struct listStruct1 {
int num;
struct listStruct1 *next;
};
listStruct1 g_listItem11 = { 100 };
listStruct1 g_listItem12 = { 200 };
listStruct1 g_listItem13 = { 300 };
#define InitializeListHead(ListHead) (\
(ListHead)->Flink = (ListHead)->Blink = (ListHead))
#define InsertTailList(ListHead,Entry) {\
PLIST_ENTRY _EX_Blink;\
PLIST_ENTRY _EX_ListHead;\
_EX_ListHead = (ListHead);\
_EX_Blink = _EX_ListHead->Blink;\
(Entry)->Flink = _EX_ListHead;\
(Entry)->Blink = _EX_Blink;\
_EX_Blink->Flink = (Entry);\
_EX_ListHead->Blink = (Entry);\
}
void FuncWithName0()
{
classChild _classChild;
@ -176,6 +217,15 @@ int _tmain(int argc, _TCHAR* argv[])
{
try
{
InitializeListHead( &g_listHead );
InsertTailList( &g_listHead, &g_listItem1.listEntry );
InsertTailList( &g_listHead, &g_listItem2.listEntry );
InsertTailList( &g_listHead, &g_listItem3.listEntry );
g_listHead1 = &g_listItem11;
g_listItem11.next = &g_listItem12;
g_listItem12.next = &g_listItem13;
// Let test scripts to execute
__debugbreak();