# coding: utf8 import re import sys import time from PyQt5 import QtGui, QtWidgets import idc from idasec.dba_printer import instr_to_string from idasec.network.commands import END, DECODE_INSTR_REPLY from idasec.network.message import MessageInfos, MessageDecodeInstr, MessageDecodeInstrReply from idasec.ui.main_ui import Ui_Main from idasec.utils import to_hex class MainWidget(QtWidgets.QWidget, Ui_Main): def __init__(self, parent): super(MainWidget, self).__init__() self.parent = parent self.name = "MainWidget" self.core = self.parent.core self.broker = self.core.broker self.icon = QtGui.QIcon("semantics.png") self.OnCreate(self) # class IDASecApp(PluginForm, Ui_Main): def OnCreate(self, _): self.setupUi(self) self.binsec_connect_button.clicked.connect(self.connect_binsec) self.dba_decode_button.clicked.connect(self.decode_button_clicked) self.here_decode_button.clicked.connect(self.decode_here_clicked) self.pinsec_ip_field.setText("192.168.56.101") self.pinsec_port_field.setText("5555") self.binsec_port_field.setValidator(QtGui.QIntValidator(0, 65535)) self.pinsec_port_field.setValidator(QtGui.QIntValidator(0, 65535)) self.ok = QtGui.QPixmap(":/icons/icons/oxygen/22x22/ok.png") self.ko = QtGui.QPixmap(":/icons/icons/oxygen/22x22/ko.png") self.prev_modules = sys.modules.keys() self.set_pinsec_visible(False) def connect_binsec(self): try: time.sleep(0.1) except Exception: print "Something went wrong (with Binsec connection)..." if self.core.binsec_connected: self.broker.disconnect_binsec() self.set_disconnected() else: ip = self.binsec_ip_field.text() port = self.binsec_port_field.text() self.broker.connect_binsec(ip, port) self.broker.send_binsec_message("GET_INFOS", "STUB", blocking=False) time.sleep(0.1) cmd, data = self.broker.receive_binsec_message(blocking=False) if cmd is not None and data is not None: print "Connected to Binsec" self.binsec_label_status.setPixmap(self.ok) message = MessageInfos() message.parse(data) nb_workers, analyses, solvers = message.get_infos() self.infos_label.setText( "CPU:%d\nAnalyses:%s\nSolvers:%s" % (nb_workers, " ".join(analyses), " ".join(solvers))) self.parent.add_solvers(solvers) self.parent.add_analyses([x.upper() for x in analyses]) self.core.nb_cpus = nb_workers self.set_connected() else: print "Not Connected to Binsec" self.set_disconnected() self.binsec_label_status.setPixmap(self.ko) def set_connected(self): self.core.binsec_connected = True self.infos_title_label.setEnabled(True) self.infos_label.setEnabled(True) self.utils_label.setEnabled(True) self.ir_label.setEnabled(True) self.dba_decode_field.setEnabled(True) self.dba_decode_button.setEnabled(True) self.ir_textarea.setEnabled(True) self.binsec_connect_button.setText("disconnect") self.binsec_port_field.setEnabled(False) self.binsec_ip_field.setEnabled(False) def set_disconnected(self): self.core.binsec_connected = False self.binsec_label_status.clear() self.infos_title_label.setEnabled(False) self.infos_label.setEnabled(False) self.utils_label.setEnabled(False) self.ir_label.setEnabled(False) self.dba_decode_field.setEnabled(False) self.dba_decode_button.setEnabled(False) self.ir_textarea.setEnabled(False) self.binsec_connect_button.setText("connect") self.binsec_port_field.setEnabled(True) self.binsec_ip_field.setEnabled(True) def set_pinsec_visible(self, value): self.label_2.setVisible(value) self.pinsec_connect_button.setVisible(value) self.pinsec_ip_field.setVisible(value) self.pinsec_label.setVisible(value) self.pinsec_port_field.setVisible(value) def decode_here_clicked(self): inst = idc.here() if not idc.isCode(idc.GetFlags(inst)): print "Not code instruction" else: raw = idc.GetManyBytes(inst, idc.NextHead(inst)-inst) s = to_hex(raw) self.decode_ir(s) def decode_button_clicked(self): opc = self.dba_decode_field.text().encode('ascii', 'ignore').replace(" ", "") if not re.match('^[0-9a-fA-F]+$', opc): print "Invalid input:"+opc return self.decode_ir(opc) def decode_ir(self, opc): if not self.core.binsec_connected: self.parent.log("ERROR", "Not connected to Binsec") return if opc != "": mess = MessageDecodeInstr(kind="hexa", instrs=opc, base_addrs=0) raw = mess.serialize() self.broker.send_binsec_message("DECODE_INSTR", raw, blocking=False) time.sleep(0.2) cmd, data = self.broker.receive_binsec_message(blocking=False) if cmd is not None and data is not None: if cmd == END: self.ir_textarea.setText("Error occured:"+data) elif cmd == DECODE_INSTR_REPLY: reply = MessageDecodeInstrReply() reply.parse(data) for opc, dbainsts in reply.instrs: self.ir_textarea.setText(opc+":") length = len(dbainsts)-1 arr = ["⎧" if i == 0 else "⎩" if i == length - 1 else "⎨" if i == length / 2 else "⎪" for i in range(length)] arr = [""] if length == 1 else arr for i in range(len(dbainsts[:-1])): dba = dbainsts[i] self.ir_textarea.append(arr[i]+instr_to_string(dba)) else: print "Unknown cmd:"+cmd else: print "Timeout exceeded to receive a binsec reply" else: print "Invalid input :"+opc def OnClose(self, _): print("Closed invoked !") pass