def main(): if not idaapi.is_debugger_on(): idc.Warning("Please run the process first!") return if idaapi.get_process_state() != -1: idc.Warning("Please suspend the debugger first!") return # only avail from IdaPython r232 if hasattr(idaapi, "NearestName"): # get all debug names dn = idaapi.get_debug_names(idaapi.cvar.inf.minEA, idaapi.cvar.inf.maxEA) # initiate a nearest name search (using debug names) nn = idaapi.NearestName(dn) else: nn = None ret, callstack = CallStackWalk(nn) if ret: title = "Call stack walker (thread %X)" % (GetCurrentThreadId()) idaapi.close_chooser(title) c = CallStackWalkChoose(callstack, title) c.choose() else: idc.Warning("Failed to walk the stack:" + callstack)
def main(): if not idaapi.is_debugger_on(): idc.Warning("Please run the process first!") return if idaapi.get_process_state() != -1: idc.Warning("Please suspend the debugger first!") return info = idaapi.get_inf_structure() if info.is_64bit(): long_size = 8 elif info.is_32bit(): long_size = 4 else: idc.Warning("Only 32 or 64 bit is supported!") return # only avail from IdaPython r232 if hasattr(idaapi, "NearestName"): # get all debug names dn = idaapi.get_debug_names(idaapi.cvar.inf.minEA, idaapi.cvar.inf.maxEA) # initiate a nearest name search (using debug names) nn = idaapi.NearestName(dn) else: nn = None RetAddrStackWalk(nn, long_size)
def retrieve_reset(self, *args): if not idaapi.askyn_c( False, "All your local changes will be lost !\nDo you really want to proceed ?" ): return # disable all yaco hooks self.YaCoUI.unhook() # create a backup of current idb yatools.copy_idb_to_local_file( "_bkp_%s" % time.ctime().replace(" ", "_").replace(":", "_")) # delete all modified objects self.repo_manager.repo.checkout_head() # get reset self.repo_manager.fetch_origin() self.repo_manager.rebase_from_origin() original_idb_name = yatools.get_original_idb_name(idc.GetIdbPath()) # remove current idb os.remove(idc.GetIdbPath()) # recreate local idb shutil.copy(original_idb_name, yatools.get_local_idb_name(original_idb_name)) # local should not be overwritten, so we have to close IDA brutally ! idaapi.cvar.database_flags |= idaapi.DBFL_KILL idc.Warning("Force pull complete, you can restart IDA") idc.Exit(0)
def __init__(self, symbols=True): try: check_and_configure_bap() except: idc.Message('BAP> configuration failed\n{0}\n'.format( str(sys.exc_info()))) traceback.print_exc() raise BapIdaError() bap = config.get('bap_executable_path') if bap is None or not os.access(bap, os.X_OK): idc.Warning(''' The bap application is either not found or is not an executable. Please install bap or, if it is installed, provide a path to it. Installation instructions are available at: http://bap.ece.cmu.edu. ''') raise BapNotFound() binary = idaapi.get_input_file_path() super(BapIda, self).__init__(bap, binary) # if you run IDA inside IDA you will crash IDA self.args.append('--no-ida') self._on_finish = [] self._on_cancel = [] self._on_failed = [] if symbols: self._setup_symbols() headers = config.is_set('ida_api.enabled') if headers: self._setup_headers(bap)
def GetCurrentFuncsView(self): if self.ColorFuncsView == None: idc.Warning("First analyse profile file, man") return False else: self.ColorFuncsView.show() return True
def bulk_prefix(): """ Prefix the Functions window selection with a user defined string. """ # prompt the user for a prefix to apply to the selected functions tag = idc.AskStr(PREFIX_DEFAULT, "Function Tag") # the user closed the window... ignore if tag == None: return # the user put a blank string and hit 'okay'... notify & ignore elif tag == '': idc.Warning("[ERROR] Tag cannot be empty [ERROR]") return # # loop through all the functions selected in the 'Functions window' and # apply the user defined prefix tag to each one. # for func_name in get_selected_funcs(): # ignore functions that already have the specified prefix applied if func_name.startswith(tag): continue # apply the user defined prefix to the function (rename it) new_name = '%s%s%s' % (str(tag), PREFIX_SEPARATOR, func_name) idc.MakeNameEx(idc.LocByName(func_name), new_name, idaapi.SN_NOWARN) # refresh the IDA views refresh_views()
def make_enums(self): """ Create the enumerations from the files. This function will read all .txt files in a given directory and create an enum for each file. """ dir_path = idc.AskStr("", "Enter full path to the directory of dumped PoisonIvy symbols") if not os.path.exists(dir_path): idc.Warning("Invalid path. Restart script and enter a valid path") idc.Exit for item in os.listdir(dir_path): filename = os.path.join(dir_path, item) if not os.path.isfile(filename): continue if not filename.endswith('.txt'): continue with open(filename, 'rb') as fh: symbols = self.fixdata(fh) self.createenum(symbols)
def check_valid_cache_startup(self): logger.debug("check_valid_cache_startup") if "origin" not in self.repo.get_remotes(): logger.debug( "WARNING origin not defined : ignoring origin and master sync check !" ) else: if self.repo.get_commit("origin/master") != self.repo.get_commit( "master"): message = "Master and origin/master doesn't point to the same commit, please update your master." logger.debug(message) if IDA_RUNNING is True: try: os.mkdir("cache/") except OSError: pass idbname = os.path.basename(idc.GetIdbPath()) idbname_prefix = os.path.splitext(idbname)[0] idbname_extension = os.path.splitext(idbname)[1] if not idbname_prefix.endswith('_local'): local_idb_name = "%s_local%s" % (idbname_prefix, idbname_extension) if not os.path.exists(local_idb_name): copy_idb_to_local_file() if IDA_IS_INTERACTIVE: message = "To use YaCo you must name your IDB with _local suffix. " message += "YaCo will create one for you.\nRestart IDA and open %s." % local_idb_name logger.debug(message) idaapi.cvar.database_flags |= idaapi.DBFL_KILL idc.Warning(message) idc.Exit(0)
def init(self): """ Ensure plugin's line modification function is called whenever needed. If Hex-Rays is not installed, or is not initialized yet, then plugin will not load. To ensure that the plugin loads after Hex-Rays, please name your plugin's .py file with a name that starts lexicographically after "hexx86f" """ try: if idaapi.init_hexrays_plugin(): def hexrays_event_callback(event, *args): if event == idaapi.hxe_refresh_pseudocode: # We use this event instead of hxe_text_ready because # MacOSX doesn't seem to work well with it # TODO: Look into this vu, = args self.visit_func(vu.cfunc) return 0 idaapi.install_hexrays_callback(hexrays_event_callback) else: return idaapi.PLUGIN_SKIP except AttributeError: idc.Warning('''init_hexrays_plugin() not found. Skipping Hex-Rays plugin.''') return idaapi.PLUGIN_KEEP
def wrapper(): try: optimice() except: print "-------------" traceback.print_exc() print "-------------" idc.Warning("---Please send the error message from the output window to: [email protected]")
def OnCommand(self, n, cmd_id): if cmd_id == self.cmd_a: if self.items[n][2] in self.comm_flist: idc.Warning("Common Funcs: %d" % len(self.comm_flist)) elif self.items[n][2] in self.first_flist: idc.Warning( "First profile (blue) Funcs: %d\n\nProfile file: %s" % (len(self.first_flist), os.path.basename(self.first_prof_name))) elif self.items[n][2] in self.second_flist: idc.Warning( "Second Profile (orange) Funcs: %d\n\nProfile file: %s" % (len(self.second_flist), os.path.basename(self.second_prof_name))) else: print "Unknown command:", cmd_id return 1
def OneProfMakeFuncs(self): fname = idc.AskFile(0, '*.*', 'Select profile file, plz') prof = open(fname, 'rb') binprofile = prof.read().split('\n\n') binprof = self.kern.analyze_callgr_profile(binprofile) idaapi.msg("Tryind add funcs...\n") num = self.kern.make_funcs_from_prof(binprof) idc.Warning("%d funcs was added" % num) return True
def showSimicsMessage(self): command = '@cgc.idaMessage()' simics_string = gdbProt.Evalx('SendGDBMonitor("%s");' % command) print simics_string if type(simics_string) is str: if 'Simics got lost' in simics_string: idc.Warning(simics_string) elif 'Just debug' in simics_string: self.just_debug = True return simics_string
def get_selected_funcs(): tform = idaapi.find_tform("Functions window") if not tform: idc.Warning("Unable to find 'Functions window'") return widget = idaapi.PluginForm.FormToPySideWidget(tform) table = widget.findChild(QtWidgets.QTableView) selected_funcs = [str(s.data()) for s in table.selectionModel().selectedRows()] return match_funcs(selected_funcs)
def checkInteractiveMode(self): """ Interactive Mode - This is disabled for this version """ if self.idaTracer.taintStart is None or self.idaTracer.taintStop is None: idc.Warning( "Please set the starting and stopping points before using Interactive Mode" ) return False else: return True
def __init__(self): ## dict of addresses and enum ids for faster lookup addr = idc.AskAddr(0, "Enter the original base address of the file") if addr == idaapi.BADADDR: idc.Warning("Invalid Address please enter the correct base address") idc.Exit idc.rebase_program(addr, idaapi.MSF_FIXONCE) self.enums = {} self.start_addr = None self.symbols = {}
def TwoProfColor(self): self.is_singleprofile = False self.is_twoprofile = True if not self.is_reanalyse: self.ProgectWarning() self.fname = idc.AskFile(0, '*.*', 'Select first profile file, plz') self.sname = idc.AskFile(0, '*.*', 'Select second profile file, plz') if (self.fname == None) or (self.sname == None): return False first = open(self.fname, 'rb') second = open(self.sname, 'rb') firstprofile = first.read().split('\n\n') secondprofile = second.read().split('\n\n') idaapi.msg("Analysing profiles...\n") firstprof = self.kern.analyze_callgr_profile(firstprofile) secondprof = self.kern.analyze_callgr_profile(secondprofile) if not self.is_reanalyse: YN = idc.AskYN( 0, 'Do you want to make additional funcs, based on callgrind logs?\n(If func not already exist)' ) if YN == 1: idaapi.msg("Tryind add funcs...\n") num = self.kern.make_funcs_from_profiles(firstprof, secondprof) idc.Warning("%d funcs was added" % num) actfuncs_dict = self.kern.color_profs(firstprof, secondprof, BLUE, ORG, GREEN) self.ColorFuncsView = FuncsColorChooser("Colored Funcs", actfuncs_dict, self.fname, self.sname) # self.ColorFuncsView.show() idaapi.msg("Done, enjoy work!\n") idaapi.msg( "\nHelp:\n - Click Functions window and Type Alt+1 to see actually executed funcs from profiles\n" ) self.is_reanalyse = False return True
def main(): message = "First of all you need to specify folder with test cases." idc.Warning(message) fname = idc.AskFile( 0, "*.*", "Please specify first trace file in test cases folder \ to start prioritization") if fname == None: print "You need to specify any file in test cases folder to start prioritization" return 0 fname = os.path.dirname(fname) if fname == None: return 0 print "Starting prioritization of " + fname start_prior(fname) print "Done"
def getEIPWhenStopped(delay=0, kernel_ok=False): done = False retval = None count = 0 if delay == 0: delay = 0.5 while not done: count += 1 if count == 50: print("waiting for response from monitor...") idc.Warning("may take a while") time.sleep(delay) simicsString = Evalx('SendGDBMonitor("@cgc.getEIPWhenStopped(%s)");' % kernel_ok) #print 'ready set' #print 'getEIPWhenStopped got %s of type %s' % (simicsString, type(simicsString)) if simicsString is not None and type( simicsString ) is str and simicsString != '0' and MAILBOX in simicsString: mail = stripMailbox(simicsString) #print 'mail is %s' % mail if mail == 'exited': retval = 0 print('Process exited') done = True elif not mail.startswith('ip:'): done = True try: retval = int(mail[2:], 16) except: print 'could not get int 16 from %s' % mail[2:] #print 'getEIPWhenStopped found ip of %x, now empty mailbox' % retval Evalx('SendGDBMonitor("@cgc.emptyMailbox()");') else: if type(simicsString) is str and not simicsString.strip().startswith('not stopped') \ and not simicsString.strip().startswith('End of playback'): # hack until python logging not sent to stdout on rev module simicsString = simicsString.strip() if not (simicsString.startswith('[')) and not simicsString.startswith('SystemPerf') \ and not simicsString.startswith('Using virtual time'): print('monitor stopped at wrong place: <%s>' % simicsString) done = True #print('getEIPWhenStopped returning %x' % retval) if count > 50: print("Got response from monitor.") msg = Evalx('SendGDBMonitor("@cgc.emptyMailbox()");') return retval
def retrieve_reset(self, *args): if not idaapi.askyn_c( False, "All your local changes will be lost !\nDo you really want to proceed ?" ): return # disable all yaco hooks self.YaCoUI.unhook() self.repo_manager.discard_and_pull_idb() # current idb should not be overwritten, so we have to close IDA brutally ! idaapi.set_database_flag(idaapi.DBFL_KILL) idc.Warning("Force pull complete, you can restart IDA") idc.Exit(0)
def create_reset(self, *args): title = "YaCo Force Push" text = "You are going to force push your IDB. Other YaCo users will need to stop working & force pull.\n" "Do you really want to force push ?" val = idaapi.askbuttons_c( "Yes", "No", "", idaapi.ASKBTN_NO, "TITLE %s\nICON QUESTION\nAUTOHIDE SESSION\n" "HIDECANCEL\n%s" % (title, text)) if val != idaapi.ASKBTN_YES: return # disable all yaco hooks self.YaCoUI.unhook() # create a backup of current idb yatools.copy_idb_to_local_file( "_bkp_%s" % time.ctime().replace(" ", "_").replace(":", "_")) # restore original idb original_file = yatools.copy_idb_to_original_file() # get xml files xml_files = [] for root, dirs, files in os.walk('cache/'): for file in files: xml_files.append("%s/%s" % (root, file)) # add idb self.repo_manager.repo.add_file(original_file) # remove xml cache self.repo_manager.repo.remove_files(xml_files) for xml_file in xml_files: os.remove(xml_file) # create commit self.repo_manager.repo.commit("YaCo force push") # push commit self.repo_manager.push_origin_master() idc.Warning( "Force push complete, you can restart IDA and other YaCo users can \"Force pull\"" ) idc.Exit(0)
def recursive_prefix(addr): """ Recursively prefix a function tree with a user defined string. """ func_addr = idc.LocByName(idaapi.get_func_name(addr)) if func_addr == idaapi.BADADDR: idaapi.msg("Prefix: 0x%08X does not belong to a defined function\n" % addr) return # prompt the user for a prefix to apply to the selected functions tag = idc.AskStr(PREFIX_DEFAULT, "Function Tag") # the user closed the window... ignore if tag == None: return # the user put a blank string and hit 'okay'... notify & ignore elif tag == '': idc.Warning("[ERROR] Tag cannot be empty [ERROR]") return # recursively collect all the functions called by this function nodes_xref_down = graph_down(func_addr, path=set([])) # graph_down returns the int address needs to be converted tmp = [] tmp1 = '' for func in nodes_xref_down: tmp1 = idaapi.get_func_name(func) if tmp1: tmp.append(tmp1) nodes_xref_down = tmp # prefix the tree of functions for rename in nodes_xref_down: func_addr = idc.LocByName(rename) if tag not in rename: idc.MakeNameEx(func_addr, '%s%s%s' % (str(tag), PREFIX_SEPARATOR, rename), idaapi.SN_NOWARN) # refresh the IDA views refresh_views()
def attach(self,processConfig): from dispatcher.core.structures.Tracer import InteractivemodeCallbacks as InteractivemodeCallbacks EThook = self.setDebuggerOptions(processConfig,True) self.interactivemodeCallback.SetDebuggerInstance(EThook) self.interactivemodeCallback.SetLoggerInstance(self.logger) process_name = processConfig.getApplication() PID = self.getRunningProcesses(process_name) self.logger.info("Attaching to %s to generate a trace..please wait..." % process_name) if PID == -1: idc.Warning("%s is not running. Please start the process first." % process_name) else: ret = idc.AttachProcess(PID, -1)
def REanalyseColors(self): self.is_reanalyse = True if self.is_singleprofile: self.ClearColors() self.OneProfColor() self.is_reanalyse = False return True elif self.is_twoprofile: self.ClearColors() self.TwoProfColor() self.is_reanalyse = False return True elif (not self.is_singleprofile) and (not self.is_twoprofile): idc.Warning("Don't fool me!\nChoose profile file first.") self.is_reanalyse = False return False self.is_reanalyse = False return False
def basic_block_coverage(json_path): bb_coverage = {} with open(json_path, 'r') as f: bb_coverage = json.load(f) for covered_basic_block in bb_coverage['coverage']: start_addr = covered_basic_block['start_addr'] func = idaapi.get_func(start_addr) if not func: idc.Warning('Could not find function associated with address ' '0x%x' % start_addr) return for block in idaapi.FlowChart(func): if block.startEA <= start_addr and block.endEA > start_addr: _color_block(block) print_stats(bb_coverage)
def get_selected_funcs(): """ Return the list of function names selected in the Functions window. """ # locate the functions window for scraping tform = idaapi.find_tform("Functions window") if not tform: idc.Warning("Unable to find 'Functions window'") return # # extract the PySide / PyQt widget from the located IDA TForm so we can # tap into its Qt elements more easily and scrape relevant data from them # if using_pyqt5(): widget = idaapi.PluginForm.FormToPyQtWidget(tform) else: widget = idaapi.PluginForm.FormToPySideWidget(tform) # # locate the table widget within the Functions window that actually holds # all the visible function metadata # table = widget.findChild(QtWidgets.QTableView) # # scrape the selected function names from the Functions window table # selected_funcs = [ str(s.data()) for s in table.selectionModel().selectedRows() ] # # re-map the scraped names as they appear in the function table, to their true # names as they are saved in the IDB. See the match_funcs(...) function # comment for more details # return match_funcs(selected_funcs)
def should_filter(self, context): if not self.script_compile: return False try: exec(self.script_compile, context) except Exception as ex: errors = context.get('Errors', 'stop') if errors == 'stop': self.script_compile = None idc.Warning( "Filter function encountered a runtime error: {}.\n" "Disabling filters.".format(ex)) elif errors == 'filter': pass elif errors == 'hide': return True elif 'errors' == 'show': return False return 'Filter' in context and context['Filter']
def run(self, *args, **kwargs): try: print("YaCo: waiting for auto analysis to finish\n") idc.Wait() print("YaCo: saving base in current state\n") idc.SaveBase("") import_yaco_paths() import YaCo if not YaCo.start(): idc.Warning("YaCo: already started") except Exception, e: print("YaCo: error during run") print(traceback.format_exc()) logger = logging.getLogger("YaCo") if logger is not None: try: logger.error("YaCo: error during run") logger.error(traceback.format_exc()) except: pass raise e
def create_reset(self, *args): title = "YaCo Force Push" text = "You are going to force push your IDB. Other YaCo users will need to stop working & force pull.\n" "Do you really want to force push ?" val = idaapi.askbuttons_c( "Yes", "No", "", idaapi.ASKBTN_NO, "TITLE %s\nICON QUESTION\nAUTOHIDE SESSION\n" "HIDECANCEL\n%s" % (title, text)) if val != idaapi.ASKBTN_YES: return # disable all yaco hooks self.YaCoUI.unhook() self.repo_manager.sync_and_push_original_idb() idc.Warning( "Force push complete, you can restart IDA and other YaCo users can \"Force pull\"" ) idc.Exit(0)
def OneProfColor(self): self.is_singleprofile = True self.is_twoprofile = False if not self.is_reanalyse: self.singlname = idc.AskFile(0, '*.*', 'Select profile file, plz') if self.singlname == None: return False prof = open(self.singlname, 'rb') binprofile = prof.read().split('\n\n') idaapi.msg("Analysing profile...\n") binprof = self.kern.analyze_callgr_profile(binprofile) actfuncs = self.kern.color_single_profile(binprof, GREEN) if not self.is_reanalyse: YN = idc.AskYN( 0, 'Do you want to make additional funcs, based on callgrind logs?\n(If func not already exist)' ) if YN == 1: idaapi.msg("Tryind add funcs...\n") num = self.kern.make_funcs_from_prof(binprof) idc.Warning("%d funcs was added" % num) self.ColorFuncsView = FuncsUniqueProfile("Actually funcs", actfuncs, GREEN) # self.ColorFuncsView.show() idaapi.msg("Done, enjoy work!") idaapi.msg( "\nHelp:\n - Click Functions window and Type Alt+1 to see actually executed funcs from profile\n" ) self.is_reanalyse = False return True