mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-29 20:03:33 +08:00
[samples] added: a very simple debugger
git-svn-id: https://pykd.svn.codeplex.com/svn@70215 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
parent
071ae4e12a
commit
d7f76b4b5b
@ -384,7 +384,7 @@ BOOST_PYTHON_MODULE( pykd )
|
|||||||
.def( boost::python::init<>( "constructor" ) )
|
.def( boost::python::init<>( "constructor" ) )
|
||||||
.def( boost::python::init<ULONG64>( boost::python::args("offset"), "constructor" ) )
|
.def( boost::python::init<ULONG64>( boost::python::args("offset"), "constructor" ) )
|
||||||
.def( "disasm", &disasm::disassemble, "Disassemble next instruction" )
|
.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( "begin", &disasm::begin, "Return begin offset" )
|
||||||
.def( "current", &disasm::current, "Return current offset" )
|
.def( "current", &disasm::current, "Return current offset" )
|
||||||
.def( "length", &disasm::length, "Return current instruction length" )
|
.def( "length", &disasm::length, "Return current instruction length" )
|
||||||
|
218
samples/debug.py
218
samples/debug.py
@ -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()
|
|
119
samples/debug/debug.py
Normal file
119
samples/debug/debug.py
Normal file
@ -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()
|
13
samples/debug/widgets/__init__.py
Normal file
13
samples/debug/widgets/__init__.py
Normal file
@ -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 )
|
||||||
|
|
50
samples/debug/widgets/cmd.py
Normal file
50
samples/debug/widgets/cmd.py
Normal file
@ -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 )
|
||||||
|
|
||||||
|
|
28
samples/debug/widgets/disasm.py
Normal file
28
samples/debug/widgets/disasm.py
Normal file
@ -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() )
|
||||||
|
|
48
samples/debug/widgets/regs.py
Normal file
48
samples/debug/widgets/regs.py
Normal file
@ -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() )
|
||||||
|
|
32
samples/debug/widgets/stack.py
Normal file
32
samples/debug/widgets/stack.py
Normal file
@ -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() )
|
Loading…
Reference in New Issue
Block a user