From d7f76b4b5ba3a63747dcc11a3ec536b2fcc1580e Mon Sep 17 00:00:00 2001 From: "SND\\kernelnet_cp" Date: Wed, 5 Oct 2011 09:01:15 +0000 Subject: [PATCH] [samples] added: a very simple debugger git-svn-id: https://pykd.svn.codeplex.com/svn@70215 9b283d60-5439-405e-af05-b73fd8c4d996 --- pykd/dbgext.cpp | 2 +- samples/debug.py | 218 ------------------------------ samples/debug/debug.py | 119 ++++++++++++++++ samples/debug/widgets/__init__.py | 13 ++ samples/debug/widgets/cmd.py | 50 +++++++ samples/debug/widgets/disasm.py | 28 ++++ samples/debug/widgets/regs.py | 48 +++++++ samples/debug/widgets/stack.py | 32 +++++ 8 files changed, 291 insertions(+), 219 deletions(-) delete mode 100644 samples/debug.py create mode 100644 samples/debug/debug.py create mode 100644 samples/debug/widgets/__init__.py create mode 100644 samples/debug/widgets/cmd.py create mode 100644 samples/debug/widgets/disasm.py create mode 100644 samples/debug/widgets/regs.py create mode 100644 samples/debug/widgets/stack.py diff --git a/pykd/dbgext.cpp b/pykd/dbgext.cpp index bbe2732..e75d0bf 100644 --- a/pykd/dbgext.cpp +++ b/pykd/dbgext.cpp @@ -384,7 +384,7 @@ BOOST_PYTHON_MODULE( pykd ) .def( boost::python::init<>( "constructor" ) ) .def( boost::python::init( boost::python::args("offset"), "constructor" ) ) .def( "disasm", &disasm::disassemble, "Disassemble next instruction" ) - .def( "sasm", &disasm::assembly, "Insert assemblied instuction to current offset" ) + .def( "asm", &disasm::assembly, "Insert assemblied instuction to current offset" ) .def( "begin", &disasm::begin, "Return begin offset" ) .def( "current", &disasm::current, "Return current offset" ) .def( "length", &disasm::length, "Return current instruction length" ) diff --git a/samples/debug.py b/samples/debug.py deleted file mode 100644 index c00194d..0000000 --- a/samples/debug.py +++ /dev/null @@ -1,218 +0,0 @@ -# -# -# - -from PySide.QtCore import * -from PySide.QtGui import * - -import pykd - - -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): - 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 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)" ) ) - - 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() - exitres = app.exec_() - -if __name__ == "__main__": - main() \ No newline at end of file diff --git a/samples/debug/debug.py b/samples/debug/debug.py new file mode 100644 index 0000000..8a8e34e --- /dev/null +++ b/samples/debug/debug.py @@ -0,0 +1,119 @@ +# +# +# + +from PySide.QtCore import * +from PySide.QtGui import * + +import pykd +import widgets + +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): + self.func() + app.postEvent( mainForm, UpdateEvent() ) + self.exit() + + +class MainForm( QMainWindow ): + + updated = Signal() + + def __init__( self ): + + + QMainWindow.__init__( self, None ) + self.setWindowTitle("Pykd Debugger Sample") + self.setDockNestingEnabled( True ) + + self.goThread = None + + + self.fileMenu = QMenu( "&File" ) + self.fileMenu.addAction( "Open process...", self.onOpenProcess ) + self.fileMenu.addAction( "Exit", self.onExit ) + self.menuBar().addMenu( self.fileMenu ) + + + self.debugMenu = QMenu( "Debug" ) + self.debugMenu.addAction( "Break", self.onBreak ) + self.debugMenu.addAction( "Go", self.onGo ) + self.debugMenu.addAction( "Step", self.onStep ) + self.menuBar().addMenu( self.debugMenu ) + + + self.viewMenu = QMenu( "View" ) + self.menuBar().addMenu( self.viewMenu ) + + self.resize( 800, 600 ) + + widgets.register( self ) + + + 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)" ) ) + + 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 onUpdate( self ): + self.updated.emit() + + +def main(): + + global app + global mainForm + + app = QApplication( [] ) + mainForm = MainForm() + mainForm.show() + exitres = app.exec_() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/samples/debug/widgets/__init__.py b/samples/debug/widgets/__init__.py new file mode 100644 index 0000000..204a79c --- /dev/null +++ b/samples/debug/widgets/__init__.py @@ -0,0 +1,13 @@ + +import regs +import disasm +import stack +import cmd + + +def register( mainFrame ): + cmd.CmdWidget( mainFrame ) + regs.RegistersWidget( mainFrame ) + disasm.DisasmWidget( mainFrame ) + stack.StackWidget( mainFrame ) + \ No newline at end of file diff --git a/samples/debug/widgets/cmd.py b/samples/debug/widgets/cmd.py new file mode 100644 index 0000000..cd46870 --- /dev/null +++ b/samples/debug/widgets/cmd.py @@ -0,0 +1,50 @@ + + +from PySide.QtCore import * +from PySide.QtGui import * + +import pykd + + +class CmdWidget( QDockWidget ): + + def __init__( self, parent ): + QDockWidget.__init__( self ) + self.setWindowTitle( "Commands" ) + + self.inCmd = QLineEdit() + self.inCmd.returnPressed.connect( self.onCommandInput ) + + self.outCmd = QTextEdit() + self.outCmd.setReadOnly( True ) + + + layout = QVBoxLayout() + layout.addWidget( self.outCmd ) + layout.addWidget( self.inCmd ) + + + + layoutWidget = QWidget() + layoutWidget.setLayout( layout ) + + self.setWidget( layoutWidget ) + + self.setVisible( False ) + parent.addDockWidget( Qt.LeftDockWidgetArea, self ) + parent.viewMenu.addAction( "Commands", self.onCommandsShow ) + + + def onCommandsShow( self ): + self.setVisible( not self.isVisible() ) + + + def onCommandInput( self ): + self.inCmd.setReadOnly( True ) + cmdLine = self.inCmd.text() + self.inCmd.setText( "running %s" % cmdLine ) + self.outCmd.append( pykd.dbgCommand( cmdLine ) ) + self.inCmd.setText( "" ) + self.inCmd.setReadOnly( False ) + + diff --git a/samples/debug/widgets/disasm.py b/samples/debug/widgets/disasm.py new file mode 100644 index 0000000..d5d4fd0 --- /dev/null +++ b/samples/debug/widgets/disasm.py @@ -0,0 +1,28 @@ + +from PySide.QtCore import * +from PySide.QtGui import * + +import pykd + + +class DisasmWidget( QDockWidget ): + + def __init__( self, parent ): + QDockWidget.__init__( self ) + self.setWindowTitle( "Disassembler" ) + self.textArea = QTextEdit() + self.setWidget( self.textArea ) + self.setVisible( False ) + parent.addDockWidget( Qt.LeftDockWidgetArea, self ) + parent.updated.connect(self.onUpdate ) + parent.viewMenu.addAction( "Disassembler", self.onDisassemblerShow ) + + + def onUpdate( self ): + disasm = pykd.disasm() + self.textArea.setPlainText( "\n".join( [ disasm.disasm() for i in xrange(50) ] ) ) + + + def onDisassemblerShow( self ): + self.setVisible( not self.isVisible() ) + \ No newline at end of file diff --git a/samples/debug/widgets/regs.py b/samples/debug/widgets/regs.py new file mode 100644 index 0000000..82f9ef2 --- /dev/null +++ b/samples/debug/widgets/regs.py @@ -0,0 +1,48 @@ + + +from PySide.QtCore import * +from PySide.QtGui import * + +import pykd + + +class RegistersWidget( QDockWidget ): + + def __init__( self, parent ): + QDockWidget.__init__( self ) + self.setWindowTitle( "Registers" ) + self.textArea = QTextEdit() + self.setWidget( self.textArea ) + self.setVisible( False ) + parent.addDockWidget( Qt.LeftDockWidgetArea, self ) + parent.updated.connect(self.onUpdate ) + parent.viewMenu.addAction( "Regsiters", self.onRegistersShow ) + + + 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 + + def onRegistersShow( self ): + self.setVisible( not self.isVisible() ) + diff --git a/samples/debug/widgets/stack.py b/samples/debug/widgets/stack.py new file mode 100644 index 0000000..91a83fa --- /dev/null +++ b/samples/debug/widgets/stack.py @@ -0,0 +1,32 @@ + +from PySide.QtCore import * +from PySide.QtGui import * + +import pykd + + +class StackWidget( QDockWidget ): + + def __init__( self, parent ): + QDockWidget.__init__( self ) + self.setWindowTitle( "Stack" ) + self.textArea = QTextEdit() + self.setWidget( self.textArea ) + self.setVisible( False ) + parent.addDockWidget( Qt.LeftDockWidgetArea, self ) + parent.updated.connect(self.onUpdate ) + parent.viewMenu.addAction( "Stack", self.onStackShow ) + + + def onUpdate( self ): + s = "" + + stackFrames = pykd.getCurrentStack() + for frame in stackFrames: + s += pykd.findSymbol( frame.instructionOffset ) + " (%x)" % frame.instructionOffset + "\n" + + self.textArea.setPlainText( s ) + + + def onStackShow( self ): + self.setVisible( not self.isVisible() )