From 2234c675e9a8099ba751e79f424968d8f0cde8d8 Mon Sep 17 00:00:00 2001 From: "SND\\kernelnet_cp" Date: Wed, 17 Aug 2011 16:13:04 +0000 Subject: [PATCH] [pykd] added : cpuReg constructor with index parameter git-svn-id: https://pykd.svn.codeplex.com/svn@69075 9b283d60-5439-405e-af05-b73fd8c4d996 --- pykd/dbgext.cpp | 4 +- pykd/dbgreg.cpp | 53 ++++++++++++-- pykd/dbgreg.h | 9 +++ samples/debug.py | 184 ++++++++++++++++++++++++++++++++++++++++++----- 4 files changed, 224 insertions(+), 26 deletions(-) diff --git a/pykd/dbgext.cpp b/pykd/dbgext.cpp index 03a540f..7a51348 100644 --- a/pykd/dbgext.cpp +++ b/pykd/dbgext.cpp @@ -486,8 +486,10 @@ BOOST_PYTHON_MODULE( pykd ) "CPU regsiter class", boost::python::no_init ) .def( boost::python::init(boost::python::args("name"), "constructor" ) ) + .def( boost::python::init(boost::python::args("index"), "constructor" ) ) .def( "name", &cpuReg::name, "The name of the regsiter" ) - .def( "beLive", &cpuReg::beLive, "Turn the object to live: its value will be following thr target register value" ); + .def( "index", &cpuReg::index, "The index of thr register" ) + .def( "beLive", &cpuReg::beLive, "Turn the object to live: its value will be following the target register value" ); // debug status diff --git a/pykd/dbgreg.cpp b/pykd/dbgreg.cpp index c16c109..b1511bd 100644 --- a/pykd/dbgreg.cpp +++ b/pykd/dbgreg.cpp @@ -10,8 +10,54 @@ using namespace std; cpuReg::cpuReg( std::string regName ) { + HRESULT hres; + m_name = regName; m_lived = false; + + hres = dbgExt->registers->GetIndexByName( m_name.c_str(), &m_index ); + if ( FAILED( hres ) ) + throw DbgException( "IDebugRegister::GetIndexByName failed" ); + + reloadValue(); +} + +/////////////////////////////////////////////////////////////////////////////////// + +cpuReg::cpuReg( ULONG index ) +{ + HRESULT hres; + + m_index = index; + m_lived = false; + + ULONG nameSize = 0; + + hres = + dbgExt->registers->GetDescription( + m_index, + NULL, + 0, + &nameSize, + NULL ); + + if ( FAILED( hres ) ) + throw DbgException( "IDebugRegister::GetDescription failed" ); + + std::vector nameBuffer(nameSize); + + hres = + dbgExt->registers->GetDescription( + m_index, + &nameBuffer[0], + nameSize, + NULL, + NULL ); + + if ( FAILED( hres ) ) + throw DbgException( "IDebugRegister::GetDescription failed" ); + + m_name = std::string( &nameBuffer[0] ); reloadValue(); } @@ -21,14 +67,9 @@ cpuReg::cpuReg( std::string regName ) void cpuReg::reloadValue() const { HRESULT hres; - ULONG registerIndex = 0; - - hres = dbgExt->registers->GetIndexByName( m_name.c_str(), ®isterIndex ); - if ( FAILED( hres ) ) - throw DbgException( "IDebugRegister::GetIndexByName failed" ); DEBUG_VALUE debugValue; - hres = dbgExt->registers->GetValue( registerIndex, &debugValue ); + hres = dbgExt->registers->GetValue( m_index, &debugValue ); if ( FAILED( hres ) ) throw DbgException( "IDebugRegister::GetValue failed" ); diff --git a/pykd/dbgreg.h b/pykd/dbgreg.h index 0a31a83..8ee6d4d 100644 --- a/pykd/dbgreg.h +++ b/pykd/dbgreg.h @@ -12,11 +12,18 @@ class cpuReg : public intBase { public : cpuReg( std::string regName ); + + cpuReg( ULONG index ); std::string name() const { return m_name; } + + ULONG + index() const { + return m_index; + } void beLive() { m_lived = true; @@ -35,6 +42,8 @@ private: void reloadValue() const; std::string m_name; + + ULONG m_index; bool m_lived; }; diff --git a/samples/debug.py b/samples/debug.py index 761d083..c00194d 100644 --- a/samples/debug.py +++ b/samples/debug.py @@ -3,66 +3,212 @@ # from PySide.QtCore import * -from PySide.QtGui import * +from PySide.QtGui import * import pykd -class DbgThread( QThread ): - +class UpdateEvent( QEvent ): def __init__(self): + QEvent.__init__(self, QEvent.Type(QEvent.User + 1)) + + +class GoThread( QThread ): + + def __init__(self, func): QThread.__init__(self) + self.start() + self.func = func def run(self): - pykd.startProcess( self.processName ) - pykd.go() - # pass - while True: - self.sleep(100) - - + self.func() + app.postEvent( mainForm, UpdateEvent() ) self.exit() +class DisasmWidget( QDockWidget ): + + def __init__( self ): + QDockWidget.__init__( self ) + self.setWindowTitle( "Disassembler" ) + self.textArea = QTextEdit() + self.textArea.setReadOnly( True ) + self.setWidget( self.textArea ) + + + def onUpdate( self ): + + disasm = pykd.disasm() + disasmStr = disasm.instruction() + "\n" + for i in xrange(50): + disasmStr += disasm.next() + "\n" + + self.textArea.setPlainText( disasmStr ) + + +class RegistersWidget( QDockWidget ): + + def __init__( self ): + QDockWidget.__init__( self ) + self.setWindowTitle( "Registers" ) + self.textArea = QTextEdit() + self.setWidget( self.textArea ) + + def onUpdate( self ): + + s = "" + + for reg in self.getRegisterSet(): + s += "%s %x ( %d )\r\n" % ( reg.name(), reg.value(), reg.value() ) + + self.textArea.setPlainText( s ) + + + def getRegisterSet(self): + regSet=[] + try: + i = 0 + while True: + reg = pykd.cpuReg(i) + regSet.append(reg) + i += 1 + + except pykd.BaseException: + pass + + return regSet + + +class StackWidget( QDockWidget ): + + def __init__( self ): + QDockWidget.__init__( self ) + self.setWindowTitle( "Stack" ) + self.textArea = QTextEdit() + self.setWidget( self.textArea ) + + def onUpdate( self ): + + s = "" + + stackFrames = pykd.getCurrentStack() + for frame in stackFrames: + s += pykd.findSymbol( frame.instructionOffset ) + " (%x)" % frame.instructionOffset + "\n" + + self.textArea.setPlainText( s ) + + class MainForm( QMainWindow ): + + updated = Signal() def __init__( self ): + QMainWindow.__init__( self, None ) self.setWindowTitle("Pykd Debugger Sample") + self.setDockNestingEnabled( True ) + + self.goThread = None + fileMenu = QMenu( "&File" ) fileMenu.addAction( "Open process...", self.onOpenProcess ) fileMenu.addAction( "Exit", self.onExit ) - self.menuBar().addMenu( fileMenu ) + + debugMenu = QMenu( "Debug" ) + debugMenu.addAction( "Break", self.onBreak ) + debugMenu.addAction( "Go", self.onGo ) + debugMenu.addAction( "Step", self.onStep ) + self.menuBar().addMenu( debugMenu ) + + + viewMenu = QMenu( "View" ) + viewMenu.addAction( "Disasm", self.onDisasmShow ) + viewMenu.addAction( "Regsiters", self.onRegistersShow ) + viewMenu.addAction( "Stack", self.onStackShow ) + self.menuBar().addMenu( viewMenu ) + + self.disasmWidget = DisasmWidget() + self.disasmWidget.setVisible( False ) + self.addDockWidget( Qt.LeftDockWidgetArea, self.disasmWidget ) + self.updated.connect(self.disasmWidget.onUpdate ) + + self.registersWidget = RegistersWidget() + self.registersWidget.setVisible( False ) + self.addDockWidget( Qt.LeftDockWidgetArea, self.registersWidget ) + self.updated.connect(self.registersWidget.onUpdate ) + + self.stackWidget = StackWidget() + self.stackWidget.setVisible( False ) + self.addDockWidget( Qt.LeftDockWidgetArea, self.stackWidget ) + self.updated.connect(self.stackWidget.onUpdate ) + self.resize( 800, 600 ) - def __del__( self ): - if self.debugger.isRunning(): - self.debugger.quit() - self.debugger.wait(1000) - self.debugger.terminate() + def stopGoThread( self ): + + if self.goThread != None and self.goThread.isRunning(): + self.goThread.quit() + self.goThread.wait(10000) + + + def event( self, ev ): + + if ev.type() == QEvent.User + 1: + self.onUpdate() + return True + else: + return QMainWindow.event( self, ev ) + def onOpenProcess( self ): fileDlg = QFileDialog( self ) fileDlg.setNameFilter( self.tr("Executable (*.exe)" ) ) - self.debugger = DbgThread() - self.debugger.processName = fileDlg.getOpenFileName()[0] - self.debugger.start() + pykd.startProcess( fileDlg.getOpenFileName()[0] ) + self.goThread = GoThread( pykd.go ) + + + def onBreak( self ): + pykd.breakin() + + def onGo( self ): + self.stopGoThread() + self.goThread = GoThread( pykd.go ) + + def onStep( self ): + self.stopGoThread() + self.goThread = GoThread( pykd.step ) def onExit( self ): self.close() + def onDisasmShow( self ): + self.disasmWidget.setVisible( not self.disasmWidget.isVisible() ) + + def onRegistersShow( self ): + self.registersWidget.setVisible( not self.registersWidget.isVisible() ) + + + def onStackShow( self ): + self.stackWidget.setVisible( not self.stackWidget.isVisible() ) + + def onUpdate( self ): + self.updated.emit() + def main(): + global app + global mainForm + app = QApplication( [] ) mainForm = MainForm() mainForm.show()