[0.1.x] added : setCurrentProcess routine

[0.1.x] added : setImplicitThread routine
[0.1.x] added : setProcessorMode routine
[0.1.x] added : typedVarArray method of the module class


git-svn-id: https://pykd.svn.codeplex.com/svn@72698 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
SND\kernelnet_cp 2011-12-26 06:57:48 +00:00 committed by Mikhail I. Izmestev
parent 7c70e6d166
commit 8fd90cf647
10 changed files with 174 additions and 14 deletions

View File

@ -333,6 +333,29 @@ std::string getPdbFile( ULONG64 moduleBase )
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
std::string DebugClient::dbgSymPath()
{
HRESULT hres;
std::string pathStr;
ULONG size;
m_symbols->GetSymbolPath( NULL, 0, &size );
std::vector<char> path(size);
hres = m_symbols->GetSymbolPath( &path[0], size, NULL );
if ( FAILED( hres ) )
throw DbgException( "IDebugSymbols::GetSymbolPath failed" );
return std::string(&path[0],size);
}
std::string dbgSymPath()
{
return g_dbgClient->dbgSymPath();
}
///////////////////////////////////////////////////////////////////////////////////
void DebugClient::setExecutionStatus( ULONG status ) void DebugClient::setExecutionStatus( ULONG status )
{ {
HRESULT hres; HRESULT hres;

View File

@ -103,6 +103,8 @@ public:
std::string getProcessorType(); std::string getProcessorType();
std::string dbgSymPath();
python::list getThreadList(); python::list getThreadList();
template<ULONG status> template<ULONG status>
@ -194,8 +196,14 @@ public:
python::object getRegByIndex( ULONG index ); python::object getRegByIndex( ULONG index );
void setCurrentProcess( ULONG64 addr );
void setExecutionStatus( ULONG status ); void setExecutionStatus( ULONG status );
void setImplicitThread( ULONG64 threadAddr );
void setProcessorMode( const std::wstring &mode );
void terminateProcess(); void terminateProcess();
void waitForEvent(); void waitForEvent();
@ -298,6 +306,8 @@ ULONG64 getOffset( const std::wstring symbolname );
std::string getPdbFile( ULONG64 moduleBase ); std::string getPdbFile( ULONG64 moduleBase );
std::string dbgSymPath();
bool is64bitSystem(); bool is64bitSystem();
bool isKernelDebugging(); bool isKernelDebugging();

View File

@ -261,16 +261,24 @@ BOOST_PYTHON_MODULE( pykd )
"Return a CPU regsiter value by the register's name" ) "Return a CPU regsiter value by the register's name" )
.def( "reg", &DebugClient::getRegByIndex, .def( "reg", &DebugClient::getRegByIndex,
"Return a CPU regsiter value by the register's value" ) "Return a CPU regsiter value by the register's value" )
.def( "setCurrentProcess", &DebugClient::setCurrentProcess,
"Set current process by address" )
.def( "setExecutionStatus", &DebugClient::setExecutionStatus, .def( "setExecutionStatus", &DebugClient::setExecutionStatus,
"Requests that the debugger engine enter an executable state" ) "Requests that the debugger engine enter an executable state" )
.def( "wrmsr", &DebugClient::setMSR, .def( "setImplicitThread", &DebugClient::setImplicitThread,
"Set MSR value" ) "Set implicit thread for current process" )
.def( "setProcessorMode", &DebugClient::setProcessorMode,
"Set current processor mode by string (X86, ARM, IA64 or X64)" )
.def( "step", &DebugClient::changeDebuggerStatus<DEBUG_STATUS_STEP_OVER>, .def( "step", &DebugClient::changeDebuggerStatus<DEBUG_STATUS_STEP_OVER>,
"Change debugger status to DEBUG_STATUS_STEP_OVER" ) "Change debugger status to DEBUG_STATUS_STEP_OVER" )
.def( "symbolsPath", &DebugClient::dbgSymPath,
"Return symbol path" )
.def( "trace", &DebugClient::changeDebuggerStatus<DEBUG_STATUS_STEP_INTO>, .def( "trace", &DebugClient::changeDebuggerStatus<DEBUG_STATUS_STEP_INTO>,
"Change debugger status to DEBUG_STATUS_STEP_INTO" ) "Change debugger status to DEBUG_STATUS_STEP_INTO" )
.def( "waitForEvent", &DebugClient::waitForEvent, .def( "waitForEvent", &DebugClient::waitForEvent,
"Wait for events that breaks into the debugger" ) "Wait for events that breaks into the debugger" )
.def( "wrmsr", &DebugClient::setMSR,
"Set MSR value" )
.def( "addSynSymbol", &DebugClient::addSyntheticSymbol, .def( "addSynSymbol", &DebugClient::addSyntheticSymbol,
"Add new synthetic symbol for virtual address" ) "Add new synthetic symbol for virtual address" )
.def( "delAllSynSymbols", &DebugClient::delAllSyntheticSymbols, .def( "delAllSynSymbols", &DebugClient::delAllSyntheticSymbols,
@ -420,15 +428,23 @@ BOOST_PYTHON_MODULE( pykd )
"Return a CPU regsiter value by the register's name" ); "Return a CPU regsiter value by the register's name" );
python::def( "reg", &getRegByIndex, python::def( "reg", &getRegByIndex,
"Return a CPU regsiter value by the register's value" ); "Return a CPU regsiter value by the register's value" );
python::def( "setExecutionStatus", &pykd::setExecutionStatus, python::def( "setExecutionStatus", &setExecutionStatus,
"Requests that the debugger engine enter an executable state" ); "Requests that the debugger engine enter an executable state" );
python::def( "step", &pykd::changeDebuggerStatus<DEBUG_STATUS_STEP_OVER>, python::def( "setCurrentProcess", &setCurrentProcess,
"Set current process by address" );
python::def( "setImplicitThread", &setImplicitThread,
"Set implicit thread for current process" );
python::def( "setProcessorMode", &setProcessorMode,
"Set current processor mode by string (X86, ARM, IA64 or X64)" );
python::def( "step", &changeDebuggerStatus<DEBUG_STATUS_STEP_OVER>,
"Change debugger status to DEBUG_STATUS_STEP_OVER" ); "Change debugger status to DEBUG_STATUS_STEP_OVER" );
python::def( "symbolsPath", &dbgSymPath,
"Return symbol path" );
python::def( "wrmsr", &setMSR, python::def( "wrmsr", &setMSR,
"Set MSR value" ); "Set MSR value" );
python::def( "trace", &pykd::changeDebuggerStatus<DEBUG_STATUS_STEP_INTO>, python::def( "trace", &changeDebuggerStatus<DEBUG_STATUS_STEP_INTO>,
"Change debugger status to DEBUG_STATUS_STEP_INTO" ); "Change debugger status to DEBUG_STATUS_STEP_INTO" );
python::def( "waitForEvent", &pykd::waitForEvent, python::def( "waitForEvent", &waitForEvent,
"Wait for events that breaks into the debugger" ); "Wait for events that breaks into the debugger" );
python::class_<TypeInfo, TypeInfoPtr, boost::noncopyable >("typeInfo", "Class representing typeInfo", python::no_init ) python::class_<TypeInfo, TypeInfoPtr, boost::noncopyable >("typeInfo", "Class representing typeInfo", python::no_init )
@ -490,6 +506,10 @@ BOOST_PYTHON_MODULE( pykd )
"Return a list of the typedVar class instances. Each item represents an item of the linked list in the target memory" ) "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, .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" ) "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("typedVarArray", &Module::getTypedVarArrayByType,
"Return a list of the typedVar class instances. Each item represents an item of the counted array in the target memory" )
.def("containingRecord", &Module::containingRecordByName, .def("containingRecord", &Module::containingRecordByName,
"Return instance of the typedVar class. It's value are loaded from the target memory." "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" ) "The start address is calculated by the same method as the standard macro CONTAINING_RECORD does" )

