def run(self, arg): start, end = sark.get_selection() struct_name = idc.AskStr(self._prev_struct_name, "Struct Name") if not struct_name: return self._prev_struct_name = struct_name common_reg = sark.structure.get_common_register(start, end) reg_name = idc.AskStr(common_reg, "Register") if not reg_name: return offsets, operands = sark.structure.infer_struct_offsets( start, end, reg_name) try: sark.structure.create_struct_from_offsets(struct_name, offsets) except sark.exceptions.SarkStructAlreadyExists: yes_no_cancel = idc.AskYN( idaapi.ASKBTN_NO, "Struct already exists. Modify?\n" "Cancel to avoid applying the struct.") if yes_no_cancel == idaapi.ASKBTN_CANCEL: return elif yes_no_cancel == idaapi.ASKBTN_YES: sid = sark.structure.get_struct(struct_name) sark.structure.set_struct_offsets(offsets, sid) else: # yes_no_cancel == idaapi.ASKBTN_NO: pass sark.structure.apply_struct(start, end, reg_name, struct_name)
def change_config(self): try: self.get_current_from_ini_file() except: self.host = "<ip>:<port>" self.max_descriptions_returned = ">0" os.remove(self._path) cfgfile = open(self._path, 'w') parser = ConfigParser.SafeConfigParser() parser.add_section('REDB') host = idc.AskStr(self.host, "REDB: Please enter the server's ip and port:") if host is not None: parser.set('REDB', 'host', host) max_descriptions_returned = \ int(idc.AskStr(str(self.max_descriptions_returned), ("REDB: Please enter the maximum number " + \ "of descriptions that you want to be " + \ "returned from the server:"))) if max_descriptions_returned is not None: parser.set('REDB', 'max_descriptions_returned', str(max_descriptions_returned)) parser.write(cfgfile) cfgfile.close()
def kernelcache_find_virtual_method_overrides(classname=None, method=None): import idc import ida_kernelcache as kc kc.collect_class_info() if not classname: classname = idc.AskStr('IOUserClient', 'Enter class name') if classname not in kc.class_info: print 'Not a valid class: {}'.format(classname) return False if not method: method = idc.AskStr('externalMethod', 'Enter method name') print 'Subclasses of {} that override {}:'.format(classname, method) baseinfo = kc.class_info[classname] found = False for classinfo in baseinfo.descendants(): for _, override, _ in kc.vtable.class_vtable_overrides( classinfo, superinfo=baseinfo, methods=True): name = idc.NameEx(idc.BADADDR, override) demangled = idc.Demangle(name, idc.GetLongPrm(idc.INF_SHORT_DN)) name = demangled if demangled else name if method in name: print '{:#x} {}'.format(override, classinfo.classname) found = True if not found: print 'No subclass of {} overrides {}'.format(classname, method) return found
def OnKeydown(self, vkey, shift): """ User pressed a key @param vkey: Virtual key code @param shift: Shift flag @return: Boolean. True if you handled the event """ print "OnKeydown, vk=%d shift=%d" % (vkey, shift) # ESCAPE? if vkey == 27: self.Close() # VK_DELETE elif vkey == 46: n = self.GetLineNo() if n is not None: self.DelLine(n) self.Refresh() print "Deleted line %d" % n # Goto? elif vkey == ord('G'): n = self.GetLineNo() if n is not None: v = idc.AskLong(self.GetLineNo(), "Where to go?") if v: self.Jump(v, 0, 5) elif vkey == ord('R'): print "refreshing...." self.Refresh() elif vkey == ord('C'): print "refreshing current line..." self.RefreshCurrent() elif vkey == ord('A'): s = idc.AskStr("NewLine%d" % self.Count(), "Append new line") self.AddLine(s) self.Refresh() elif vkey == ord('X'): print "Clearing all lines" self.ClearLines() self.Refresh() elif vkey == ord('I'): n = self.GetLineNo() s = idc.AskStr("InsertedLine%d" % n, "Insert new line") self.InsertLine(n, s) self.Refresh() elif vkey == ord('E'): l = self.GetCurrentLine(notags=1) if not l: return False n = self.GetLineNo() print "curline=<%s>" % l l = l + idaapi.COLSTR("*", idaapi.SCOLOR_VOIDOP) self.EditLine(n, l) self.RefreshCurrent() print "Edited line %d" % n else: return False return True
def run(self, arg): start, end = sark.get_selection() if not sark.structure.selection_has_offsets(start, end): message('No structure offsets in selection. Operation cancelled.') idaapi.warning( 'No structure offsets in selection. Operation cancelled.') return struct_name = idc.AskStr(self._prev_struct_name, "Struct Name") if not struct_name: message("No structure name provided. Operation cancelled.") return self._prev_struct_name = struct_name common_reg = sark.structure.get_common_register(start, end) reg_name = idc.AskStr(common_reg, "Register") if not reg_name: message("No offsets found. Operation cancelled.") return try: offsets, operands = sark.structure.infer_struct_offsets( start, end, reg_name) except sark.exceptions.InvalidStructOffset: message( "Invalid offset found. Cannot create structure.", "Make sure there are no negative offsets in the selection.") return except sark.exceptions.SarkInvalidRegisterName: message( "Invalid register name {!r}. Cannot create structs.".format( reg_name)) return try: sark.structure.create_struct_from_offsets(struct_name, offsets) except sark.exceptions.SarkStructAlreadyExists: yes_no_cancel = idc.AskYN( idaapi.ASKBTN_NO, "Struct already exists. Modify?\n" "Cancel to avoid applying the struct.") if yes_no_cancel == idaapi.ASKBTN_CANCEL: return elif yes_no_cancel == idaapi.ASKBTN_YES: sid = sark.structure.get_struct(struct_name) sark.structure.set_struct_offsets(offsets, sid) else: # yes_no_cancel == idaapi.ASKBTN_NO: pass sark.structure.apply_struct(start, end, reg_name, struct_name)
def AskParams(self, macro='$!', expr='${idc.here()}$', desc='Current cursor location'): macro = idc.AskStr(macro, "Enter macro name") if macro is None: return None expr = idc.AskStr(expr, "Enter Python expression") if expr is None: return None desc = idc.AskStr(desc, "Enter macro description") if desc is None: return None return (macro, expr, desc)
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 rename(self, nuname=None, **kwargs): tp = self.currentType(**kwargs) cnm = tp['name'] if not nuname: nuname = idc.AskStr(cnm, "Set new type name for " + cnm + ":") if not nuname or nuname == cnm: Logger.debug("Rename cancelled") return sid = idc.GetStrucIdByName(nuname) if sid and sid != idc.BADADDR: raise self.WrongTypeError("Type already exists", nuname) Logger.debug("Renaming class %s to %s", str(tp), nuname) if tp.get('vtblea'): idc.MakeName(tp['vtblea'], 'vtbl_' + nuname) if tp.get('id'): idc.SetStrucName(tp['id'], nuname) if tp.get('vtblid'): tp['vtblnm'] = nuname + 'Vtbl' idc.SetStrucName(tp['vtblid'], tp['vtblnm']) for nm in idautils.Names(): if nm[1].startswith(cnm): fn = nm[1].replace(cnm, nuname) Logger.debug("Renaming function " + nm[1] + " to " + fn) idc.MakeName(nm[0], fn) self.typeid = nuname self.update()
def rename_regex(self, n, regex_str="", dryrun=False): count = 0 if not regex_str: regex_str = idc.AskStr("", "Regex rename rule") if regex_str: if dryrun: print "Testing regex rename rule: '%s'" % regex_str regex = re.compile(regex_str) # Look at all the profiled functions for (function, xrefs) in self.profile.functions.iteritems(): new_function_name = "" # Don't rename functions that have already been renamed if not idc.Name(function).startswith("sub_"): continue # Look through all the strings referenced by this function for string in [x.string for x in xrefs if x.type == str]: # Does the string match the given regex? m = regex.search(string) if m: # Take the last group from the regex match potential_function_name = m.groups()[-1].split(" ")[0] # Replace common bad chars with underscores for c in ['-', '>']: potential_function_name = potential_function_name.replace( c, '_') # Make sure this is a valid name; should not include format strings if idaapi.isident( potential_function_name ) and '%' not in potential_function_name: # Use the longest of the matching strings if len(potential_function_name) > len( new_function_name): new_function_name = potential_function_name if new_function_name: # Append _n to the function name, if it already exists n = 1 orig_new_function_name = new_function_name while idc.LocByName(new_function_name) != idc.BADADDR: new_function_name = "%s_%d" % (orig_new_function_name, n) n += 1 if dryrun: print "%s => %s" % (idc.Name(function), new_function_name) count += 1 else: if idc.MakeName(function, new_function_name): count += 1 print "Renamed %d functions" % count
def main(): f = open(idc.AskFile(0, '*.json', 'Where is the first JSON report you want to load ?'), 'r') report = json.load(f) l1 = report['basic_blocks_info']['list'] f = open(idc.AskFile(0, '*.json', 'Where is the second JSON report you want to load ?'), 'r') report = json.load(f) l2 = report['basic_blocks_info']['list'] c = idc.AskStr('black', 'Which color do you want ?').lower() addresses_l1 = set(r['address'] for r in l1) addresses_l2 = set(r['address'] for r in l2) dic_l2 = dict((k['address'], k['nbins']) for k in l2) diff = addresses_l2 - addresses_l1 print '%d bbls in the first execution' % len(addresses_l1) print '%d bbls in the second execution' % len(addresses_l2) print 'Differences between the two executions: %d bbls' % len(diff) assert(len(addresses_l1) < len(addresses_l2)) funcs = defaultdict(list) for i in diff: try: color(i, dic_l2[i], c) funcs[get_func(i).startEA].append(i) except Exception, e: print 'fail %s' % str(e)
def OnFormChange(self, fid): if fid == -2: # click on ok print self._project_list[self.GetControlValue(self.iProject)] if self._project_list[self.GetControlValue(self.iProject)] == "Select public project": project_id = idc.AskStr("", "Project id:") try: headers = {"Authorization" : "Bearer {0}".format(shared.USER_TOKEN)} data = json.loads(requests.get("{0}/{1}".format(shared.BASE_URL, constants.GET_PROJECT_HEADER.format(project_id)), headers = headers).content) hash_of_program = data["body"]["hash"] warning("{0} {1}".format(ida_nalt.retrieve_input_file_sha256().lower(), hash_of_program)) if ida_nalt.retrieve_input_file_sha256().lower() != hash_of_program: warning("Wrong hash of program, exiting now") ida_pro.qexit(1) contributors = data["body"]["contributors"] shared.MASTER_PAUSE_HOOK = True for cont in contributors: if cont["id"] == shared.USERID: shared.MASTER_PAUSE_HOOK = False shared.PAUSE_HOOK = True break shared.PROJECT_ID = data["body"]["id"] except Exception as e: warning("Cant get project information: " + str(e)) return 0 else: headers = {"Authorization" : "Bearer {0}".format(shared.USER_TOKEN)} data = json.loads(requests.get("{0}/{1}".format(shared.BASE_URL, constants.GET_PROJECT_HEADER.format(self._project_list[self.GetControlValue(self.iProject)].split(" ")[0])), headers = headers).content) hash_of_program = data["body"]["hash"] if ida_nalt.retrieve_input_file_sha256().lower() != hash_of_program: warning("Wrong hash of program, exiting now") ida_pro.qexit(1) shared.PROJECT_ID = self._project_list[self.GetControlValue(self.iProject)].split(" ")[0] return 1 else: return 1
def AllocateCodeSegment(self): if self.segment_start != 0: self.FreeCodeSegment() while True: seg_start = idaapi.BADADDR while seg_start == idaapi.BADADDR: seg_start = idc.AskAddr( 0x1000, "Enter address to create new code segment") seg_size = 0 while seg_size == 0: seg_size = idc.AskAddr(0x10000, "Enter size of new code segment") if idc.SegCreate(seg_start, seg_start + seg_size, 0, 1, 0, 0) != 0: break self.segment_start = seg_start self.segment_size = seg_size while True: seg_name = '' while seg_name == '': seg_name = idc.AskStr("optimized", "Enter a new segment name") if idc.SegRename(self.segment_start, seg_name) != 0: break self.segment_name = seg_name self.free_ea = self.segment_start
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 autoenum(self): common_value = get_common_value() enum_name = idc.AskStr(self._last_enum, "Enum Name") if enum_name is None: return if not enum_name: enum_name = None self._last_enum = enum_name # Can't ask with negative numbers. if common_value >> ((8 * sark.core.get_native_size()) - 1): common_value = 0 const_value = idc.AskLong(common_value, "Const Value") if const_value is None: return modify = True try: enum = sark.add_enum(enum_name) except sark.exceptions.EnumAlreadyExists: enum = sark.Enum(enum_name) yes_no_cancel = idc.AskYN(idaapi.ASKBTN_NO, "Enum already exists. Modify?\n") if yes_no_cancel == idaapi.ASKBTN_CANCEL: return elif yes_no_cancel == idaapi.ASKBTN_YES: modify = True else: # yes_no_cancel == idaapi.ASKBTN_NO: modify = False member_name = const_name(enum, const_value) if modify: try: enum.members.add(member_name, const_value) except sark.exceptions.SarkErrorAddEnumMemeberFailed as ex: idaapi.msg("[AutoEnum] Adding enum member failed: {}.".format( ex.message)) else: for member in enum.members: if member.value == const_value: member_name = member.name break else: return # Apply the enum apply_enum_by_name(enum, member_name)
def jump_to(self): current = self.base_expr if self.base_expr is not None else "" b = idc.AskStr(current, "Sync with") if b and len(b) > 0: try: self.base_expr = b self.reload_info() except: idaapi.warning("Invalid expression") else: self.base_addr = None
def activate(self, ctx): highlighted = idaapi.get_highlighted_identifier() addr = getHex(highlighted) count = idc.AskStr(last_data_watch_count, 'number of bytes to watch?') if count is None: return print('watch %s bytes from 0x%x' % (count, addr)) simicsString = gdbProt.Evalx('SendGDBMonitor("@cgc.watchData(0x%x, 0x%s)");' % (addr, count)) eip = gdbProt.getEIPWhenStopped() self.isim.signalClient() self.isim.showSimicsMessage()
def main(): dllname = idc.AskStr('kernel32', "Enter module name") if not dllname: print("Cancelled") return imports, R = find_import_ref(dllname) for k, v in R.items(): print(imports[k][1]) for ea in v: print("\t%x" % ea)
def runToWrite(self): print('runToWrite') result = idc.AskStr('?', 'String') if result is None: return command = "@cgc.runToWrite('%s')" % result print('command is %s' % command) simicsString = gdbProt.Evalx('SendGDBMonitor("%s");' % command) eip = gdbProt.getEIPWhenStopped() print('runToWrite %s, ended at eip 0x%x' % (result, eip)) self.signalClient(norev=True) self.showSimicsMessage()
def query_configuration(): # Set the default values to None db_engine, db_host, db_name, db_user, db_password = (None, ) * 5 class ExportChoose(idaapi.Choose): def __init__(self, engines=[]): idaapi.Choose.__init__(self, engines, 'Select Database Type', 1) self.width = 30 def sizer(self): return len(self.list) - 1 engines = [ DB_ENGINE.MYSQL, DB_ENGINE.POSTGRESQL, DB_ENGINE.MYSQLDUMP, 'Export Method' ] dlg = ExportChoose(engines) chosen_one = dlg.choose() if chosen_one > 0: db_engine = engines[chosen_one - 1] if db_engine == DB_ENGINE.MYSQLDUMP: # If a SQL dump is going to be generated, no DB # parameters are needed # return db_engine, '', '', '', '' db_host = idc.AskStr('localhost', '[1/4] Enter database host:') if not db_host is None: db_name = idc.AskStr('db_name', '[2/4] Enter database(schema) name:') if not db_name is None: db_user = idc.AskStr('root', '[3/4] Enter database user:'******'', '[4/4] Enter password for user:') return db_engine, db_host, db_name, db_user, db_password
def activate(self, ctx): highlighted = idaversion.getHighlight() current = idaversion.getRegVarValue(highlighted) default = '%x' % current print('default %s' % default) #prompt = 'Value to write to %s (in hex, no prefix)' % highlighted #print('prompt is %s' % prompt) #enc = prompt.encode('utf-8') value = idc.AskStr(default, 'reg value ?') if value is None: return reg_param = "'%s'" % highlighted simicsString = gdbProt.Evalx('SendGDBMonitor("@cgc.writeRegValue(%s, 0x%s)");' % (reg_param, value))
def runToBind(self): print('runToBind') result = idc.AskStr('?', 'Network address as ip:port (or regex)') if result is None: return #result = '192.168.31.52:20480' command = "@cgc.runToBind('%s')" % result print('command is %s' % command) simicsString = gdbProt.Evalx('SendGDBMonitor("%s");' % command) eip = gdbProt.getEIPWhenStopped() print('runToBind %s, ended at eip 0x%x' % (result, eip)) self.signalClient(norev=True) self.showSimicsMessage()
def main(): f = open( idc.AskFile(0, '*.json', 'Where is the JSON report you want to load ?'), 'r') c = idc.AskStr('black', 'Which color do you want ?').lower() report = json.load(f) for i in report['basic_blocks_info']['list']: print '%x' % i['address'], try: color(i['address'], i['nbins'], c) print 'ok' except Exception, e: print 'fail: %s' % str(e)
def subclass(self, sup=None, **kwargs): tp = self.currentType(self.CHECK_VTBL, **kwargs) tp = self.checkVtblStruct(tp) cnm = tp['name'] if not sup: sup = idc.AskStr('', "Subclass " + cnm + " from:") if not sup or sup == cnm: Logger.debug("Subclasssing cancelled") return idc.Til2Idb(-1, sup + 'Vtbl') s = MODS.struct.Struct(sup + 'Vtbl') Logger.debug("Subclassing class %s from %s", str(tp), sup) ea = tp['vtblea'] nm = None funcs = [] while (not nm): ofs = idc.Qword(ea) if not ofs or ofs == idc.BADADDR: break try: func = FuncDescr.fromEA(ofs) except FuncDescr.NotFunctionError as e: func = None if not kwargs.get('force'): raise funcs += [func] ea += 8 nm = idc.Name(ea) flds = s.fields() if len(funcs) != len(flds) and (not kwargs.get('force')): raise self.WrongTypeError("Functions count doesn't match", s.name) for i, fofs in enumerate(sorted(flds.keys())): fld = flds[fofs] f = funcs[i] if f is None: continue refcnt = len(MODS.util.refsFromSeg(f.ea, ".rdata")) if self.untouchedFunc(f.name): nm = cnm if refcnt == 1 else sup was = str(f) f.clearType() f.parseType(fld['type'][0]) f.name = nm + "::" + fld['name'] ni = 1 while idaapi.get_name_ea(idc.BADADDR, f.name) != idc.BADADDR: ni += 1 f.name = nm + "::" + fld['name'] + "_" + str(ni) f.changeParam(0, 'this', nm + '*') f.update(True) Logger.debug("Converted func %s to type %s", was, str(f)) self.update()
def ask(askType, defaultVal, prompt): if askType is int or askType is long: return idc.AskLong(defaultVal, prompt) elif askType is str: return idc.AskStr(defaultVal, prompt) elif askType is bool: result = idc.AskYN(defaultVal, prompt) return bool(result) if result != -1 else None elif askType is file: typeAssert(defaultVal, bool) fname = idc.AskFile(defaultVal, "", prompt) if not isString(fname): return None return open(fname, "w" if defaultVal else "r")
def find_binary(ossi, binary): binaries = list(ossi.executed_binaries(binary)) if len(binaries) == 0: print("Binary \"{}\" not executed in the trace.".format(binary)) exit(0) if len(binaries) == 1: return binaries[0] print("Multiple matches for \"{}\":".format(binary)) for (index, binary) in enumerate(binaries): print("{}: {}".format(index, binary.path)) answer = idc.AskStr("0", "Please choose one binary: ") return binaries[int(answer)]
def runToAccept(self): print('runToAccept') result = idc.AskStr(self.recent_fd, 'FD ?') if result is None: return self.recent_fd = result fd = int(result) command = "@cgc.runToAccept(%d)" % fd print('command is %s' % command) simicsString = gdbProt.Evalx('SendGDBMonitor("%s");' % command) time.sleep(1) eip = gdbProt.getEIPWhenStopped() print('runToAccept %s, ended at eip 0x%x' % (result, eip)) self.signalClient(norev=True) self.showSimicsMessage()
def askSetBookmark(self): #print('askSetBookmark') addr = idc.GetRegValue(self.isim.PC) instruct = idc.GetDisasm(addr) if ';' in instruct: instruct, dumb = instruct.rsplit(';', 1) #print('instruct is %s' % instruct) instruct = instruct.strip() #print('eip %x instruct: %s' % (addr, instruct)) default = '0x%x: %s' % (addr, instruct) mark = idc.AskStr(default, 'Name of new bookmark:') if mark != 0 and mark != 'None': self.setBookmark(mark) self.updateBookmarkView()
def main(): f = open( idc.AskFile(0, '*.json', 'Where is the JSON report you want to load ?'), 'r') c = idc.AskStr('black', 'Which color do you want ?').lower() report = json.load(f) for i in report['basic_blocks_info']['list']: if i['module_id'] == 0: # print '%x' % i['start_addr'], try: # start_addr + 0x01000000 color(i['start_addr'] + 16777216, i['num_instrs'], c) # print 'ok' except Exception, e: print 'fail: %s' % str(e)
def rename_regex(self, n, regex_str="", dryrun=False): count = 0 if not regex_str: regex_str = idc.AskStr("", "Regex rename rule") if regex_str: if dryrun: print "Testing regex rename rule: '%s'" % regex_str regex = re.compile(regex_str) for (function, xrefs) in self.profile.functions.iteritems(): new_function_name = "" if not idc.Name(function).startswith("sub_"): continue for string in [x.string for x in xrefs if x.type == str]: m = regex.search(string) if m: potential_function_name = m.groups()[-1].split(" ")[0] for c in ['-', '>']: potential_function_name = \ potential_function_name.replace(c, '_') if idaapi.isident(potential_function_name) and \ '%' not in potential_function_name: if len(potential_function_name) > len(new_function_name): new_function_name = potential_function_name if new_function_name: # Append _n to the function name, if it already exists n = 1 orig_new_function_name = new_function_name while idc.LocByName(new_function_name) != idc.BADADDR: new_function_name = "%s_%d" % (orig_new_function_name, n) n += 1 if dryrun: print "%s => %s" % (idc.Name(function), new_function_name) count += 1 else: if ida_shims.set_name(function, new_function_name): count += 1 print "Renamed %d functions" % count
def modify_value(self): reg = self.get_selected_reg() if not reg: return reg_val = idc.GetRegValue(reg) b = idc.AskStr("0x%X" % reg_val, "Modify register value") if b is not None: try: value = int(idaapi.str2ea(b)) idc.SetRegValue(value, reg) self.reload_info() if reg == dbg.registers.flags: self.reload_flags_view() except: idaapi.warning("Invalid expression")