def run(self, arg): # this is called when select the plugin from the Edit>Plugins menu if (not self.have_taint_info()): # don't even have a file of taint information selected yet filename, _ = QFileDialog.getOpenFileName(None, self.OPEN_CAPTION, self.OPEN_DIRECTORY, self.OPEN_FILTER) if filename == "": # taint must already be disabled, so no need to re-disable return self._taint_file = filename if (self._update_process()): self.show_taint_info() self._seen_file = True elif (self.showing_taint()): request = ReuseTaintDialog.askToReuse(self._taint_file, self._tainted_process) if (ReuseTaintDialog.GET_NEW_PROCESS == request): if (self._update_process()): idaapi.refresh_idaview_anyway() ida_kernwin.refresh_chooser(ShowTaintedFuncs.TITLE) elif (ReuseTaintDialog.GET_NEW_FILE == request): filename, _ = QFileDialog.getOpenFileName(None, self.OPEN_CAPTION, self.OPEN_DIRECTORY, self.OPEN_FILTER) if filename == "": # user must've changed his mind return self._taint_file = filename self._seen_file = False if (self._update_process()): self._seen_file = True idaapi.refresh_idaview_anyway() ida_kernwin.refresh_chooser(ShowTaintedFuncs.TITLE) else: # must have an old file and process selected, but taint disabled # note that _update_process wipes _tainted_process and _taint_file # if the user cancels the process selection, so we should not have # _taint_file set without _tainted_process also being set request = ReuseTaintDialog.askToReuse(self._taint_file, self._tainted_process) if (ReuseTaintDialog.GET_NEW_PROCESS == request): if (self._update_process()): self.show_taint_info() elif (ReuseTaintDialog.GET_NEW_FILE == request): filename, _ = QFileDialog.getOpenFileName(None, self.OPEN_CAPTION, self.OPEN_DIRECTORY, self.OPEN_FILTER) if (filename == ""): return self._taint_file = filename self._seen_file = False if (self._update_process()): self.show_taint_info() self._seen_file = True
def activate(self, ctx): sel = [] for idx in ctx.chooser_selection: # rename the function ea = get_name_ea_simple(self.items[idx][2]) sfname = str(self.items[idx][4]) #set_name(ea, sfname) idaapi.do_name_anyway(ea, sfname) success('{:#x}: renamed to {}'.format(ea, sfname)) # set the function prototype sptype = str(self.items[idx][5]) if sptype != 'None': tinfo = idaapi.tinfo_t() idaapi.parse_decl2(idaapi.cvar.idati, sptype, tinfo, 0) #idaapi.apply_callee_tinfo(ea, tinfo) if idaapi.apply_tinfo(ea, tinfo, 0): success('{:#x}: function prototype set to {}'.format( ea, sptype)) else: error( '{:#x}: function prototype set FAILED (maybe you should import the types?)' .format(ea)) if ask_yn(0, 'Do you import types from the secondary idb?' ) == 1: if self.import_types(): tinfo = idaapi.tinfo_t() idaapi.parse_decl2(idaapi.cvar.idati, sptype, tinfo, 0) if idaapi.apply_tinfo(ea, tinfo, 0): success('{:#x}: function prototype set to {}'. format(ea, sptype)) else: error( '{:#x}: function prototype set FAILED again' .format(ea)) # insert the comment score = self.items[idx][0] mmatch = self.items[idx][1] cmt = 'fn_fuzzy: ssdeep={}, machoc={}'.format(score, mmatch) set_func_cmt(ea, cmt, 1) #set_decomplier_cmt(ea, cmt) # not sure how to avoid orphan comment # update the Choose rows ida_kernwin.refresh_chooser(self.title)
def rebase_taint_info(self): if (not (self._taint_file == None)): input_file = open(self._taint_file, "r") reader = csv.reader(input_file) self._tainted_funcs.clear() self._skip_csv_header(reader, False) for row in reader: pid = int(row[1]) pc = int(row[2], 16) if pid != self._tainted_process['process_id']: continue fn = ida_funcs.get_func(pc) if not fn: continue fn_start = fn.start_ea self._tainted_funcs.add(fn_start) input_file.close() ida_kernwin.refresh_chooser(ShowTaintedFuncs.TITLE)
def show_taint_info(self): self._instr_painter.hook() self._instr_hint_hook.hook() self._hooks_installed = True idaapi.refresh_idaview_anyway() ida_kernwin.refresh_chooser(ShowTaintedFuncs.TITLE)