View File

@ -277,5 +277,26 @@ python::list Module::getTypedVarListByType( ULONG64 listHeadAddress, const TypeI
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
python::list Module::getTypedVarArrayByTypeName( ULONG64 addr, const std::string &typeName, ULONG number )
{
return getTypedVarArrayByType( addr, getTypeByName( typeName ), number );
}
///////////////////////////////////////////////////////////////////////////////////
python::list Module::getTypedVarArrayByType( ULONG64 address, const TypeInfoPtr &typeInfo, ULONG number )
{
address = addr64(address);
python::list lst;
for( ULONG i = 0; i < number; ++i )
lst.append( getTypedVarByType( typeInfo, address + i * typeInfo->getSize() ) );
return lst;
}
///////////////////////////////////////////////////////////////////////////////////
}; // end of namespace pykd }; // end of namespace pykd

View File

@ -76,6 +76,11 @@ public:
python::list getTypedVarListByType( ULONG64 listHeadAddres, const TypeInfoPtr &typeInfo, const std::string &listEntryName ); python::list getTypedVarListByType( ULONG64 listHeadAddres, const TypeInfoPtr &typeInfo, const std::string &listEntryName );
python::list getTypedVarArrayByTypeName( ULONG64 addr, const std::string &typeName, ULONG number );
python::list getTypedVarArrayByType( ULONG64 addr, const TypeInfoPtr &typeInfo, ULONG number );
private: private:
ULONG getRvaByName(const std::string &symName); ULONG getRvaByName(const std::string &symName);

