from yapsy.IPlugin import IPlugin from PyQt5 import QtGui, QtCore, QtWidgets import PyQt5 import os, sys #import DisasmViewMode class Observer: def changeViewMode(self, viewMode): self._viewMode = viewMode self.viewMode = viewMode #NotImplementedError('method not implemented.') class IDisasm(): # tells disasm view what to decode def hintDisasm(self): return None, None #return DisasmViewMode.Disasm_x86_32bit # calculates va for disasm mode def hintDisasmVA(self, offset): return offset # returns ascii string in disasm view (from a va) def stringFromVA(self, va): return '' def disasmVAtoFA(self, va): return None def disasmSymbol(self, va): return None class FileFormat(IPlugin, IDisasm, Observer): name = '' _Shortcuts = [] redbrush = QtGui.QBrush(QtGui.QColor(128, 0, 0)) yellowpen = QtGui.QPen(QtGui.QColor(255, 255, 0)) def isRecognized(self): return False def init(self, viewMode, parent): pass def getShortcuts(self): return self._Shortcuts def registerShortcuts(self, parent): pass class DialogGoto(QtWidgets.QDialog): def __init__(self, parent, plugin): super(DialogGoto, self).__init__(parent) self.parent = parent self.plugin = plugin self.oshow = super(DialogGoto, self).show root = os.path.dirname(sys.argv[0]) self.ui = PyQt5.uic.loadUi(os.path.join(root, 'plugins', 'format', 'goto.ui'), baseinstance=self) self.konstants = {} self.GoTos = {'FileAddress' : self.fa} self.initUI() def show(self): # TODO: remember position? resize plugin windows when parent resize? pwidth = self.parent.parent.size().width() pheight = self.parent.parent.size().height() width = self.ui.size().width() height = self.ui.size().height() self.setGeometry(pwidth - width - 15, pheight - height, width, height) self.setFixedSize(width, height) self.ui.lineEdit.setFocus() self.oshow() def initUI(self): self.setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) shortcut = QtWidgets.QShortcut(QtGui.QKeySequence("Alt+G"), self, self.close, self.close) self.ui.setWindowTitle('GoTo') self.ui.lineEdit.returnPressed.connect(lambda: self.onReturnPressed()) def onReturnPressed(self): expr = str(self.ui.lineEdit.text()) import ast import operator as op # supported operators operators = {ast.Add: op.add, ast.Sub: op.sub, ast.Mult: op.mul, ast.Div: op.floordiv, ast.Pow: op.pow, ast.USub: op.neg} def eval_expr(expr): return eval_(ast.parse(expr, mode='eval').body) def eval_(node): if isinstance(node, ast.Num): return node.n elif isinstance(node, ast.BinOp): return operators[type(node.op)](eval_(node.left), eval_(node.right)) elif isinstance(node, ast.UnaryOp): return operators[type(node.op)](eval_(node.operand)) elif isinstance(node, object): # handle constants k = str(node.id).upper() if k in self.konstants: return self.konstants[k](k) else: raise TypeError(node) else: raise TypeError(node) try: result = eval_expr(expr) except Exception as e: self.ui.label.setText('error.') return self.ui.label.setText('{0} ({1})'.format(hex(result), result)) self.onResult(result) def onResult(self, result): gotoType = str(self.ui.comboBox.currentText()) result = self.GoTos[gotoType](result) if result is not None: self.plugin.viewMode.goTo(result) def fa(self, offset): return offset