diff --git a/idangr/context_gui.py b/idangr/context_gui.py new file mode 100644 index 0000000..e9b3083 --- /dev/null +++ b/idangr/context_gui.py @@ -0,0 +1,32 @@ + +find = [] +avoid = [] +find_lambda = "def find_cond(state):\n\tsol = state.solver.eval\n\tfor addr in finds:\n\t\tif sol(state.regs.pc) == addr: return True\n\treturn False" +avoid_lambda = "def avoid_cond(state):\n\tsol = state.solver.eval\n\tfor addr in avoids:\n\t\tif sol(state.regs.pc) == addr: return True\n\treturn False" +regs = [] +simregs = [] +simmem = [] +constraints = {} #{ item: (code string, lambda) } +stateman = None +foundstate = None +simman = None + +# indipendent from context +hooks = [] #[(address, code)] + + +def reset(): + global find, avoid, find_lambda, avoid_lambda, regs, simregs, simmem, constraints, stateman, foundstate, simman + find = [] + avoid = [] + find_lambda = "def find_cond(state):\n\tsol = state.solver.eval\n\tfor addr in finds:\n\t\tif sol(state.regs.pc) == addr: return True\n\treturn False" + avoid_lambda = "def avoid_cond(state):\n\tsol = state.solver.eval\n\tfor addr in avoids:\n\t\tif sol(state.regs.pc) == addr: return True\n\treturn False" + regs = [] + while len(simregs) > 0: + simregs.pop() + while len(simmem) > 0: + simmem.pop() + constraints = {} #{ item: (code string, lambda) } + stateman = None + foundstate = None + simman = None diff --git a/idangr/dialogs_gui.py b/idangr/dialogs_gui.py new file mode 100644 index 0000000..6b30805 --- /dev/null +++ b/idangr/dialogs_gui.py @@ -0,0 +1,308 @@ +from PyQt5 import QtCore, QtGui, QtWidgets +from PyQt5.QtCore import Qt + +from ui import * + +from angrdbg import * + +import angr +import claripy + +import idaapi +import idc +import idautils + +import glob +import os + +import manage +import context_gui as ctx + +class IDAngrTextViewerForm(QtWidgets.QDialog): + + def __init__(self, text, title): + QtWidgets.QDialog.__init__(self) + self.text = text + self.ui = Ui_IDAngrTextViewer() + self.ui.setupUi(self) + if title: + self.setWindowTitle(title) + self.ui.plainTextEdit.setPlainText(str(text)) + self.ui.plainBox.toggled.connect(self.plain_toggled) + self.ui.hexBox.toggled.connect(self.hex_toggled) + self.ui.pyBox.toggled.connect(self.py_toggled) + + def plain_toggled(self, enabled): + if enabled: + self.ui.plainTextEdit.setPlainText(str(self.text)) + + def hex_toggled(self, enabled): + if enabled: + self.ui.plainTextEdit.setPlainText(str(self.text).encode("hex")) + + def py_toggled(self, enabled): + if self.ui.pyBox.isChecked(): + self.ui.plainTextEdit.setPlainText(repr(self.text)) + + @staticmethod + def show_text(text, title=None): + frm = IDAngrTextViewerForm(text, title) + frm.exec_() + + +class IDAngrEditorDialog(QtWidgets.QDialog): + + def __init__(self, title, text=""): + QtWidgets.QDialog.__init__(self) + + self.ui = Ui_IDAngrEditorDialog() + self.ui.setupUi(self) + + self.setWindowTitle("Editor - " + str(title)) + + self.ui.codeEdit.setPlainText(text) + self.h = PythonHighlighter(self.ui.codeEdit.document()) + + @staticmethod + def go(title, text=""): + dialog = IDAngrConstraintsDialog(title, text) + + r = dialog.exec_() + if r == QtWidgets.QDialog.Accepted: + return dialog.ui.codeEdit.toPlainText() + + +class IDAngrHookDialog(IDAngrEditorDialog): + + def __init__(self, addr, text=""): + if type(addr) in (int, long): + addr = hex(addr).replace("L","") + title = str(addr) + " Hook" + + IDAngrEditorDialog.__init__(self, title, text) + + @staticmethod + def get_hook(addr): + code = IDAngrHookDialog.go() + if code is None: + return None + + pass + + +class IDAngrAddMemDialog(QtWidgets.QDialog): + + def __init__(self): + QtWidgets.QDialog.__init__(self) + + self.ui = Ui_IDAngrAddMem() + self.ui.setupUi(self) + + self.ui.lenTextEdit.setText(str(load_project().arch.bits / 8)) + + def set_addr(self, addr): + if type(addr) == int or type(addr) == long: + addr = "0x%x" % addr + self.ui.addrTextEdit.setText(addr) + + @staticmethod + def get_mem(addr): + dialog = IDAngrAddMemDialog() + dialog.set_addr(addr) + r = dialog.exec_() + if r == QtWidgets.QDialog.Accepted: + addr = dialog.ui.addrTextEdit.displayText() + try: + addr = int(addr, 16) + except: + QtWidgets.QMessageBox(QtWidgets.QMessageBox.Critical, 'Error', "Address not in hex format").exec_() + return None + length = dialog.ui.lenTextEdit.displayText() + try: + length = int(length) + except: + QtWidgets.QMessageBox(QtWidgets.QMessageBox.Critical, 'Error', "Length not in dec format").exec_() + return None + return (addr, length) + return None + + + +class IDAngrSavedsDialog(QtWidgets.QDialog): + + def __init__(self, folder, title): + QtWidgets.QDialog.__init__(self) + + self.ui = Ui_IDAngrSavedsDialog() + self.ui.setupUi(self) + + self.setWindowTitle(title) + self.h = PythonHighlighter(self.ui.codeView.document()) + + self.folder = folder + self.files_list = [] + for path in glob.glob(os.path.join(folder, "*.py")): + self.files_list.append(os.path.basename(path)[:-3]) + + self.ui.selectorList.setModel(QtCore.QStringListModel(self.files_list)) + self.model = self.ui.selectorList.selectionModel() + self.model.selectionChanged.connect(self.selector_clicked) + + def selector_clicked(self): + item = self.model.selection().indexes()[0] + path = os.path.join(self.folder, item.data() + ".py") + with open(path, "r") as f: + code = f.read() + self.ui.codeView.setPlainText(code) + + + @staticmethod + def go(folder, title="Saveds"): + dialog = IDAngrSavedsDialog(folder, title) + r = dialog.exec_() + if r == QtWidgets.QDialog.Accepted: + return dialog.ui.codeView.toPlainText() + + + +class IDAngrConstraintsDialog(QtWidgets.QDialog): + + def __init__(self, item, text=""): + QtWidgets.QDialog.__init__(self) + + self.ui = Ui_IDAngrConstraintsDialog() + self.ui.setupUi(self) + + if type(item) in (int, long): + item = hex(item).replace("L","") + + self.ui.constrEdit.setPlainText(text) + self.setWindowTitle("Edit Constraints - " + str(item)) + self.h = PythonHighlighter(self.ui.constrEdit.document()) + + self.ui.savedsBtn.clicked.connect(self.saveds_clicked) + + def saveds_clicked(self): + code = IDAngrSavedsDialog.go(os.path.join(os.path.dirname(__file__), "saveds", "constraints"), "Predefined Constraints") + if code == None: + return + self.ui.constrEdit.setPlainText(code) + + @staticmethod + def go(item): + + if item in ctx.constraints: + dialog = IDAngrConstraintsDialog(item, ctx.constraints[item][0]) + else: + dialog = IDAngrConstraintsDialog(item, "# add your constraints to the var 'sym' using the var 'state'\n") + + r = dialog.exec_() + if r == QtWidgets.QDialog.Accepted: + code = dialog.ui.constrEdit.toPlainText() + func = "def constr_func(sym, state):\n" + for line in code.split("\n"): + func += "\t" + line + "\n" + try: + if manage.is_remote(): + manage.remote_exec(func) + else: + exec(func) in globals() + except Exception as ee: + QtWidgets.QMessageBox(QtWidgets.QMessageBox.Critical, 'Constraints Code - Python Error', str(ee)).exec_() + return + + if manage.is_remote(): + ctx.constraints[item] = (code, manage.remote_eval("constr_func")) + else: + ctx.constraints[item] = (code, constr_func) + + +class IDAngrExecDialog(QtWidgets.QDialog): + + def __init__(self): + QtWidgets.QDialog.__init__(self) + + self.ui = Ui_IDAngrExecDialog() + self.ui.setupUi(self) + + if ctx.find_lambda: + self.ui.findCondEdit.setPlainText(ctx.find_lambda) + if ctx.avoid_lambda: + self.ui.avoidCondEdit.setPlainText(ctx.avoid_lambda) + + self.ui.simprocsBox.setChecked(get_memory_type() == SIMPROCS_FROM_CLE) + self.ui.textloaderBox.setChecked(get_memory_type() == USE_CLE_MEMORY) + self.ui.gotloaderBox.setChecked(get_memory_type() == ONLY_GOT_FROM_CLE) + self.ui.execallBox.setChecked(get_memory_type() == GET_ALL_DISCARD_CLE) + + self.fh = PythonHighlighter(self.ui.findCondEdit.document()) + self.ah = PythonHighlighter(self.ui.avoidCondEdit.document()) + + @staticmethod + def go(): + dialog = IDAngrExecDialog() + r = dialog.exec_() + if r == QtWidgets.QDialog.Accepted: + if dialog.ui.simprocsBox.isChecked(): + set_memory_type(SIMPROCS_FROM_CLE) + elif dialog.ui.textloaderBox.isChecked(): + set_memory_type(USE_CLE_MEMORY) + elif dialog.ui.gotloaderBox.isChecked(): + set_memory_type(ONLY_GOT_FROM_CLE) + elif dialog.ui.execallBox.isChecked(): + set_memory_type(GET_ALL_DISCARD_CLE) + + if dialog.ui.useFindCondBox.isChecked(): + code = dialog.ui.findCondEdit.toPlainText() + ctx.find_lambda = code + finds = ctx.find + avoids = ctx.avoid + try: + if manage.is_remote(): + manage.remote_exec("finds = %s" % repr(finds)) + manage.remote_exec("avoids = %s" % repr(finds)) + manage.remote_exec(code) + else: + exec(code) in locals() + except Exception as ee: + QtWidgets.QMessageBox(QtWidgets.QMessageBox.Critical, 'Find Condition - Python Error', str(ee)).exec_() + return None + try: + if manage.is_remote(): + find = manage.remote_eval("find_cond") + else: + find = find_cond + except: + QtWidgets.QMessageBox(QtWidgets.QMessageBox.Critical, 'Error', "find_cond not defined").exec_() + return None + else: + find = ctx.find + if dialog.ui.useAvoidCondBox.isChecked(): + code = dialog.ui.avoidCondEdit.toPlainText() + ctx.avoid_lambda = code + finds = ctx.find + avoids = ctx.avoid + try: + if manage.is_remote(): + manage.remote_exec("finds = %s" % repr(finds)) + manage.remote_exec("avoids = %s" % repr(finds)) + manage.remote_exec(code) + else: + exec(code) in locals() + except Exception as ee: + QtWidgets.QMessageBox(QtWidgets.QMessageBox.Critical, 'Avoid Condition - Python Error', str(ee)).exec_() + return None + try: + if manage.is_remote(): + avoid = manage.remote_eval("avoid_cond") + else: + avoid = avoid_cond + except: + QtWidgets.QMessageBox(QtWidgets.QMessageBox.Critical, 'Error', "avoid_cond not defined").exec_() + return None + else: + avoid = ctx.avoid + return (find, avoid) + return None + + diff --git a/idangr/main_gui.py b/idangr/main_gui.py index 6b03483..0f56dae 100644 --- a/idangr/main_gui.py +++ b/idangr/main_gui.py @@ -13,289 +13,24 @@ import idc import idautils -import glob import sip import pickle import os import manage +import context_gui as ctx -class IDAngrCtx(object): - def __init__(self): - self.find = [] - self.avoid = [] - self.find_lambda = "def find_cond(state):\n\tsol = state.solver.eval\n\tfor addr in finds:\n\t\tif sol(state.regs.pc) == addr: return True\n\treturn False" - self.avoid_lambda = "def avoid_cond(state):\n\tsol = state.solver.eval\n\tfor addr in avoids:\n\t\tif sol(state.regs.pc) == addr: return True\n\treturn False" - self.regs = [] - self.simregs = [] - self.simmem = [] - self.constraints = {} #{ item: (code string, lambda) } - self.stateman = None - self.foundstate = None - self.simman = None - -_idangr_ctx = IDAngrCtx() +from dialogs_gui import * def save_ctx(filename): - global _idangr_ctx with open(filename, "wb") as fh: - pickle.dump(_idangr_ctx, fh) + pickle.dump(ctx, fh) def load_ctx(filename): - global _idangr_ctx with open(filename, "rb") as fh: - _idangr_ctx = pickle.load(fh) + ctx = pickle.load(fh) -class IDAngrTextViewerForm(QtWidgets.QDialog): - - def __init__(self, text, title): - QtWidgets.QDialog.__init__(self) - self.text = text - self.ui = Ui_IDAngrTextViewer() - self.ui.setupUi(self) - if title: - self.setWindowTitle(title) - self.ui.plainTextEdit.setPlainText(str(text)) - self.ui.plainBox.toggled.connect(self.plain_toggled) - self.ui.hexBox.toggled.connect(self.hex_toggled) - self.ui.pyBox.toggled.connect(self.py_toggled) - - def plain_toggled(self, enabled): - if enabled: - self.ui.plainTextEdit.setPlainText(str(self.text)) - - def hex_toggled(self, enabled): - if enabled: - self.ui.plainTextEdit.setPlainText(str(self.text).encode("hex")) - - def py_toggled(self, enabled): - if self.ui.pyBox.isChecked(): - self.ui.plainTextEdit.setPlainText(repr(self.text)) - - @staticmethod - def show_text(text, title=None): - frm = IDAngrTextViewerForm(text, title) - frm.exec_() - -class IDAngrAddMemDialog(QtWidgets.QDialog): - - def __init__(self): - QtWidgets.QDialog.__init__(self) - - self.ui = Ui_IDAngrAddMem() - self.ui.setupUi(self) - - self.ui.lenTextEdit.setText(str(load_project().arch.bits / 8)) - - def set_addr(self, addr): - if type(addr) == int or type(addr) == long: - addr = "0x%x" % addr - self.ui.addrTextEdit.setText(addr) - - @staticmethod - def get_mem(addr): - dialog = IDAngrAddMemDialog() - dialog.set_addr(addr) - r = dialog.exec_() - if r == QtWidgets.QDialog.Accepted: - addr = dialog.ui.addrTextEdit.displayText() - try: - addr = int(addr, 16) - except: - QtWidgets.QMessageBox(QtWidgets.QMessageBox.Critical, 'Error', "Address not in hex format").exec_() - return None - length = dialog.ui.lenTextEdit.displayText() - try: - length = int(length) - except: - QtWidgets.QMessageBox(QtWidgets.QMessageBox.Critical, 'Error', "Length not in dec format").exec_() - return None - return (addr, length) - return None - - - -class IDAngrSavedsDialog(QtWidgets.QDialog): - - def __init__(self, folder, title): - QtWidgets.QDialog.__init__(self) - - self.ui = Ui_IDAngrSavedsDialog() - self.ui.setupUi(self) - - self.setWindowTitle(title) - self.h = PythonHighlighter(self.ui.codeView.document()) - - self.folder = folder - self.files_list = [] - for path in glob.glob(os.path.join(folder, "*.py")): - self.files_list.append(os.path.basename(path)[:-3]) - - self.ui.selectorList.setModel(QtCore.QStringListModel(self.files_list)) - self.model = self.ui.selectorList.selectionModel() - self.model.selectionChanged.connect(self.selector_clicked) - - def selector_clicked(self): - item = self.model.selection().indexes()[0] - path = os.path.join(self.folder, item.data() + ".py") - with open(path, "r") as f: - code = f.read() - self.ui.codeView.setPlainText(code) - - - @staticmethod - def go(folder, title="Saveds"): - dialog = IDAngrSavedsDialog(folder, title) - r = dialog.exec_() - if r == QtWidgets.QDialog.Accepted: - return dialog.ui.codeView.toPlainText() - - - -class IDAngrConstraintsDialog(QtWidgets.QDialog): - - def __init__(self, item, text=""): - QtWidgets.QDialog.__init__(self) - - self.ui = Ui_IDAngrConstraintsDialog() - self.ui.setupUi(self) - - if type(item) in (int, long): - item = hex(item) - - self.ui.constrEdit.setPlainText(text) - self.setWindowTitle("Edit Constraints - " + str(item)) - self.h = PythonHighlighter(self.ui.constrEdit.document()) - - self.ui.savedsBtn.clicked.connect(self.saveds_clicked) - - def saveds_clicked(self): - code = IDAngrSavedsDialog.go(os.path.join(os.path.dirname(__file__), "saveds", "constraints"), "Predefined Constraints") - if code == None: - return - self.ui.constrEdit.setPlainText(code) - - @staticmethod - def go(item): - global _idangr_ctx - if item in _idangr_ctx.constraints: - dialog = IDAngrConstraintsDialog(item, _idangr_ctx.constraints[item][0]) - else: - dialog = IDAngrConstraintsDialog(item, "# add your constraints to the var 'sym' using the var 'state'\n") - - r = dialog.exec_() - if r == QtWidgets.QDialog.Accepted: - code = dialog.ui.constrEdit.toPlainText() - func = "def constr_func(sym, state):\n" - for line in code.split("\n"): - func += "\t" + line + "\n" - try: - if manage.is_remote(): - manage.remote_exec(func) - else: - exec(func) in globals() - except Exception as ee: - QtWidgets.QMessageBox(QtWidgets.QMessageBox.Critical, 'Constraints Code - Python Error', str(ee)).exec_() - return - - if manage.is_remote(): - _idangr_ctx.constraints[item] = (code, manage.remote_eval("constr_func")) - else: - _idangr_ctx.constraints[item] = (code, constr_func) - - -class IDAngrExecDialog(QtWidgets.QDialog): - - def __init__(self): - global _idangr_ctx - QtWidgets.QDialog.__init__(self) - - self.ui = Ui_IDAngrExecDialog() - self.ui.setupUi(self) - - if _idangr_ctx.find_lambda: - self.ui.findCondEdit.setPlainText(_idangr_ctx.find_lambda) - if _idangr_ctx.avoid_lambda: - self.ui.avoidCondEdit.setPlainText(_idangr_ctx.avoid_lambda) - - self.ui.simprocsBox.setChecked(get_memory_type() == SIMPROCS_FROM_CLE) - self.ui.textloaderBox.setChecked(get_memory_type() == USE_CLE_MEMORY) - self.ui.gotloaderBox.setChecked(get_memory_type() == ONLY_GOT_FROM_CLE) - self.ui.execallBox.setChecked(get_memory_type() == GET_ALL_DISCARD_CLE) - - self.fh = PythonHighlighter(self.ui.findCondEdit.document()) - self.ah = PythonHighlighter(self.ui.avoidCondEdit.document()) - - @staticmethod - def go(): - global _idangr_ctx - dialog = IDAngrExecDialog() - r = dialog.exec_() - if r == QtWidgets.QDialog.Accepted: - if dialog.ui.simprocsBox.isChecked(): - set_memory_type(SIMPROCS_FROM_CLE) - elif dialog.ui.textloaderBox.isChecked(): - set_memory_type(USE_CLE_MEMORY) - elif dialog.ui.gotloaderBox.isChecked(): - set_memory_type(ONLY_GOT_FROM_CLE) - elif dialog.ui.execallBox.isChecked(): - set_memory_type(GET_ALL_DISCARD_CLE) - - if dialog.ui.useFindCondBox.isChecked(): - code = dialog.ui.findCondEdit.toPlainText() - _idangr_ctx.find_lambda = code - finds = _idangr_ctx.find - avoids = _idangr_ctx.avoid - try: - if manage.is_remote(): - manage.remote_exec("finds = %s" % repr(finds)) - manage.remote_exec("avoids = %s" % repr(finds)) - manage.remote_exec(code) - else: - exec(code) in locals() - except Exception as ee: - QtWidgets.QMessageBox(QtWidgets.QMessageBox.Critical, 'Find Condition - Python Error', str(ee)).exec_() - return None - try: - if manage.is_remote(): - find = manage.remote_eval("find_cond") - else: - find = find_cond - except: - QtWidgets.QMessageBox(QtWidgets.QMessageBox.Critical, 'Error', "find_cond not defined").exec_() - return None - else: - find = _idangr_ctx.find - if dialog.ui.useAvoidCondBox.isChecked(): - code = dialog.ui.avoidCondEdit.toPlainText() - _idangr_ctx.avoid_lambda = code - finds = _idangr_ctx.find - avoids = _idangr_ctx.avoid - try: - if manage.is_remote(): - manage.remote_exec("finds = %s" % repr(finds)) - manage.remote_exec("avoids = %s" % repr(finds)) - manage.remote_exec(code) - else: - exec(code) in locals() - except Exception as ee: - QtWidgets.QMessageBox(QtWidgets.QMessageBox.Critical, 'Avoid Condition - Python Error', str(ee)).exec_() - return None - try: - if manage.is_remote(): - avoid = manage.remote_eval("avoid_cond") - else: - avoid = avoid_cond - except: - QtWidgets.QMessageBox(QtWidgets.QMessageBox.Critical, 'Error', "avoid_cond not defined").exec_() - return None - else: - avoid = _idangr_ctx.avoid - return (find, avoid) - return None - - class IDAngrTableModel(QtCore.QAbstractTableModel): def __init__(self, datain, headerdata, parent=None): @@ -324,6 +59,9 @@ def headerData(self, col, orientation, role): return None +def show_edit_hook(idx): + pass + class IDAngrPanelForm(PluginForm): def on_find_menu(self, point): @@ -333,11 +71,10 @@ def delete(): for i in self.ui.findView.selectedIndexes(): model.removeRow(i.row()) def jumpto(): - global _idangr_ctx model = self.ui.findView.model() sel = self.ui.findView.selectedIndexes() if len(sel) > 0: - idc.jumpto(_idangr_ctx.find[sel[0].row()]) + idc.jumpto(ctx.find[sel[0].row()]) m.addAction('Jump to', jumpto) m.addAction('Delete', delete) m.exec_(self.ui.findView.viewport().mapToGlobal(point)) @@ -349,14 +86,36 @@ def delete(): for i in self.ui.avoidView.selectedIndexes(): model.removeRow(i.row()) def jumpto(): - global _idangr_ctx model = self.ui.avoidView.model() sel = self.ui.avoidView.selectedIndexes() if len(sel) > 0: - idc.jumpto(_idangr_ctx.avoid[sel[0].row()]) + idc.jumpto(ctx.avoid[sel[0].row()]) m.addAction('Jump to', jumpto) m.addAction('Delete', delete) m.exec_(self.ui.avoidView.viewport().mapToGlobal(point)) + + def on_hook_menu(self, point): + m = QtWidgets.QMenu(self.ui.hooksView) + def delete(): + model = self.ui.hooksView.model() + for i in self.ui.hooksView.selectedIndexes(): + model.removeRow(i.row()) + def jumpto(): + global _idangr_hooks + model = self.ui.hooksView.model() + sel = self.ui.hooksView.selectedIndexes() + if len(sel) > 0: + idc.jumpto(_idangr_hooks[sel[0].row()][0]) + def edit(): + global _idangr_hooks + model = self.ui.hooksView.model() + sel = self.ui.hooksView.selectedIndexes() + if len(sel) > 0: + show_edit_hook(sel[0].row()) + m.addAction('Jump to', jumpto) + m.addAction('Edit code', edit) + m.addAction('Delete', delete) + m.exec_(self.ui.hooksView.viewport().mapToGlobal(point)) def add_find(self, addr): item = QtWidgets.QListWidgetItem("0x%x" % addr) @@ -378,18 +137,19 @@ def remove_avoid(self, addr): i = self.ui.avoidView.indexFromItem(item) model.removeRow(i.row()) + def add_hook(self, addr): + item = QtWidgets.QListWidgetItem("0x%x" % addr) + self.ui.hooksView.addItem(item) + + def remove_hook(self, addr): + model = self.ui.hooksView.model() + for item in self.ui.hooksView.findItems("0x%x" % addr, Qt.MatchExactly): + i = self.ui.hooksView.indexFromItem(item) + model.removeRow(i.row()) + def reset_clicked(self): - global _idangr_ctx - while len(_idangr_ctx.simregs) > 0: - _idangr_ctx.simregs.pop() - while len(_idangr_ctx.simmem) > 0: - _idangr_ctx.simmem.pop() - _idangr_ctx.find = [] - _idangr_ctx.avoid = [] - _idangr_ctx.stateman = None - _idangr_ctx.simman = None - _idangr_ctx.foundstate = None + ctx.reset() self.ui.regsView.model().layoutChanged.emit() self.ui.memoryView.model().layoutChanged.emit() self.ui.findView.clear() @@ -400,55 +160,54 @@ def reset_clicked(self): def run_clicked(self): - global _idangr_ctx conds = IDAngrExecDialog.go() if conds == None: return try: - _idangr_ctx.stateman = StateManager() + ctx.stateman = StateManager() except Exception as ee: QtWidgets.QMessageBox(QtWidgets.QMessageBox.Critical, 'StateManager - Python Error', str(ee)).exec_() return - for e in _idangr_ctx.simregs: - _idangr_ctx.stateman.sim(e[0]) - if e[0] in _idangr_ctx.constraints: + for e in ctx.simregs: + ctx.stateman.sim(e[0]) + if e[0] in ctx.constraints: try: - _idangr_ctx.constraints[e[0]][1](_idangr_ctx.stateman.symbolics[e[0]][0], _idangr_ctx.stateman.state) + ctx.constraints[e[0]][1](ctx.stateman.symbolics[e[0]][0], ctx.stateman.state) except Exception as ee: QtWidgets.QMessageBox(QtWidgets.QMessageBox.Critical, 'Constraints on %s - Python Error' % str(e[0]), str(ee)).exec_() return - for e in _idangr_ctx.simmem: + for e in ctx.simmem: addr = int(e[0], 16) - _idangr_ctx.stateman.sim(addr, int(e[1])) - if addr in _idangr_ctx.constraints: + ctx.stateman.sim(addr, int(e[1])) + if addr in ctx.constraints: try: - _idangr_ctx.constraints[addr][1](_idangr_ctx.stateman.symbolics[int(e[0], 16)][0], _idangr_ctx.stateman.state) + ctx.constraints[addr][1](ctx.stateman.symbolics[int(e[0], 16)][0], ctx.stateman.state) except Exception as ee: QtWidgets.QMessageBox(QtWidgets.QMessageBox.Critical, 'Constraints on %s - Python Error' % str(e[0]), str(ee)).exec_() return - sm = _idangr_ctx.stateman.simulation_manager() - _idangr_ctx.simman = sm + sm = ctx.stateman.simulation_manager() + ctx.simman = sm sm.explore(find=conds[0], avoid=conds[1]) if len(sm.found) == 0: - QtWidgets.QMessageBox(QtWidgets.QMessageBox.Warning, 'Not Found', "Valid state not found after exploration.\n" + str(_idangr_ctx.stateman) + "\n").exec_() + QtWidgets.QMessageBox(QtWidgets.QMessageBox.Warning, 'Not Found', "Valid state not found after exploration.\n" + str(ctx.stateman) + "\n").exec_() return - _idangr_ctx.foundstate = sm.found[0] - conc = _idangr_ctx.stateman.concretize(_idangr_ctx.foundstate) - for i in xrange(len(_idangr_ctx.simregs)): + ctx.foundstate = sm.found[0] + conc = ctx.stateman.concretize(ctx.foundstate) + for i in xrange(len(ctx.simregs)): try: - _idangr_ctx.simregs[i][2] = "0x%x" % conc[_idangr_ctx.simregs[i][0]] + ctx.simregs[i][2] = "0x%x" % conc[ctx.simregs[i][0]] except: pass - for i in xrange(len(_idangr_ctx.simmem)): + for i in xrange(len(ctx.simmem)): try: - _idangr_ctx.simmem[i][2] = repr(conc[int(_idangr_ctx.simmem[i][0], 16)]) + ctx.simmem[i][2] = repr(conc[int(ctx.simmem[i][0], 16)]) except: pass - #print _idangr_ctx.simmem + #print ctx.simmem - self.ui.filesBox.setRange(0, len(_idangr_ctx.foundstate.posix.fd) -1 +3) + self.ui.filesBox.setRange(0, len(ctx.foundstate.posix.files) -1) self.ui.regsView.model().layoutChanged.emit() self.ui.memoryView.model().layoutChanged.emit() @@ -460,56 +219,56 @@ def run_clicked(self): def next_clicked(self): - global _idangr_ctx conds = IDAngrExecDialog.go() if conds == None: return - if _idangr_ctx.stateman == None: - _idangr_ctx.stateman = StateManager() - for e in _idangr_ctx.simregs: - _idangr_ctx.stateman.sim(e[0]) - if e[0] in _idangr_ctx.constraints: + if ctx.stateman == None: + ctx.stateman = StateManager() + for e in ctx.simregs: + ctx.stateman.sim(e[0]) + if e[0] in ctx.constraints: try: - _idangr_ctx.constraints[e[0]][1](_idangr_ctx.stateman.symbolics[e[0]], _idangr_ctx.stateman.state) + ctx.constraints[e[0]][1](ctx.stateman.symbolics[e[0]], ctx.stateman.state) except Exception as ee: QtWidgets.QMessageBox(QtWidgets.QMessageBox.Critical, 'Constraints on %s - Python Error' % str(e[0]), str(ee)).exec_() return - for e in _idangr_ctx.simmem: + for e in ctx.simmem: addr = int(e[0], 16) - _idangr_ctx.stateman.sim(addr, int(e[1])) - if addr in _idangr_ctx.constraints: + ctx.stateman.sim(addr, int(e[1])) + if addr in ctx.constraints: try: - _idangr_ctx.constraints[addr][1](_idangr_ctx.stateman.symbolics[int(e[0], 16)], _idangr_ctx.stateman.state) + ctx.constraints[addr][1](ctx.stateman.symbolics[int(e[0], 16)], ctx.stateman.state) except Exception as ee: QtWidgets.QMessageBox(QtWidgets.QMessageBox.Critical, 'Constraints on %s - Python Error' % str(e[0]), str(ee)).exec_() return - if _idangr_ctx.simman == None: - if _idangr_ctx.foundstate == None: - sm = _idangr_ctx.stateman.simulation_manager() + if ctx.simman == None: + if ctx.foundstate == None: + sm = ctx.stateman.simulation_manager() else: - sm = load_project().factory.simulation_manager(_idangr_ctx.foundstate) - _idangr_ctx.simman = sm + sm = load_project().factory.simulation_manager(ctx.foundstate) + ctx.simman = sm else: - sm = _idangr_ctx.simman + sm = ctx.simman sm.explore(find=conds[0], avoid=conds[1]) if len(sm.found) == 0: - QtWidgets.QMessageBox(QtWidgets.QMessageBox.Warning, 'Not Found', "Valid state not found after exploration.\n" + str(_idangr_ctx.stateman) + "\n").exec_() + QtWidgets.QMessageBox(QtWidgets.QMessageBox.Warning, 'Not Found', "Valid state not found after exploration.\n" + str(ctx.stateman) + "\n").exec_() return - _idangr_ctx.foundstate = sm.found[-1] - conc = _idangr_ctx.stateman.concretize(_idangr_ctx.foundstate) - for i in xrange(len(_idangr_ctx.simregs)): + ctx.foundstate = sm.found[-1] + conc = ctx.stateman.concretize(ctx.foundstate) + for i in xrange(len(ctx.simregs)): try: - _idangr_ctx.simregs[i][2] = "0x%x" % conc[_idangr_ctx.simregs[i][0]] + ctx.simregs[i][2] = "0x%x" % conc[ctx.simregs[i][0]] except: pass - for i in xrange(len(_idangr_ctx.simmem)): + for i in xrange(len(ctx.simmem)): try: - _idangr_ctx.simmem[i][2] = repr(conc[int(_idangr_ctx.simmem[i][0], 16)]) + ctx.simmem[i][2] = repr(conc[int(ctx.simmem[i][0], 16)]) except: pass - #print _idangr_ctx.simmem - self.ui.filesBox.setRange(0, len(_idangr_ctx.foundstate.posix.fd) -1 +3) + + #print ctx.simmem + self.ui.filesBox.setRange(0, len(ctx.foundstate.posix.files) -1) self.ui.regsView.model().layoutChanged.emit() self.ui.memoryView.model().layoutChanged.emit() @@ -518,24 +277,22 @@ def next_clicked(self): def todbg_clicked(self): - global _idangr_ctx - _idangr_ctx.stateman.to_dbg(_idangr_ctx.foundstate) + ctx.stateman.to_dbg(ctx.foundstate) def on_regs_menu(self, point): - global _idangr_ctx m = QtWidgets.QMenu(self.ui.regsView) def delete(): model = self.ui.regsView.model() for i in self.ui.regsView.selectedIndexes(): - _idangr_ctx.simregs.pop(i.row()) + ctx.simregs.pop(i.row()) self.ui.regsView.model().layoutChanged.emit() def jumpto(): model = self.ui.regsView.model() sel = self.ui.regsView.selectedIndexes() if len(sel) > 0: try: - addr = int(_idangr_ctx.simregs[sel[0].row()][2], 16) + addr = int(ctx.simregs[sel[0].row()][2], 16) idc.jumpto(addr) except: pass @@ -545,12 +302,12 @@ def copyval(): if len(sel) > 0: cb = QtWidgets.QApplication.clipboard() cb.clear(mode=cb.Clipboard) - cb.setText(_idangr_ctx.simregs[sel[0].row()][2], mode=cb.Clipboard) + cb.setText(ctx.simregs[sel[0].row()][2], mode=cb.Clipboard) def set_constr(): model = self.ui.regsView.model() sel = self.ui.regsView.selectedIndexes() if len(sel) > 0: - item = _idangr_ctx.simregs[sel[0].row()][0] + item = ctx.simregs[sel[0].row()][0] IDAngrConstraintsDialog.go(item) m.addAction('Jump to', jumpto) m.addAction('Copy value', copyval) @@ -559,30 +316,29 @@ def set_constr(): m.exec_(self.ui.regsView.viewport().mapToGlobal(point)) def on_mem_menu(self, point): - global _idangr_ctx m = QtWidgets.QMenu(self.ui.memoryView) def delete(): model = self.ui.memoryView.model() for i in self.ui.memoryView.selectedIndexes(): - _idangr_ctx.simmem.pop(i.row()) + ctx.simmem.pop(i.row()) self.ui.memoryView.model().layoutChanged.emit() def jumpto(): model = self.ui.memoryView.model() sel = self.ui.memoryView.selectedIndexes() if len(sel) > 0: - idc.jumpto(int(_idangr_ctx.simmem[sel[0].row()][0], 16)) + idc.jumpto(int(ctx.simmem[sel[0].row()][0], 16)) def copyval(): model = self.ui.memoryView.model() sel = self.ui.memoryView.selectedIndexes() if len(sel) > 0: cb = QtWidgets.QApplication.clipboard() cb.clear(mode=cb.Clipboard) - cb.setText(_idangr_ctx.simmem[sel[0].row()][2], mode=cb.Clipboard) + cb.setText(ctx.simmem[sel[0].row()][2], mode=cb.Clipboard) def set_constr(): model = self.ui.memoryView.model() sel = self.ui.memoryView.selectedIndexes() if len(sel) > 0: - item = int(_idangr_ctx.simmem[sel[0].row()][0], 16) + item = int(ctx.simmem[sel[0].row()][0], 16) IDAngrConstraintsDialog.go(item) m.addAction('Jump to', jumpto) m.addAction('Copy value', copyval) @@ -592,19 +348,17 @@ def set_constr(): def add_reg(self, idx): - global _idangr_ctx - reg = _idangr_ctx.regs[idx] - for row in _idangr_ctx.simregs: #don't add a reg twice + reg = ctx.regs[idx] + for row in ctx.simregs: #don't add a reg twice if row[0] == reg: return - _idangr_ctx.simregs.append([reg, load_project().arch.registers[reg][1], "?"]) + ctx.simregs.append([reg, load_project().arch.registers[reg][1], "?"]) self.ui.regsView.model().layoutChanged.emit() def add_mem(self, addr, size): - global _idangr_ctx if type(addr) == int or type(addr) == long: addr = "0x%x" % addr - _idangr_ctx.simmem.append([addr, size, "?"]) + ctx.simmem.append([addr, size, "?"]) self.ui.memoryView.model().layoutChanged.emit() def remove_mem(self, addr): @@ -613,32 +367,29 @@ def remove_mem(self, addr): def view_file_clicked(self): - global _idangr_ctx fd = self.ui.filesBox.value() - IDAngrTextViewerForm.show_text(_idangr_ctx.foundstate.posix.dumps(fd), "File %d Viewer" % fd) + IDAngrTextViewerForm.show_text(ctx.foundstate.posix.dumps(fd), "File %d Viewer" % fd) def load_clicked(self): - global _idangr_ctx filename = QtWidgets.QFileDialog.getOpenFileName(self.parent, 'Open File')[0] if filename != "": self.reset_clicked() load_ctx(filename) - for addr in _idangr_ctx.find: + for addr in ctx.find: self.add_find(addr) - for addr in _idangr_ctx.avoid: + for addr in ctx.avoid: self.add_avoid(addr) - tablemodel = IDAngrTableModel(_idangr_ctx.simregs, ['Name', 'Size', 'Value'], self.parent) + tablemodel = IDAngrTableModel(ctx.simregs, ['Name', 'Size', 'Value'], self.parent) self.ui.regsView.setModel(tablemodel) self.ui.regsView.resizeColumnsToContents() - tablemodel = IDAngrTableModel(_idangr_ctx.simmem, ['Address', 'Length', 'Value'], self.parent) + tablemodel = IDAngrTableModel(ctx.simmem, ['Address', 'Length', 'Value'], self.parent) self.ui.memoryView.setModel(tablemodel) self.ui.memoryView.resizeColumnsToContents() def save_clicked(self): - global _idangr_ctx filename = QtWidgets.QFileDialog.getSaveFileName(self.parent, 'Save File')[0] if filename != "": save_ctx(filename) @@ -648,8 +399,7 @@ def OnCreate(self, form): """ Called when the plugin form is created """ - global _idangr_ctx - _idangr_ctx = IDAngrCtx() + #ctx.reset() # Get parent widget self.parent = self.FormToPyQtWidget(form) @@ -661,7 +411,8 @@ def OnCreate(self, form): self.ui.findView.customContextMenuRequested.connect(self.on_find_menu) self.ui.avoidView.customContextMenuRequested.connect(self.on_avoid_menu) - + self.ui.hooksView.customContextMenuRequested.connect(self.on_hook_menu) + self.ui.resetBtn.clicked.connect(self.reset_clicked) self.ui.runBtn.clicked.connect(self.run_clicked) self.ui.nextBtn.clicked.connect(self.next_clicked) @@ -670,25 +421,31 @@ def OnCreate(self, form): self.ui.loadBtn.clicked.connect(self.load_clicked) self.ui.saveBtn.clicked.connect(self.save_clicked) - _idangr_ctx.regs = sorted(project.arch.registers, key=lambda x: project.arch.registers.get(x)[0]) + ctx.regs = sorted(project.arch.registers, key=lambda x: project.arch.registers.get(x)[0]) - for reg in _idangr_ctx.regs: + for reg in ctx.regs: self.ui.registerChooser.addItem(reg) self.ui.registerChooser.setCurrentIndex(-1) self.ui.registerChooser.currentIndexChanged.connect(self.add_reg) - tablemodel = IDAngrTableModel(_idangr_ctx.simregs, ['Name', 'Size', 'Value'], self.parent) + tablemodel = IDAngrTableModel(ctx.simregs, ['Name', 'Size', 'Value'], self.parent) self.ui.regsView.setModel(tablemodel) self.ui.regsView.resizeColumnsToContents() - tablemodel = IDAngrTableModel(_idangr_ctx.simmem, ['Address', 'Length', 'Value'], self.parent) + tablemodel = IDAngrTableModel(ctx.simmem, ['Address', 'Length', 'Value'], self.parent) self.ui.memoryView.setModel(tablemodel) self.ui.memoryView.resizeColumnsToContents() self.ui.regsView.customContextMenuRequested.connect(self.on_regs_menu) self.ui.memoryView.customContextMenuRequested.connect(self.on_mem_menu) + for addr, _ in ctx.hooks: + self.add_hook(addr) + for addr in ctx.find: + self.add_find(addr) + for addr in ctx.avoid: + self.add_avoid(addr) def OnClose(self, form): @@ -706,8 +463,6 @@ def Show(self): options = (PluginForm.FORM_TAB | PluginForm.FORM_CLOSE_LATER)) - - class IDAngrActionHandler(idaapi.action_handler_t): def __init__(self, action): @@ -715,62 +470,68 @@ def __init__(self, action): self.action = action def activate(self, ctx): - global _idangr_ctx, _idangr_panel + global _idangr_panel if self.action == "Find": addr = idaapi.get_screen_ea() - if addr in _idangr_ctx.avoid: - _idangr_ctx.avoid.remove(addr) + if addr in ctx.avoid: + ctx.avoid.remove(addr) _idangr_panel.remove_avoid(addr) - if addr in _idangr_ctx.find: + if addr in ctx.find: return - _idangr_ctx.find.append(addr) + ctx.find.append(addr) _idangr_panel.add_find(addr) elif self.action == "Avoid": addr = idaapi.get_screen_ea() - if addr in _idangr_ctx.find: - _idangr_ctx.find.remove(addr) + if addr in ctx.find: + ctx.find.remove(addr) _idangr_panel.remove_find(addr) - if addr in _idangr_ctx.avoid: + if addr in ctx.avoid: return - _idangr_ctx.avoid.append(addr) + ctx.avoid.append(addr) _idangr_panel.add_avoid(addr) elif self.action == "Symbolic": addr = idaapi.get_screen_ea() - #if addr in _idangr_ctx.simmem: + #if addr in ctx.simmem: # return m = IDAngrAddMemDialog.get_mem(addr) if m != None: - _idangr_panel.add_mem(m[0], m[1]) - #_idangr_ctx.simmem.append(m) + _idangr_panel.add_mem(m[0], m[1]) #addr, size + #ctx.simmem.append(m) + elif self.action == "Hook": + addr = idaapi.get_screen_ea() + m = IDAngrHookDialog.get_hook(addr) + if m != None: + _idangr_panel.add_hook(m) def update(self, ctx): return idaapi.AST_ENABLE_ALWAYS -class IDAngrHooks(idaapi.UI_Hooks): + +class IDAngrUIHooks(idaapi.UI_Hooks): @staticmethod def finish_populating_tform_popup(form, popup): idaapi.attach_action_to_popup(form, popup, "Find", "IDAngr/") idaapi.attach_action_to_popup(form, popup, "Avoid", "IDAngr/") idaapi.attach_action_to_popup(form, popup, "Symbolic", "IDAngr/") + idaapi.attach_action_to_popup(form, popup, "Hook", "IDAngr/") idaapi.register_action(idaapi.action_desc_t('Find', 'Find', IDAngrActionHandler("Find"))) idaapi.register_action(idaapi.action_desc_t('Avoid', 'Avoid', IDAngrActionHandler("Avoid"))) idaapi.register_action(idaapi.action_desc_t('Symbolic', 'Symbolic', IDAngrActionHandler("Symbolic"))) +idaapi.register_action(idaapi.action_desc_t('Hook', 'Hook', IDAngrActionHandler("Hook"))) -_idangr_hooks = IDAngrHooks() -_idangr_hooks.hook() - +_ui_hooks = IDAngrUIHooks() +_ui_hooks.hook() -try: - _idangr_panel -except: - _idangr_panel = IDAngrPanelForm() +_idangr_panel = None def idangr_panel_show(): global _idangr_panel + if _idangr_panel == None: + _idangr_panel = IDAngrPanelForm() _idangr_panel.Show() diff --git a/idangr/manage.py b/idangr/manage.py index 181cd8e..fb9de26 100644 --- a/idangr/manage.py +++ b/idangr/manage.py @@ -1,6 +1,7 @@ import sys import rpyc import thread + from rpyc.utils.classic import DEFAULT_SERVER_PORT, DEFAULT_SERVER_SSL_PORT class AngrDbgNotInstalled(RuntimeError): diff --git a/idangr/ui/Makefile b/idangr/ui/Makefile index 37d6d48..204e3a1 100755 --- a/idangr/ui/Makefile +++ b/idangr/ui/Makefile @@ -1,4 +1,4 @@ -all: connect.py panel.py addmem.py execute.py viewer.py constraints.py saveds.py +all: connect.py panel.py addmem.py execute.py viewer.py constraints.py saveds.py editor.py connect.py: %.py: %.ui pyuic5 connect.ui -o connect.py @@ -21,6 +21,8 @@ constraints.py: %.py: %.ui saveds.py: %.py: %.ui pyuic5 saveds.ui -o saveds.py +editor.py: %.py: %.ui + pyuic5 editor.ui -o editor.py clean: - rm panel.py addmem.py execute.py viewer.py constraints.py saveds.py + rm connect.py panel.py addmem.py execute.py viewer.py constraints.py saveds.py editor.py diff --git a/idangr/ui/__init__.py b/idangr/ui/__init__.py index 1157280..e4f3aaf 100755 --- a/idangr/ui/__init__.py +++ b/idangr/ui/__init__.py @@ -5,5 +5,6 @@ from viewer import * from constraints import * from saveds import * +from editor import * from syntax import PythonHighlighter diff --git a/idangr/ui/editor.py b/idangr/ui/editor.py new file mode 100644 index 0000000..e52a70d --- /dev/null +++ b/idangr/ui/editor.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- + +# Form implementation generated from reading ui file 'editor.ui' +# +# Created by: PyQt5 UI code generator 5.10.1 +# +# WARNING! All changes made in this file will be lost! + +from PyQt5 import QtCore, QtGui, QtWidgets + +class Ui_IDAngrEditorDialog(object): + def setupUi(self, IDAngrEditorDialog): + IDAngrEditorDialog.setObjectName("IDAngrEditorDialog") + IDAngrEditorDialog.resize(750, 604) + self.gridLayout = QtWidgets.QGridLayout(IDAngrEditorDialog) + self.gridLayout.setObjectName("gridLayout") + self.codeEdit = QtWidgets.QPlainTextEdit(IDAngrEditorDialog) + self.codeEdit.setObjectName("codeEdit") + self.gridLayout.addWidget(self.codeEdit, 0, 0, 1, 1) + self.buttonBox = QtWidgets.QDialogButtonBox(IDAngrEditorDialog) + self.buttonBox.setOrientation(QtCore.Qt.Horizontal) + self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok) + self.buttonBox.setObjectName("buttonBox") + self.gridLayout.addWidget(self.buttonBox, 1, 0, 1, 1) + + self.retranslateUi(IDAngrEditorDialog) + self.buttonBox.accepted.connect(IDAngrEditorDialog.accept) + self.buttonBox.rejected.connect(IDAngrEditorDialog.reject) + QtCore.QMetaObject.connectSlotsByName(IDAngrEditorDialog) + + def retranslateUi(self, IDAngrEditorDialog): + _translate = QtCore.QCoreApplication.translate + IDAngrEditorDialog.setWindowTitle(_translate("IDAngrEditorDialog", "Editor")) + diff --git a/idangr/ui/editor.ui b/idangr/ui/editor.ui index acc9022..7f8f89a 100644 --- a/idangr/ui/editor.ui +++ b/idangr/ui/editor.ui @@ -1,7 +1,7 @@ - Dialog - + IDAngrEditorDialog + 0 @@ -11,31 +11,30 @@ - Dialog + Editor - - - - 400 - 570 - 341 - 32 - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + buttonBox accepted() - Dialog + IDAngrEditorDialog accept() @@ -51,7 +50,7 @@ buttonBox rejected() - Dialog + IDAngrEditorDialog reject() diff --git a/idangr/ui/panel.py b/idangr/ui/panel.py index ed0f468..db75a82 100644 --- a/idangr/ui/panel.py +++ b/idangr/ui/panel.py @@ -14,72 +14,8 @@ def setupUi(self, IDAngrPanel): IDAngrPanel.setEnabled(True) IDAngrPanel.resize(926, 703) IDAngrPanel.setLayoutDirection(QtCore.Qt.LeftToRight) - self.gridLayout_6 = QtWidgets.QGridLayout(IDAngrPanel) - self.gridLayout_6.setObjectName("gridLayout_6") - self.gridLayout_5 = QtWidgets.QGridLayout() + self.gridLayout_5 = QtWidgets.QGridLayout(IDAngrPanel) self.gridLayout_5.setObjectName("gridLayout_5") - self.gridLayout = QtWidgets.QGridLayout() - self.gridLayout.setSpacing(12) - self.gridLayout.setObjectName("gridLayout") - self.label_2 = QtWidgets.QLabel(IDAngrPanel) - self.label_2.setMinimumSize(QtCore.QSize(0, 41)) - self.label_2.setObjectName("label_2") - self.gridLayout.addWidget(self.label_2, 0, 0, 1, 1) - self.memoryView = QtWidgets.QTableView(IDAngrPanel) - self.memoryView.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) - self.memoryView.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection) - self.memoryView.setSortingEnabled(False) - self.memoryView.setObjectName("memoryView") - self.gridLayout.addWidget(self.memoryView, 1, 0, 1, 2) - self.gridLayout_5.addLayout(self.gridLayout, 0, 0, 1, 1) - self.gridLayout_2 = QtWidgets.QGridLayout() - self.gridLayout_2.setObjectName("gridLayout_2") - self.regsView = QtWidgets.QTableView(IDAngrPanel) - self.regsView.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) - self.regsView.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection) - self.regsView.setSortingEnabled(False) - self.regsView.setObjectName("regsView") - self.gridLayout_2.addWidget(self.regsView, 1, 0, 1, 2) - self.registerChooser = QtWidgets.QComboBox(IDAngrPanel) - self.registerChooser.setObjectName("registerChooser") - self.gridLayout_2.addWidget(self.registerChooser, 0, 1, 1, 1) - self.label = QtWidgets.QLabel(IDAngrPanel) - self.label.setMinimumSize(QtCore.QSize(0, 41)) - self.label.setObjectName("label") - self.gridLayout_2.addWidget(self.label, 0, 0, 1, 1) - self.gridLayout_5.addLayout(self.gridLayout_2, 0, 1, 1, 1) - self.gridLayout_6.addLayout(self.gridLayout_5, 2, 0, 1, 1) - self.splitter_2 = QtWidgets.QSplitter(IDAngrPanel) - self.splitter_2.setMaximumSize(QtCore.QSize(16777215, 16777215)) - self.splitter_2.setOrientation(QtCore.Qt.Horizontal) - self.splitter_2.setObjectName("splitter_2") - self.layoutWidget = QtWidgets.QWidget(self.splitter_2) - self.layoutWidget.setObjectName("layoutWidget") - self.gridLayout_3 = QtWidgets.QGridLayout(self.layoutWidget) - self.gridLayout_3.setContentsMargins(0, 0, 0, 0) - self.gridLayout_3.setObjectName("gridLayout_3") - self.label_3 = QtWidgets.QLabel(self.layoutWidget) - self.label_3.setObjectName("label_3") - self.gridLayout_3.addWidget(self.label_3, 0, 0, 1, 1) - self.findView = QtWidgets.QListWidget(self.layoutWidget) - self.findView.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) - self.findView.setSelectionMode(QtWidgets.QAbstractItemView.MultiSelection) - self.findView.setObjectName("findView") - self.gridLayout_3.addWidget(self.findView, 1, 0, 1, 1) - self.layoutWidget_2 = QtWidgets.QWidget(self.splitter_2) - self.layoutWidget_2.setObjectName("layoutWidget_2") - self.gridLayout_4 = QtWidgets.QGridLayout(self.layoutWidget_2) - self.gridLayout_4.setContentsMargins(0, 0, 0, 0) - self.gridLayout_4.setObjectName("gridLayout_4") - self.label_4 = QtWidgets.QLabel(self.layoutWidget_2) - self.label_4.setObjectName("label_4") - self.gridLayout_4.addWidget(self.label_4, 0, 0, 1, 1) - self.avoidView = QtWidgets.QListWidget(self.layoutWidget_2) - self.avoidView.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) - self.avoidView.setSelectionMode(QtWidgets.QAbstractItemView.MultiSelection) - self.avoidView.setObjectName("avoidView") - self.gridLayout_4.addWidget(self.avoidView, 1, 0, 1, 1) - self.gridLayout_6.addWidget(self.splitter_2, 3, 0, 1, 1) self.widget = QtWidgets.QWidget(IDAngrPanel) self.widget.setEnabled(True) self.widget.setMinimumSize(QtCore.QSize(0, 41)) @@ -98,7 +34,7 @@ def setupUi(self, IDAngrPanel): self.todbgBtn.setObjectName("todbgBtn") self.viewFileBtn = QtWidgets.QPushButton(self.widget) self.viewFileBtn.setEnabled(False) - self.viewFileBtn.setGeometry(QtCore.QRect(500, 10, 122, 27)) + self.viewFileBtn.setGeometry(QtCore.QRect(500, 10, 141, 27)) self.viewFileBtn.setObjectName("viewFileBtn") self.filesBox = QtWidgets.QSpinBox(self.widget) self.filesBox.setGeometry(QtCore.QRect(400, 10, 91, 27)) @@ -115,7 +51,84 @@ def setupUi(self, IDAngrPanel): self.saveBtn.setEnabled(True) self.saveBtn.setGeometry(QtCore.QRect(760, 10, 85, 27)) self.saveBtn.setObjectName("saveBtn") - self.gridLayout_6.addWidget(self.widget, 0, 0, 1, 1) + self.gridLayout_5.addWidget(self.widget, 0, 0, 1, 1) + self.splitter_3 = QtWidgets.QSplitter(IDAngrPanel) + self.splitter_3.setOrientation(QtCore.Qt.Vertical) + self.splitter_3.setObjectName("splitter_3") + self.widget1 = QtWidgets.QWidget(self.splitter_3) + self.widget1.setObjectName("widget1") + self.gridLayout = QtWidgets.QGridLayout(self.widget1) + self.gridLayout.setContentsMargins(0, 0, 0, 0) + self.gridLayout.setObjectName("gridLayout") + self.label_3 = QtWidgets.QLabel(self.widget1) + self.label_3.setObjectName("label_3") + self.gridLayout.addWidget(self.label_3, 0, 0, 1, 1) + self.label_4 = QtWidgets.QLabel(self.widget1) + self.label_4.setObjectName("label_4") + self.gridLayout.addWidget(self.label_4, 0, 1, 1, 1) + self.findView = QtWidgets.QListWidget(self.widget1) + self.findView.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) + self.findView.setSelectionMode(QtWidgets.QAbstractItemView.MultiSelection) + self.findView.setObjectName("findView") + self.gridLayout.addWidget(self.findView, 1, 0, 1, 1) + self.avoidView = QtWidgets.QListWidget(self.widget1) + self.avoidView.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) + self.avoidView.setSelectionMode(QtWidgets.QAbstractItemView.MultiSelection) + self.avoidView.setObjectName("avoidView") + self.gridLayout.addWidget(self.avoidView, 1, 1, 1, 1) + self.splitter_2 = QtWidgets.QSplitter(self.splitter_3) + self.splitter_2.setOrientation(QtCore.Qt.Horizontal) + self.splitter_2.setObjectName("splitter_2") + self.widget2 = QtWidgets.QWidget(self.splitter_2) + self.widget2.setObjectName("widget2") + self.gridLayout_4 = QtWidgets.QGridLayout(self.widget2) + self.gridLayout_4.setContentsMargins(0, 0, 0, 0) + self.gridLayout_4.setObjectName("gridLayout_4") + self.label_2 = QtWidgets.QLabel(self.widget2) + self.label_2.setMinimumSize(QtCore.QSize(0, 41)) + self.label_2.setObjectName("label_2") + self.gridLayout_4.addWidget(self.label_2, 0, 0, 1, 1) + self.memoryView = QtWidgets.QTableView(self.widget2) + self.memoryView.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) + self.memoryView.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection) + self.memoryView.setSortingEnabled(False) + self.memoryView.setObjectName("memoryView") + self.gridLayout_4.addWidget(self.memoryView, 1, 0, 1, 1) + self.splitter = QtWidgets.QSplitter(self.splitter_2) + self.splitter.setOrientation(QtCore.Qt.Vertical) + self.splitter.setObjectName("splitter") + self.widget3 = QtWidgets.QWidget(self.splitter) + self.widget3.setObjectName("widget3") + self.gridLayout_2 = QtWidgets.QGridLayout(self.widget3) + self.gridLayout_2.setContentsMargins(0, 0, 0, 0) + self.gridLayout_2.setObjectName("gridLayout_2") + self.label = QtWidgets.QLabel(self.widget3) + self.label.setMinimumSize(QtCore.QSize(0, 41)) + self.label.setObjectName("label") + self.gridLayout_2.addWidget(self.label, 0, 0, 1, 1) + self.registerChooser = QtWidgets.QComboBox(self.widget3) + self.registerChooser.setObjectName("registerChooser") + self.gridLayout_2.addWidget(self.registerChooser, 0, 1, 1, 1) + self.regsView = QtWidgets.QTableView(self.widget3) + self.regsView.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) + self.regsView.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection) + self.regsView.setSortingEnabled(False) + self.regsView.setObjectName("regsView") + self.gridLayout_2.addWidget(self.regsView, 1, 0, 1, 2) + self.widget4 = QtWidgets.QWidget(self.splitter) + self.widget4.setObjectName("widget4") + self.gridLayout_3 = QtWidgets.QGridLayout(self.widget4) + self.gridLayout_3.setContentsMargins(0, 0, 0, 0) + self.gridLayout_3.setObjectName("gridLayout_3") + self.label_5 = QtWidgets.QLabel(self.widget4) + self.label_5.setObjectName("label_5") + self.gridLayout_3.addWidget(self.label_5, 0, 0, 1, 1) + self.hooksView = QtWidgets.QListWidget(self.widget4) + self.hooksView.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) + self.hooksView.setSelectionMode(QtWidgets.QAbstractItemView.MultiSelection) + self.hooksView.setObjectName("hooksView") + self.gridLayout_3.addWidget(self.hooksView, 1, 0, 1, 1) + self.gridLayout_5.addWidget(self.splitter_3, 1, 0, 1, 1) self.retranslateUi(IDAngrPanel) QtCore.QMetaObject.connectSlotsByName(IDAngrPanel) @@ -123,16 +136,17 @@ def setupUi(self, IDAngrPanel): def retranslateUi(self, IDAngrPanel): _translate = QtCore.QCoreApplication.translate IDAngrPanel.setWindowTitle(_translate("IDAngrPanel", "IDAngr Panel")) - self.label_2.setText(_translate("IDAngrPanel", " Symbolic memory")) - self.label.setText(_translate("IDAngrPanel", " Symbolic registers")) + self.resetBtn.setText(_translate("IDAngrPanel", "Reset")) + self.runBtn.setText(_translate("IDAngrPanel", "Run")) + self.todbgBtn.setText(_translate("IDAngrPanel", "To Dbg")) + self.viewFileBtn.setText(_translate("IDAngrPanel", "View File Dump")) + self.nextBtn.setText(_translate("IDAngrPanel", "Next")) + self.loadBtn.setText(_translate("IDAngrPanel", "Load")) + self.saveBtn.setText(_translate("IDAngrPanel", "Save")) self.label_3.setText(_translate("IDAngrPanel", " Find")) - self.findView.setSortingEnabled(False) self.label_4.setText(_translate("IDAngrPanel", " Avoid")) - self.resetBtn.setText(_translate("IDAngrPanel", "RESET")) - self.runBtn.setText(_translate("IDAngrPanel", "RUN")) - self.todbgBtn.setText(_translate("IDAngrPanel", "TO DBG")) - self.viewFileBtn.setText(_translate("IDAngrPanel", "View File Dump")) - self.nextBtn.setText(_translate("IDAngrPanel", "NEXT")) - self.loadBtn.setText(_translate("IDAngrPanel", "LOAD")) - self.saveBtn.setText(_translate("IDAngrPanel", "SAVE")) + self.findView.setSortingEnabled(False) + self.label_2.setText(_translate("IDAngrPanel", " Symbolic memory")) + self.label.setText(_translate("IDAngrPanel", " Symbolic registers")) + self.label_5.setText(_translate("IDAngrPanel", "Hooks")) diff --git a/idangr/ui/panel.ui b/idangr/ui/panel.ui index 735b8de..91c202c 100755 --- a/idangr/ui/panel.ui +++ b/idangr/ui/panel.ui @@ -19,135 +19,7 @@ Qt::LeftToRight - - - - - - - 12 - - - - - - 0 - 41 - - - - Symbolic memory - - - - - - - Qt::CustomContextMenu - - - QAbstractItemView::SingleSelection - - - false - - - - - - - - - - - Qt::CustomContextMenu - - - QAbstractItemView::SingleSelection - - - false - - - - - - - - - - - 0 - 41 - - - - Symbolic registers - - - - - - - - - - - - 16777215 - 16777215 - - - - Qt::Horizontal - - - - - - - Find - - - - - - - Qt::CustomContextMenu - - - QAbstractItemView::MultiSelection - - - false - - - - - - - - - - - Avoid - - - - - - - Qt::CustomContextMenu - - - QAbstractItemView::MultiSelection - - - - - - - + @@ -172,7 +44,7 @@ - RESET + Reset @@ -188,7 +60,7 @@ - RUN + Run @@ -204,7 +76,7 @@ - TO DBG + To Dbg @@ -215,7 +87,7 @@ 500 10 - 122 + 141 27 @@ -246,7 +118,7 @@ - NEXT + Next @@ -262,7 +134,7 @@ - LOAD + Load @@ -278,8 +150,150 @@ - SAVE + Save + + + + + + + + Qt::Vertical + + + + + + + Find + + + + + + + Avoid + + + + + + + Qt::CustomContextMenu + + + QAbstractItemView::MultiSelection + + + false + + + + + + + Qt::CustomContextMenu + + + QAbstractItemView::MultiSelection + + + + + + + + Qt::Horizontal + + + + + + + 0 + 41 + + + + Symbolic memory + + + + + + + Qt::CustomContextMenu + + + QAbstractItemView::SingleSelection + + + false + + + + + + + + Qt::Vertical + + + + + + + + 0 + 41 + + + + Symbolic registers + + + + + + + + + + Qt::CustomContextMenu + + + QAbstractItemView::SingleSelection + + + false + + + + + + + + + + + Hooks + + + + + + + Qt::CustomContextMenu + + + QAbstractItemView::MultiSelection + + + + + + diff --git a/idangr_plugin.py b/idangr_plugin.py index 7d339a7..4dd7503 100644 --- a/idangr_plugin.py +++ b/idangr_plugin.py @@ -1,4 +1,4 @@ - +import idaapi class IDAngrPlugin(idaapi.plugin_t): flags = idaapi.PLUGIN_KEEP