# # # 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()