Source code for envi.qt.memory
import re
from collections import deque
from PyQt4 import QtCore, QtGui
import envi.memcanvas as e_memcanvas
import envi.qt.memcanvas as e_memcanvas_qt
import envi.memcanvas.renderers as e_render
import vqt.colors as vq_colors
import vqt.menubuilder as vqt_menu
from vqt.main import idlethread, idlethreadsync
[docs]class VQMemoryWindow(QtGui.QWidget):
__canvas_class__ = e_memcanvas_qt.VQMemoryCanvas
def __init__(self, memobj, syms=None, parent=None):
QtGui.QWidget.__init__(self, parent=parent)
self._mem_obj = memobj
self.top_box = QtGui.QWidget(parent=self)
hbox = QtGui.QHBoxLayout(self.top_box)
hbox.setMargin(2)
hbox.setSpacing(4)
self.hist_button = QtGui.QPushButton('History', parent=self.top_box)
self.hist_button.clicked.connect(self._histButtonClicked)
self.addr_entry = QtGui.QLineEdit(parent=self.top_box)
self.size_entry = QtGui.QLineEdit(parent=self.top_box)
self.size_entry.setText('256')
self.rend_select = QtGui.QComboBox(parent=self.top_box)
self.mem_history = deque()
self.mem_canvas = self.__canvas_class__(memobj, syms=syms, parent=self)
self.mem_canvas.vqAddHotKey(e_memcanvas_qt.KEY_BACKSPACE, self._hotkey_BS)
self.loadDefaultRenderers()
self.loadRendSelect()
self.addr_entry.returnPressed.connect(self._renderMemory)
self.size_entry.returnPressed.connect(self._renderMemory)
self.connect(self.rend_select, QtCore.SIGNAL('currentIndexChanged(QString)'), self._renderMemory)
hbox.addWidget(self.hist_button)
hbox.addWidget(self.addr_entry)
hbox.addWidget(self.size_entry)
hbox.addWidget(self.rend_select)
vbox = QtGui.QVBoxLayout(self)
vbox.setMargin(4)
vbox.setSpacing(4)
vbox.addWidget(self.top_box)
vbox.addWidget(self.mem_canvas, stretch=100)
self.top_box.setLayout(hbox)
self.setLayout(vbox)
self.setWindowTitle('Mem: None')
def _hotkey_BS(self, canv, key):
if len(self.mem_history) >= 2:
hinfo = self.mem_history.popleft()
hinfo = self.mem_history.popleft()
self._histSelected( hinfo )
def _histSelected(self, hinfo):
addrexpr, sizeexpr, rendname = hinfo
self.addr_entry.setText(addrexpr)
self.size_entry.setText(sizeexpr)
self.mem_canvas.setRenderer(rendname)
self._renderMemory()
def _histButtonClicked(self):
menu = vqt_menu.VQMenu('context', parent=self.hist_button)
menu.splitchar = '&&&&&' # Disable splitting
for hinfo in self.mem_history:
addrexpr, sizeexpr, rendname = hinfo
addr = self._mem_obj.parseExpression(addrexpr)
menustr = '0x%.8x' % addr
sym = self._mem_obj.getSymByAddr(addr)
if sym != None:
menustr += ' - %s' % repr(sym)
menu.addField(menustr, self._histSelected, (hinfo,))
menu.exec_(self.mapToGlobal(self.hist_button.pos()))
return
[docs] def vqMemNavSlot(self, expr, sizeexpr=None):
# Used by nav event generators to make us render
self.addr_entry.setText(expr)
if sizeexpr != None:
self.size_entry.setText(sizeexpr)
self._renderMemory()
[docs] def loadRendSelect(self):
self.rend_select.clear()
for name in self.mem_canvas.getRendererNames():
self.rend_select.addItem(name)
[docs] def loadDefaultRenderers(self):
self.mem_canvas.addRenderer("bytes", e_render.ByteRend())
self.mem_canvas.addRenderer("u_int_16", e_render.ShortRend())
self.mem_canvas.addRenderer("u_int_32", e_render.LongRend())
self.mem_canvas.addRenderer("u_int_64", e_render.QuadRend())
def _getRenderVaSize(self):
expr = str(self.addr_entry.text())
sizeexpr = str(self.size_entry.text())
if not expr:
return None, None
if not sizeexpr:
return None, None
try:
addr = self._mem_obj.parseExpression(expr)
except Exception, e:
self.mem_canvas.addText('Invalid Address: %s (%s)' % (expr, e))
return None, None
try:
size = self._mem_obj.parseExpression(sizeexpr)
except Exception, e:
self.mem_canvas.addText('Invalid Size: %s (%s)' % (expr, e))
return None, None
self.setWindowTitle('Mem: %s' % expr)
return addr, size
@idlethread
def _renderMemory(self, *args, **kwargs):
self.clearText()
addr, size = self._getRenderVaSize()
if addr == None:
return
expr = str(self.addr_entry.text())
rname = str(self.rend_select.currentText())
sizeexpr = str(self.size_entry.text())
mhist = (expr, sizeexpr, rname)
if mhist not in self.mem_history:
self.mem_history.appendleft( mhist )
while len(self.mem_history) > 100:
self.mem_history.pop()
self.mem_canvas.setRenderer(rname)
self.mem_canvas.renderMemory(addr, size)
[docs] def clearText(self):
self.mem_canvas.clearCanvas()