View File

@ -188,4 +188,66 @@ python::list getThreadList()
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
void DebugClient::setCurrentProcess( ULONG64 processAddr )
{
HRESULT hres;
processAddr = addr64(processAddr);
hres = m_system->SetImplicitProcessDataOffset( processAddr );
if ( FAILED( hres ) )
throw DbgException( "IDebugSystemObjects2::SetImplicitProcessDataOffset failed" );
}
void setCurrentProcess( ULONG64 processAddr )
{
g_dbgClient->setCurrentProcess( processAddr );
}
///////////////////////////////////////////////////////////////////////////////////
void DebugClient::setImplicitThread( ULONG64 threadAddr )
{
HRESULT hres;
threadAddr = addr64(threadAddr);
hres = m_system->SetImplicitThreadDataOffset( threadAddr );
if ( FAILED( hres ) )
throw DbgException( "IDebugSystemObjects2::SetImplicitThreadDataOffset failed" );
}
void setImplicitThread( ULONG64 threadAddr )
{
g_dbgClient->setImplicitThread( threadAddr );
}
///////////////////////////////////////////////////////////////////////////////////
void DebugClient::setProcessorMode( const std::wstring &mode )
{
HRESULT hres;
ULONG processorMode;
if ( mode == L"X86" )
processorMode = IMAGE_FILE_MACHINE_I386;
else if ( mode == L"ARM" )
processorMode = IMAGE_FILE_MACHINE_ARM;
else if ( mode == L"IA64" )
processorMode = IMAGE_FILE_MACHINE_IA64;
else if ( mode == L"X64" )
processorMode = IMAGE_FILE_MACHINE_AMD64;
else
throw DbgException( "Unknown processor type" );
hres = m_control->SetEffectiveProcessorType( processorMode );
if ( FAILED( hres ) )
throw DbgException( "IDebugControl::SetEffectiveProcessorType failed" );
}
void setProcessorMode( const std::wstring &mode )
{
g_dbgClient->setProcessorMode( mode );
}
///////////////////////////////////////////////////////////////////////////////////
} }

View File

@ -16,6 +16,12 @@ std::string getProcessorType();
python::list getThreadList(); python::list getThreadList();
void setCurrentProcess( ULONG64 processAddr );
void setImplicitThread( ULONG64 threadAddr );
void setProcessorMode( const std::wstring &mode );
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
} }

View File

@ -71,17 +71,14 @@ class BaseTest( unittest.TestCase ):
self.assertTrue( hasattr(pykd, 'ptrWord') ) self.assertTrue( hasattr(pykd, 'ptrWord') )
self.assertTrue( hasattr(pykd, 'rdmsr') ) self.assertTrue( hasattr(pykd, 'rdmsr') )
self.assertTrue( hasattr(pykd, 'reg') ) self.assertTrue( hasattr(pykd, 'reg') )
self.assertTrue( hasattr(pykd, 'reloadModule') )
self.assertTrue( hasattr(pykd, 'setCurrentProcess') ) self.assertTrue( hasattr(pykd, 'setCurrentProcess') )
self.assertTrue( hasattr(pykd, 'setImplicitThread') ) self.assertTrue( hasattr(pykd, 'setImplicitThread') )
self.assertTrue( hasattr(pykd, 'setProcessorMode') ) self.assertTrue( hasattr(pykd, 'setProcessorMode') )
self.assertTrue( hasattr(pykd, 'sizeof') ) # self.assertTrue( hasattr(pykd, 'sizeof') )
self.assertTrue( hasattr(pykd, 'startProcess') ) self.assertTrue( hasattr(pykd, 'startProcess') )
self.assertTrue( hasattr(pykd, 'step') ) self.assertTrue( hasattr(pykd, 'step') )
self.assertTrue( hasattr(pykd, 'symbolsPath') ) self.assertTrue( hasattr(pykd, 'symbolsPath') )
self.assertTrue( hasattr(pykd, 'trace') ) self.assertTrue( hasattr(pykd, 'trace') )
self.assertTrue( hasattr(pykd, 'typedVarArray') )
self.assertTrue( hasattr(pykd, 'typedVarList') )
self.assertTrue( hasattr(pykd, 'wrmsr') ) self.assertTrue( hasattr(pykd, 'wrmsr') )
@ -108,6 +105,9 @@ class BaseTest( unittest.TestCase ):
self.assertFalse( hasattr(pykd, 'findModule') ) self.assertFalse( hasattr(pykd, 'findModule') )
self.assertFalse( hasattr(pykd, 'loadLinkedList') ) self.assertFalse( hasattr(pykd, 'loadLinkedList') )
self.assertFalse( hasattr(pykd, 'loadPtrs') ) self.assertFalse( hasattr(pykd, 'loadPtrs') )
self.assertFalse( hasattr(pykd, 'reloadModule') )
self.assertFalse( hasattr(pykd, 'typedVarArray') )
self.assertFalse( hasattr(pykd, 'typedVarList') )
self.assertFalse( hasattr(pykd, 'windbgIn') ) self.assertFalse( hasattr(pykd, 'windbgIn') )
self.assertFalse( hasattr(pykd, 'windbgOut') ) self.assertFalse( hasattr(pykd, 'windbgOut') )

View File

@ -31,3 +31,6 @@ class DbgClientTest( unittest.TestCase ):
def testThreadList( self ): def testThreadList( self ):
self.assertNotEqual( 0, len(pykd.getThreadList()) ) self.assertNotEqual( 0, len(pykd.getThreadList()) )
def testSymbolsPath( self ):
self.assertNotEqual( '', pykd.symbolsPath() )

View File

@ -73,7 +73,7 @@ class TypedVarTest( unittest.TestCase ):
tv = target.module.typedVar("g_structWithBits") tv = target.module.typedVar("g_structWithBits")
self.assertEqual( 4, tv.m_bit0_4 ) self.assertEqual( 4, tv.m_bit0_4 )
def testTypeVarList(self): def testTypedVarList(self):
tvl = target.module.typedVarList( target.module.g_listHead, "listStruct", "listEntry" ) tvl = target.module.typedVarList( target.module.g_listHead, "listStruct", "listEntry" )
self.assertEqual( 3, len( tvl ) ) self.assertEqual( 3, len( tvl ) )
self.assertEqual( [1,2,3], [ tv.num for tv in tvl ] ) self.assertEqual( [1,2,3], [ tv.num for tv in tvl ] )
@ -90,3 +90,13 @@ class TypedVarTest( unittest.TestCase ):
self.assertEqual( 3, len( tvl ) ) self.assertEqual( 3, len( tvl ) )
self.assertEqual( [100,200,300], [ tv.num for tv in tvl ] ) self.assertEqual( [100,200,300], [ tv.num for tv in tvl ] )
def testTypedVarArray(self):
tvl = target.module.typedVarArray( target.module.g_testArray, "structTest", 2 )
self.assertEqual( 2, len( tvl ) )
self.assertEqual( 500, tvl[0].m_field1 )
self.assertEqual( False, tvl[1].m_field2 )
tvl = target.module.typedVarArray( target.module.g_testArray, target.module.type("structTest"), 2 )
self.assertEqual( 2, len( tvl ) )
self.assertEqual( 1, tvl[0].m_field3 )
self.assertEqual( 0, tvl[1].m_field4 )