def finish_populating_widget_popup(self, form, popup): form_type = idaapi.get_widget_type(form) if form_type == idaapi.BWN_DISASM or form_type == idaapi.BWN_DUMP: t0, t1, view = idaapi.twinpos_t(), idaapi.twinpos_t( ), idaapi.get_current_viewer() if idaapi.read_selection( view, t0, t1) or idc.get_item_size(idc.get_screen_ea()) > 1: idaapi.attach_action_to_popup(form, popup, ACTION_XORDATA, None) idaapi.attach_action_to_popup(form, popup, ACTION_FILLNOP, None) for action in ACTION_CONVERT: idaapi.attach_action_to_popup(form, popup, action, "Convert(Auto copy)/") if form_type == idaapi.BWN_DISASM and (ARCH, BITS) in [ (idaapi.PLFM_386, 32), (idaapi.PLFM_386, 64), (idaapi.PLFM_ARM, 32), ]: idaapi.attach_action_to_popup(form, popup, ACTION_SCANVUL, None)
def find_all_ioctls(): """ From the currently selected address attempts to traverse all blocks inside the current function to find all immediate values which are used for a comparison/sub immediately before a jz. Returns a list of address, second operand pairs. """ ioctls = [] # Find the currently selected function and get a list of all of it's basic blocks addr = idc.get_screen_ea() f = idaapi.get_func(addr) fc = ida_gdl.FlowChart(f, flags=ida_gdl.FC_PREDS) for block in fc: # grab the last two instructions in the block last_inst = idc.prev_head(block.end_ea) penultimate_inst = idc.prev_head(last_inst) # If the penultimate instruction is cmp or sub against an immediate value immediately preceding a 'jz' # then it's a decent guess that it's an IOCTL code (if this is a dispatch function) if idc.print_insn_mnem(penultimate_inst) in ['cmp', 'sub'] and idc.get_operand_type(penultimate_inst, 1) == 5: if idc.print_insn_mnem(last_inst) == 'jz': value = get_operand_value(penultimate_inst) ioctls.append((penultimate_inst, value)) ioctl_tracker.add_ioctl(penultimate_inst, value) return ioctls
def difSignatures(): path = idaapi.get_input_file_path() print('path is %s' % path) parts = path.split('/') index = 0 cndex = 0 sig_dir = '/tmp' if 'CBs' in parts: for p in parts: if p == 'CBs': cindex = index + 1 break else: index += 1 common = path.split('/')[5] + "_01" common = parts[cindex] + "_01" rcb_file = os.path.join(sig_dir, common) + ".json" else: rcb = os.path.basename(path) csid = rcb.split('-')[1] look_for = sig_dir + '/*%s*.json' % csid flist = glob.glob(look_for) if len(flist) == 0: print('no json found for %s' % look_for) exit(1) rcb_file = flist[0] print('found json of %s' % rcb_file) with open(rcb_file) as fh: print('got blocks from %s' % rcb_file) base_json = json.load(fh) ea = idc.get_screen_ea() #print('find match for 0x%x' % ea) #findMatch(base_json, idc.get_screen_ea()) print('try %x' % ea) difFun(base_json, ea) print('%d functions in base' % len(base_json))
def get_screen_ea(): return idc.get_screen_ea()
def __init__(self): default_types_info = r"""ExprId("RDX", 64): char *""" archs = ["AMD64_unk", "X86_32_unk", "msp430_unk"] func = ida_funcs.get_func(idc.get_screen_ea()) func_addr = func.start_ea start_addr = idc.read_selection_start() if start_addr == idc.BADADDR: start_addr = idc.get_screen_ea() end_addr = idc.read_selection_end() ida_kernwin.Form.__init__( self, r"""BUTTON YES* Launch BUTTON CANCEL NONE Type Propagation Settings {FormChangeCb} Analysis scope: <Whole function:{rFunction}> <From an address to the end of function:{rAddr}> <Between two addresses:{r2Addr}>{cScope}> <Target function:{functionAddr}> <Start address :{startAddr}> <End address :{endAddr}> <Architecture/compilator :{arch}> <##Header file :{headerFile}> <Use a file for type information:{rTypeFile}>{cTypeFile}> <##Types information :{typeFile}> <Types information :{strTypesInfo}> <Unalias stack:{rUnaliasStack}>{cUnalias}> """, { 'FormChangeCb': ida_kernwin.Form.FormChangeCb(self.OnFormChange), 'cScope': ida_kernwin.Form.RadGroupControl( ("rFunction", "rAddr", "r2Addr")), 'functionAddr': ida_kernwin.Form.NumericInput(tp=ida_kernwin.Form.FT_RAWHEX, value=func_addr), 'startAddr': ida_kernwin.Form.NumericInput(tp=ida_kernwin.Form.FT_RAWHEX, value=start_addr), 'endAddr': ida_kernwin.Form.NumericInput(tp=ida_kernwin.Form.FT_RAWHEX, value=end_addr), 'arch': ida_kernwin.Form.DropdownListControl( items=archs, readonly=False, selval=archs[0]), 'headerFile': ida_kernwin.Form.FileInput(swidth=20, open=True), 'cTypeFile': ida_kernwin.Form.ChkGroupControl(("rTypeFile", )), 'typeFile': ida_kernwin.Form.FileInput(swidth=20, open=True), 'strTypesInfo': ida_kernwin.Form.MultiLineTextControl( text=default_types_info, flags=ida_kernwin.Form.MultiLineTextControl.TXTF_FIXEDFONT ), 'cUnalias': ida_kernwin.Form.ChkGroupControl(("rUnaliasStack", )), }) form, args = self.Compile() form.rUnaliasStack.checked = True form.rTypeFile.checked = True
def make_ptr(ea): # TODO: arch ida_bytes.del_items(ea, 0, psize) return ida_bytes.create_dword(ea, psize) def enum_ptrs(start, end): for ea in range(start, end, psize): yield (ea, get_ptr(ea)) def enum_segment_ptrs(ea): seg = ida_segment.getseg(ea) for (ea, ptr) in enum_ptrs(seg.start_ea, seg.end_ea): yield (ea, ptr) for ea, ptr in enum_segment_ptrs(idc.get_screen_ea()): name = ida_name.get_name(ptr) if not name: continue if name.startswith('loc_'): continue print(hex(ea) + ': ' + name) make_ptr(ea) ida_name.set_name(ea, name)
def update(self, force=False): inst = self.cleanInstruction(print_insn_mnem(get_screen_ea())) if inst != self.last_inst or force == True: self.load_inst(inst)
def req_cursor(self, hash): print('[*] request IDA Pro cursor position') addr = idc.get_screen_ea() self.notice_broker('cmd', "\"cmd\":\"%s\"" % addr) return
rcb_file = os.path.join(sig_dir, common) + ".json" else: rcb = os.path.basename(path) csid = rcb.split('-')[1] look_for = sig_dir + '/*%s*.json' % csid flist = glob.glob(look_for) if len(flist) == 0: print('no json found for %s' % look_for) exit(1) rcb_file = flist[0] print('found json of %s' % rcb_file) with open(rcb_file) as fh: print('got blocks from %s' % rcb_file) base_json = json.load(fh) ea = idc.get_screen_ea() #print('find match for 0x%x' % ea) #findMatch(base_json, idc.get_screen_ea()) print('try %x' % ea) difFun(base_json, ea) print('%d functions in base' % len(base_json)) if __name__ == '__main__': ea = idc.get_screen_ea() sig_dir = '/tmp' fname = idaapi.get_root_filename() print('file is %s' % fname) difSignatures()
def activate(self, ctx): if self.menu_title == MenuAskEntryId: self.outer_self.mixto.entry_id = idaapi.ask_str( "", 1000, "Mixto Entry Id") else: if self.outer_self.mixto.entry_id is None: self.outer_self.mixto.entry_id = idaapi.ask_str( "", 1000, "Mixto Entry Id") if self.menu_title == MenuAllFunc: all_func = "" # Get count of all functions in the binary count = idaapi.get_func_qty() for i in range(count): fn = idaapi.getn_func(i) # Function should not have dummy name such as sub_* # and should not start with underscore (possible library functions) if not idaapi.has_dummy_name(get_flags_at( start_ea_of(fn))) and not idaapi.get_func_name( start_ea_of(fn)).startswith("_"): all_func += "{} @ 0x{:x}\n".format( idaapi.get_func_name(start_ea_of(fn)), start_ea_of(fn)) self.outer_self.mixto.AddCommit(all_func, self.outer_self.mixto.entry_id, "(IDA) All Functions") elif self.menu_title == MenuImports: global AllImports AllImports = "" # Get count of all import modules in the binary count = idaapi.get_import_module_qty() for i in range(count): module_name = idaapi.get_import_module_name(i) AllImports += "{}:\n".format(module_name) idaapi.enum_import_names(i, imports_cb) self.outer_self.mixto.AddCommit(AllImports, self.outer_self.mixto.entry_id, "(IDA) All Imports") elif self.menu_title == MenuDecFunc: addr_current = idc.get_screen_ea() addr_func = idaapi.get_func(addr_current) if not addr_func: idaapi.msg("Place cursor inside a function!") return False else: err = None out = str(idaapi.decompile(addr_func)) # print(out) self.outer_self.mixto.AddCommit( str(out), self.outer_self.mixto.entry_id, "(IDA) Function Decompilation {}".format( idc.GetFunctionName(addr_func.startEA)), ) elif self.menu_title == MenuExports: all_exports = "" for entry in idautils.Entries(): _, ord, ea, name = entry if not name: all_exports += "0x{:x}: ord#{}\n".format(ea, ord) else: all_exports += "0x{:x}: {} ord#{}\n".format( ea, name, ord) self.outer_self.mixto.AddCommit(all_exports, self.outer_self.mixto.entry_id, "(IDA) All Exports") elif self.menu_title == MenuAllComments: addr_current = idc.get_screen_ea() addr_func = idaapi.get_func(addr_current) uniq_comments = {} comments = [] for ea in range(addr_func.startEA, addr_func.endEA): comment = idaapi.get_cmt(ea, 0) if comment is not None: # hacky way to make sure only uniq comments are added if uniq_comments.get(comment) == 1: pass else: print(uniq_comments) comments.append("{offset} {value}".format( offset=hex(ea), value=comment)) print("here") uniq_comments[comment] = 1 if len(comments) > 0: out = "\n".join(comments) self.outer_self.mixto.AddCommit( str(out), self.outer_self.mixto.entry_id, "(IDA) Function Comments {}".format( idc.GetFunctionName(addr_func.startEA)), ) else: raise TypeError("No comments found") return True
def finish_populating_widget_popup(self, form, popup): try: b = idaapi.get_widget_type(form) == idaapi.BWN_DISASM except: b = idaapi.get_tform_type(form) == idaapi.BWN_DISASM if b: # Add separator idaapi.attach_action_to_popup(form, popup, None, None) # Add actions try: currentAddress = idc.get_screen_ea() except: currentAddress = idc.ScreenEA() #if currentAddress in [node.node_id for node in self.cc.PatternGenerator.targetNodes]: if currentAddress in self.cc.PatternGenerator.coloredNodes: idaapi.attach_action_to_popup(form, popup, "grap:pg:match_default", None) idaapi.attach_action_to_popup(form, popup, "grap:pg:match_full", None) idaapi.update_action_label( "grap:pg:match_full", self.cc.PatternGenerator.preview_match( currentAddress, "[grap] Full match", "match_full")) idaapi.attach_action_to_popup(form, popup, "grap:pg:match_opcode_arg1", None) idaapi.update_action_label( "grap:pg:match_opcode_arg1", self.cc.PatternGenerator.preview_match( currentAddress, "[grap] Opcode+arg1", "match_opcode_arg1")) idaapi.attach_action_to_popup(form, popup, "grap:pg:match_opcode_arg2", None) idaapi.update_action_label( "grap:pg:match_opcode_arg2", self.cc.PatternGenerator.preview_match( currentAddress, "[grap] Opcode+arg2", "match_opcode_arg2")) idaapi.attach_action_to_popup(form, popup, "grap:pg:match_opcode", None) idaapi.update_action_label( "grap:pg:match_opcode", self.cc.PatternGenerator.preview_match( currentAddress, "[grap] Opcode", "match_opcode")) idaapi.attach_action_to_popup(form, popup, "grap:pg:match_wildcard", None) idaapi.attach_action_to_popup(form, popup, "grap:pg:remove_target", None) for type in [ "match_default", "match_full", "match_opcode_arg1", "match_opcode_arg2", "match_opcode", "match_wildcard" ]: idaapi.update_action_icon("grap:pg:" + type, -1) if currentAddress not in self.cc.PatternGenerator.targetNodeType: type = "match_default" else: type = self.cc.PatternGenerator.targetNodeType[ currentAddress] idaapi.update_action_icon("grap:pg:" + type, self.selected_icon_number) elif self.cc.PatternGenerator.rootNode is None or currentAddress != self.cc.PatternGenerator.rootNode.node_id: idaapi.attach_action_to_popup(form, popup, "grap:pg:set_root", None) idaapi.attach_action_to_popup(form, popup, "grap:pg:add_target", None)
def _current_function(self): return idaapi.get_func(idc.get_screen_ea()).start_ea
def activate(self, ctx): if self.menu_title == MenuAskEntryId: self.outer_self.mixto.entry_id = idaapi.ask_str( "", 1000, "Mixto Entry Id") else: if self.outer_self.mixto.entry_id is None: self.outer_self.mixto.entry_id = idaapi.ask_str( "", 1000, "Mixto Entry Id") if self.menu_title == MenuAllFunc: all_func = "" # Get count of all functions in the binary count = idaapi.get_func_qty() for i in range(count): fn = idaapi.getn_func(i) # Function should not have dummy name such as sub_* # and should not start with underscore (possible library functions) if not idaapi.has_dummy_name(get_flags_at( start_ea_of(fn))) and not idaapi.get_func_name( start_ea_of(fn)).startswith("_"): all_func += "{} @ 0x{:x}\n".format( idaapi.get_func_name(start_ea_of(fn)), start_ea_of(fn)) self.outer_self.mixto.AddCommit(all_func, self.outer_self.mixto.entry_id, "(IDA) All Functions") elif self.menu_title == MenuImports: global AllImports AllImports = "" # Get count of all import modules in the binary count = idaapi.get_import_module_qty() for i in range(count): module_name = idaapi.get_import_module_name(i) AllImports += "{}:\n".format(module_name) idaapi.enum_import_names(i, imports_cb) self.outer_self.mixto.AddCommit(AllImports, self.outer_self.mixto.entry_id, "(IDA) All Imports") elif self.menu_title == MenuDecFunc: addr_current = idc.get_screen_ea() addr_func = idaapi.get_func(addr_current) if not addr_func: idaapi.msg("Place cursor inside a function!") return False else: err = None out = ida_hexrays.decompile_func(addr_func, err) # print(out) self.outer_self.mixto.AddCommit( str(out), self.outer_self.mixto.entry_id, "(IDA) Function Decompilation", ) elif self.menu_title == MenuExports: all_exports = "" for entry in idautils.Entries(): _, ord, ea, name = entry if not name: all_exports += "0x{:x}: ord#{}\n".format(ea, ord) else: all_exports += "0x{:x}: {} ord#{}\n".format( ea, name, ord) self.outer_self.mixto.AddCommit(all_exports, self.outer_self.mixto.entry_id, "(IDA) All Exports") elif self.menu_title == MenuAllComments: raise NotImplementedError("Comments not yet implemented TODO") return True
def __init__(self, ira, ircfg, mn): self.ira = ira self.ircfg = ircfg self.mn = mn self.stk_args = {'ARG%d' % i:i for i in range(10)} self.stk_unalias_force = False self.address = idc.get_screen_ea() cur_block = None for loc_key in ircfg.getby_offset(self.address): block = ircfg.get_block(loc_key) offset = self.ircfg.loc_db.get_location_offset(block.loc_key) if offset is not None: # Only one block non-generated assert cur_block is None cur_block = block assert cur_block is not None line_nb = None for line_nb, assignblk in enumerate(cur_block): if assignblk.instr.offset == self.address: break assert line_nb is not None cur_loc_key = str(cur_block.loc_key) loc_keys = sorted(map(str, ircfg.blocks)) regs = sorted(ira.arch.regs.all_regs_ids_byname) regs += list(self.stk_args) reg_default = regs[0] for i in range(10): opnd = idc.print_operand(self.address, i).upper() if opnd in regs: reg_default = opnd break ida_kernwin.Form.__init__(self, r"""BUTTON YES* Launch BUTTON CANCEL NONE Dependency Graph Settings Track the element: <Before the line:{rBeforeLine}> <After the line:{rAfterLine}> <At the end of the basic block:{rEndBlock}>{cMode}> <Target basic block:{cbBBL}> <Register to track:{cbReg}> <Line number:{iLineNb}> INFO: To track stack argument number n, use "ARGn" Method to use: <Follow Memory:{rNoMem}> <Follow Call:{rNoCall}> <Implicit dependencies:{rImplicit}> <Unalias stack:{rUnaliasStack}>{cMethod}> <Highlight color:{cColor}> """, { 'cbReg': ida_kernwin.Form.DropdownListControl( items=regs, readonly=False, selval=reg_default), 'cMode': ida_kernwin.Form.RadGroupControl( ("rBeforeLine", "rAfterLine", "rEndBlock")), 'cMethod': ida_kernwin.Form.ChkGroupControl( ("rNoMem", "rNoCall", "rImplicit", "rUnaliasStack")), 'iLineNb': ida_kernwin.Form.NumericInput( tp=ida_kernwin.Form.FT_RAWHEX, value=line_nb), 'cbBBL': ida_kernwin.Form.DropdownListControl( items=loc_keys, readonly=False, selval=cur_loc_key), 'cColor': ida_kernwin.Form.ColorInput(value=0xc0c020), }) self.Compile()
def launch_depgraph(): global graphs, comments, sol_nb, settings, addr, ir_arch, ircfg # Get the current function addr = idc.get_screen_ea() func = ida_funcs.get_func(addr) # Init machine = guess_machine(addr=func.start_ea) mn, dis_engine, ira = machine.mn, machine.dis_engine, machine.ira bs = bin_stream_ida() mdis = dis_engine(bs, dont_dis_nulstart_bloc=True) ir_arch = ira(mdis.loc_db) # Populate symbols with ida names for ad, name in idautils.Names(): if name is None: continue mdis.loc_db.add_location(name, ad) asmcfg = mdis.dis_multiblock(func.start_ea) # Generate IR ircfg = ir_arch.new_ircfg_from_asmcfg(asmcfg) # Get settings settings = depGraphSettingsForm(ir_arch, ircfg, mn) settings.Execute() loc_key, elements, line_nb = settings.loc_key, settings.elements, settings.line_nb # Simplify assignments for irb in list(viewvalues(ircfg.blocks)): irs = [] offset = ir_arch.loc_db.get_location_offset(irb.loc_key) fix_stack = offset is not None and settings.unalias_stack for assignblk in irb: if fix_stack: stk_high = m2_expr.ExprInt(idc.get_spd(assignblk.instr.offset), ir_arch.sp.size) fix_dct = {ir_arch.sp: mn.regs.regs_init[ir_arch.sp] + stk_high} new_assignblk = {} for dst, src in viewitems(assignblk): if fix_stack: src = src.replace_expr(fix_dct) if dst != ir_arch.sp: dst = dst.replace_expr(fix_dct) dst, src = expr_simp(dst), expr_simp(src) new_assignblk[dst] = src irs.append(AssignBlock(new_assignblk, instr=assignblk.instr)) ircfg.blocks[irb.loc_key] = IRBlock(irb.loc_key, irs) # Get dependency graphs dg = settings.depgraph graphs = dg.get(loc_key, elements, line_nb, set([ir_arch.loc_db.get_offset_location(func.start_ea)])) # Display the result comments = {} sol_nb = 0 # Register and launch ida_kernwin.add_hotkey("Shift-N", next_element) treat_element()
def kernelcache_populate_struct(struct=None, address=None, register=None, delta=None): import idc import idautils import idaapi import ida_kernelcache as kc import ida_kernelcache.ida_utilities as idau # Define the form to ask for the arguments. class MyForm(idaapi.Form): def __init__(self): swidth = 40 idaapi.Form.__init__( self, r"""STARTITEM 0 Automatically populate struct fields <#The name of the structure#Structure:{structure}> <#The address of the instruction at which the register points to the structure#Address :{address}> <#The register containing the pointer to the structure#Register :{register}> <#The offset of the pointer from the start of the structure#Delta :{delta}>""", { 'structure': idaapi.Form.StringInput(tp=idaapi.Form.FT_IDENT, swidth=swidth), 'address': idaapi.Form.NumericInput( tp=idaapi.Form.FT_ADDR, swidth=swidth, width=1000), 'register': idaapi.Form.StringInput(tp=idaapi.Form.FT_IDENT, swidth=swidth), 'delta': idaapi.Form.NumericInput(tp=idaapi.Form.FT_INT64, swidth=swidth), }) def OnFormChange(self, fid): return 1 # If any argument is unspecified, get it using the form. if any(arg is None for arg in (struct, address, register, delta)): f = MyForm() f.Compile() f.structure.value = struct or '' f.address.value = address or idc.get_screen_ea() f.register.value = register or 'X0' f.delta.value = delta or 0 ok = f.Execute() if ok != 1: print 'Cancelled' return False struct = f.structure.value address = f.address.value register = f.register.value delta = f.delta.value f.Free() # Check whether this struct is a class. kc.collect_class_info() is_class = struct in kc.class_info # Open the structure. sid = idau.struct_open(struct, create=True) if sid is None: print 'Could not open struct {}'.format(struct) return False # Check that the address is in a function. if not idaapi.get_func(address): print 'Address {:#x} is not a function'.format(address) return False # Get the register id. register_id = None if type(register) is str: register_id = idaapi.str2reg(register) elif type(register) is int: register_id = register register = idaapi.get_reg_name(register_id, 8) if register_id is None or register_id < 0: print 'Invalid register {}'.format(register) return False # Validate delta. if delta < 0 or delta > 0x1000000: print 'Invalid delta {}'.format(delta) return False elif is_class and delta != 0: print 'Nonzero delta not yet supported' return False type_name = 'class' if is_class else 'struct' print '{} = {}, address = {:#x}, register = {}, delta = {:#x}'.format( type_name, struct, address, register, delta) if is_class: # Run the analysis. kc.class_struct.process_functions([(address, struct, register_id)]) else: # Run the data flow to collect the accesses and then add those fields to the struct. accesses = kc.data_flow.pointer_accesses( function=address, initialization={address: { register_id: delta }}) kc.build_struct.create_struct_fields(sid, accesses=accesses) # Set the offsets to stroff. for addresses_and_deltas in accesses.values(): for ea, delta in addresses_and_deltas: insn = idautils.DecodeInstruction(ea) if insn: for op in insn.Operands: if op.type == idaapi.o_displ: idau.insn_op_stroff(insn, op.n, sid, delta) # All done! :) print 'Done' return True
def activate(self, ctx): if self.action in ACTION_CONVERT: # convert t0, t1, view = idaapi.twinpos_t(), idaapi.twinpos_t( ), idaapi.get_current_viewer() if idaapi.read_selection(view, t0, t1): start, end = t0.place(view).toea(), t1.place(view).toea() size = end - start elif idc.get_item_size(idc.get_screen_ea()) > 1: start = idc.get_screen_ea() size = idc.get_item_size(start) end = start + size else: return False data = idc.get_bytes(start, size) if isinstance(data, str): # python2 compatibility data = bytearray(data) name = idc.get_name(start, idc.GN_VISIBLE) if not name: name = "data" if data: print("\n[+] Dump 0x%X - 0x%X (%u bytes) :" % (start, end, size)) if self.action == ACTION_CONVERT[0]: # escaped string print('"%s"' % "".join("\\x%02X" % b for b in data)) elif self.action == ACTION_CONVERT[1]: # hex string print("".join("%02X" % b for b in data)) elif self.action == ACTION_CONVERT[2]: # C array output = "unsigned char %s[%d] = {" % (name, size) for i in range(size): if i % 16 == 0: output += "\n " output += "0x%02X, " % data[i] output = output[:-2] + "\n};" print(output) elif self.action == ACTION_CONVERT[3]: # C array word data += b"\x00" array_size = (size + 1) // 2 output = "unsigned short %s[%d] = {" % (name, array_size) for i in range(0, size, 2): if i % 16 == 0: output += "\n " output += "0x%04X, " % u16(data[i:i + 2]) output = output[:-2] + "\n};" print(output) elif self.action == ACTION_CONVERT[4]: # C array dword data += b"\x00" * 3 array_size = (size + 3) // 4 output = "unsigned int %s[%d] = {" % (name, array_size) for i in range(0, size, 4): if i % 32 == 0: output += "\n " output += "0x%08X, " % u32(data[i:i + 4]) output = output[:-2] + "\n};" print(output) elif self.action == ACTION_CONVERT[5]: # C array qword data += b"\x00" * 7 array_size = (size + 7) // 8 output = "unsigned long %s[%d] = {" % (name, array_size) for i in range(0, size, 8): if i % 32 == 0: output += "\n " output += "%#018X, " % u64(data[i:i + 8]) output = output[:-2] + "\n};" print(output.replace("0X", "0x")) elif self.action == ACTION_CONVERT[6]: # python list print("[%s]" % ", ".join("0x%02X" % b for b in data)) elif self.action == ACTION_CONVERT[7]: # python list word data += b"\x00" print("[%s]" % ", ".join("0x%04X" % u16(data[i:i + 2]) for i in range(0, size, 2))) elif self.action == ACTION_CONVERT[8]: # python list dword data += b"\x00" * 3 print("[%s]" % ", ".join("0x%08X" % u32(data[i:i + 4]) for i in range(0, size, 4))) elif self.action == ACTION_CONVERT[9]: # python list qword data += b"\x00" * 7 print("[%s]" % ", ".join( "%#018X" % u64(data[i:i + 8]) for i in range(0, size, 8)).replace("0X", "0x")) elif self.action == ACTION_XORDATA: t0, t1, view = idaapi.twinpos_t(), idaapi.twinpos_t( ), idaapi.get_current_viewer() if idaapi.read_selection(view, t0, t1): start, end = t0.place(view).toea(), t1.place(view).toea() else: if idc.get_item_size(idc.get_screen_ea()) > 1: start = idc.get_screen_ea() end = start + idc.get_item_size(start) else: return False data = idc.get_bytes(start, end - start) if isinstance(data, str): # python2 compatibility data = bytearray(data) x = idaapi.ask_long(0, "Xor with...") if x: x &= 0xFF print("\n[+] Xor 0x%X - 0x%X (%u bytes) with 0x%02X:" % (start, end, end - start, x)) print(repr("".join(chr(b ^ x) for b in data))) elif self.action == ACTION_FILLNOP: t0, t1, view = idaapi.twinpos_t(), idaapi.twinpos_t( ), idaapi.get_current_viewer() if idaapi.read_selection(view, t0, t1): start, end = t0.place(view).toea(), t1.place(view).toea() idaapi.patch_bytes(start, b"\x90" * (end - start)) print("\n[+] Fill 0x%X - 0x%X (%u bytes) with NOPs" % (start, end, end - start)) elif self.action == ACTION_SCANVUL: print("\n[+] Finding Format String Vulnerability...") found = [] for addr in idautils.Functions(): name = idc.get_func_name(addr) if "printf" in name and "v" not in name and idc.get_segm_name( addr) in (".text", ".plt", ".idata"): xrefs = idautils.CodeRefsTo(addr, False) for xref in xrefs: vul = self.check_fmt_function(name, xref) if vul: found.append(vul) if found: print("[!] Done! %d possible vulnerabilities found." % len(found)) ch = VulnChoose("Vulnerability", found, None, False) ch.Show() else: print("[-] No format string vulnerabilities found.") else: return 0 return 1
def run(self, _=0): if idc.get_operand_type(idc.get_screen_ea(), 1) != 5: # Immediate return value = idc.get_operand_value(idc.get_screen_ea(), 1) & 0xffffffff winio_decode(value)
def makesig(): addr = idc.get_screen_ea() addr = idc.get_func_attr(addr, idc.FUNCATTR_START) funcstart = addr if addr == idc.BADADDR: print("Make sure you are in a function!") return name = idc.get_name(addr, ida_name.GN_VISIBLE) funcend = idc.get_func_attr(addr, idc.FUNCATTR_END) sig = "" found = 0 done = 0 addr = funcstart while addr != idc.BADADDR: info = ida_ua.insn_t() if not ida_ua.decode_insn(info, addr): return None done = 0 if info.Op1.type == ida_ua.o_near or info.Op1.type == ida_ua.o_far: if (idc.get_wide_byte(addr)) == 0x0F: # Two-byte instruction sig = sig + ("0F %02X " % idc.get_wide_byte(addr + 1)) + print_wildcards( get_dt_size(info.Op1.dtype)) else: sig = sig + ("%02X " % idc.get_wide_byte(addr)) + print_wildcards( get_dt_size(info.Op1.dtype)) done = 1 if not done: # Unknown, just wildcard addresses i = 0 size = idc.get_item_size(addr) while 1: # Screw u python loc = addr + i if ((idc.get_fixup_target_type(loc) & 0xF) == ida_fixup.FIXUP_OFF32): sig = sig + print_wildcards(4) i = i + 3 else: sig = sig + ("%02X " % idc.get_wide_byte(loc)) i = i + 1 if i >= size: break if (is_good_sig(sig)): found = 1 break addr = idc.next_head(addr, funcend) if found is 0: print(sig) print("Ran out of bytes to create unique signature.") return None l = len(sig) - 1 smsig = r"\x" for i in xrange(l): c = sig[i] if c == " ": smsig = smsig + r"\x" elif c == "?": smsig = smsig + "2A" else: smsig = smsig + c print("Signature for %s:\n%s\n%s\n" % (name, sig, smsig)) return smsig
def kernelcache_process_external_methods(ea=None, struct_type=None, count=None): import idc import ida_kernelcache as kc import ida_kernelcache.ida_utilities as idau kIOUCVariableStructureSize = 0xffffffff kIOUCTypeMask = 0xf kIOUCScalarIScalarO = 0 kIOUCScalarIStructO = 2 kIOUCStructIStructO = 3 kIOUCScalarIStructI = 4 kIOUCFlags = 0xff IOExternalMethod_types = (kIOUCScalarIScalarO, kIOUCScalarIStructO, kIOUCStructIStructO, kIOUCScalarIStructI) IOExternalMethod_count0_scalar = (kIOUCScalarIScalarO, kIOUCScalarIStructO, kIOUCScalarIStructI) IOExternalMethod_count1_scalar = (kIOUCScalarIScalarO,) def check_scalar(scalar_count): return (0 <= scalar_count <= 400) def check_structure(structure_size): return (0 <= structure_size <= 0x100000 or structure_size == kIOUCVariableStructureSize) def is_IOExternalMethodDispatch(obj): return (idau.is_mapped(obj.function) and check_scalar(obj.checkScalarInputCount) and check_structure(obj.checkStructureInputSize) and check_scalar(obj.checkScalarOutputCount) and check_structure(obj.checkStructureOutputSize)) def process_IOExternalMethodDispatch(obj): return (obj.checkScalarInputCount, obj.checkStructureInputSize, obj.checkScalarOutputCount, obj.checkStructureOutputSize) def is_IOExternalMethod(obj): method_type = obj.flags & kIOUCTypeMask check_count0 = check_scalar if method_type in IOExternalMethod_count0_scalar else check_structure check_count1 = check_scalar if method_type in IOExternalMethod_count1_scalar else check_structure return ((obj.object == 0 or idau.is_mapped(obj.object)) and (obj.flags & kIOUCFlags == obj.flags) and idau.is_mapped(obj.func) and method_type in IOExternalMethod_types and check_count0(obj.count0) and check_count1(obj.count1)) def process_IOExternalMethod(obj): isc, iss, osc, oss = 0, 0, 0, 0 method_type = obj.flags & kIOUCTypeMask if method_type == kIOUCScalarIScalarO: isc, osc = obj.count0, obj.count1 elif method_type == kIOUCScalarIStructO: isc, oss = obj.count0, obj.count1 elif method_type == kIOUCStructIStructO: iss, oss = obj.count0, obj.count1 elif method_type == kIOUCScalarIStructI: isc, iss = obj.count0, obj.count1 else: assert False return (isc, iss, osc, oss) TYPE_MAP = { 'IOExternalMethodDispatch': (is_IOExternalMethodDispatch, process_IOExternalMethodDispatch), 'IOExternalMethod': (is_IOExternalMethod, process_IOExternalMethod), } # Get the EA. if ea is None: ea = idc.get_screen_ea() # Get the struct_type and the check and process functions. if struct_type is None: for stype in TYPE_MAP: struct_type = stype check, process = TYPE_MAP[struct_type] obj = idau.read_struct(ea, struct=struct_type, asobject=True) if check(obj): break else: print 'Address {:#x} does not look like any known external method struct'.format(ea) return False else: if struct_type not in TYPE_MAP: print 'Unknown external method struct type {}'.format(struct_type) return False check, process = TYPE_MAP[struct_type] obj = idau.read_struct(ea, struct=struct_type, asobject=True) if not check(obj): print 'Address {:#x} does not look like {}'.format(ea, struct_type) # Process the external methods. selector = 0; while (count is None and check(obj)) or (selector < count): isc, iss, osc, oss = process(obj) print '{{ {:3}, {:5}, {:#10x}, {:5}, {:#10x} }}'.format(selector, isc, iss, osc, oss) selector += 1 ea += len(obj) obj = idau.read_struct(ea, struct=struct_type, asobject=True) return True
def get_screen_ea(): if idaapi.IDA_SDK_VERSION <= 699: cursor = idc.GetScreenEA() else: cursor = idc.get_screen_ea() return cursor
def get_rva() -> int: ea = idc.get_screen_ea() base = idaapi.get_imagebase() rva = ea - base return rva
def req_cursor(self, hash): rs_log('request IDA Pro cursor position') addr = self.rebase_remote(idc.get_screen_ea()) self.notice_broker('cmd', "\"cmd\":\"0x%x\"" % addr) return
def copy_rva(): ea = idc.get_screen_ea() base = ida_nalt.get_imagebase() rva = ea - base plg_print("EA = %X - RVA = %X copied to clipboard" % (ea, rva)) copy_to_clip("0x%X" % rva)
def cmd_get_cursor_pos(self): return self.fmt_addr(idc.get_screen_ea())
def init_ui(self): self.parent.setStyleSheet( "QTableView {background-color: transparent; selection-background-color: #87bdd8;}" "QHeaderView::section {background-color: transparent; border: 0.5px solid;}" "QPushButton {width: 50px; height: 20px;}" # "QPushButton::pressed {background-color: #ccccff}" ) self.parent.resize(400, 600) self.parent.setWindowTitle('ArgAnalyzer-' + str(self.id)) btn_Clone = QtWidgets.QPushButton("&Clone") btn_Clone.clicked.connect(self.clone) btn_watch = QtWidgets.QPushButton("&WatchPtr") btn_watch.clicked.connect(self.add_var_watch) btn_screenEA = QtWidgets.QPushButton("&ScreenEA") btn_screenEA.clicked.connect(lambda: self.printout.setText("0x%X" % idc.get_screen_ea())) btn_origin = QtWidgets.QPushButton("&Backup") btn_resolve = QtWidgets.QPushButton("Restore") text_out = QtWidgets.QLineEdit() self.printout = text_out btn_recognize = QtWidgets.QPushButton("Recognize Shape") btn_recognize.setStyleSheet("QPushButton {width: 100px; height: 20px;}") # btn_finalize.setShortcut("f") # struct_view = QtWidgets.QTableView() # struct_view.setModel(self.structure_model) # # struct_view.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection) # # struct_view.verticalHeader().setVisible(False) # struct_view.verticalHeader().setDefaultSectionSize(24) # struct_view.horizontalHeader().setStretchLastSection(True) # struct_view.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents) grid_box = QtWidgets.QGridLayout() grid_box.setSpacing(0) grid_box.addWidget(btn_Clone, 0, 0) grid_box.addWidget(btn_screenEA, 0, 1) grid_box.addWidget(btn_watch, 0, 2) grid_box.addWidget(btn_origin, 0, 3) grid_box.addWidget(btn_resolve, 0, 4) grid_box.addItem(QtWidgets.QSpacerItem(20, 20, QtWidgets.QSizePolicy.Expanding), 0, 5) grid_box.addWidget(text_out, 0, 6) grid_box.addWidget(btn_recognize, 0, 7) vertical_box = QtWidgets.QVBoxLayout() horizontal_box = QtWidgets.QHBoxLayout() argLayout = QtWidgets.QVBoxLayout() treeselectmode = QtWidgets.QAbstractItemView.ExtendedSelection argtree = QtWidgets.QTreeWidget() self.argtree = argtree # 设置列数 argtree.setColumnCount(2) # 设置树形控件头部的标题 argtree.setHeaderLabels(['argument', 'Value']) argLayout.addWidget(argtree) # 设置根节点 # funcname=idc.get_func_off_str(funcarg.addr) # root.setText(0, funcname) # root.setIcon(0, QtWidgets.QIcon('./images/root.png')) # 设置树形控件的列的宽度 argtree.setColumnWidth(0, 150) # TODO 优化3 给节点添加响应事件 argtree.clicked.connect(self.onClicked) argtree.doubleClicked.connect(self.onDClicked) argtree.setSelectionMode(treeselectmode) # 节点全部展开 # argtree.expandAll() fneditlayout = QtWidgets.QHBoxLayout() argLayout.addLayout(fneditlayout) lineedit = QtWidgets.QLineEdit() lineedit.setPlaceholderText("funcname") self.funcinput = lineedit fneditlayout.addWidget(lineedit) btnadd = QtWidgets.QPushButton("add") btnadd.clicked.connect(self.add_func) fneditlayout.addWidget(btnadd) spacer = QtWidgets.QSpacerItem(20, 20, QtWidgets.QSizePolicy.Expanding) fneditlayout.addSpacerItem(spacer) btndel = QtWidgets.QPushButton("&del") btndel.clicked.connect(self.del_func) fneditlayout.addWidget(btndel) updatewatch = QtWidgets.QPushButton("&update") updatewatch.clicked.connect(self.load_data) fneditlayout.addWidget(updatewatch) btnwatch = QtWidgets.QPushButton("&[un]watch") btnwatch.clicked.connect(self.add_func_watch) fneditlayout.addWidget(btnwatch) watchLayout = QtWidgets.QVBoxLayout() watchtree = QtWidgets.QTreeWidget() self.watchtree = watchtree # treeView.setGeometry(QtCore.QRect(400, 150, 256, 192)) # treeView.setObjectName("treeView") watchtree.setColumnCount(2) watchtree.setHeaderLabels(['Pointer', 'Value']) watchtree.clicked.connect(self.onClicked2) watchtree.doubleClicked.connect(self.onDClicked) watchLayout.addWidget(watchtree) watcheditlayout = QtWidgets.QHBoxLayout() watchLayout.addLayout(watcheditlayout) addrinput = QtWidgets.QLineEdit() self.addrinput = addrinput addrinput.setPlaceholderText("addr type np name") watcheditlayout.addWidget(addrinput) btnwatch = QtWidgets.QPushButton("&watch") btnwatch.clicked.connect(self.watch_var) watcheditlayout.addWidget(btnwatch) spacer = QtWidgets.QSpacerItem(20, 20, QtWidgets.QSizePolicy.Expanding) watcheditlayout.addSpacerItem(spacer) btndel = QtWidgets.QPushButton("&del") # btndel.clicked.connect(self.addOrDelFunc) watcheditlayout.addWidget(btndel) # combo2 = QtWidgets.QComboBox(self.parent) # combo2.addItem("argument pointer") # combo2.addItem("argument variable") # combo2.activated[str].connect(self.onActivated) horizontal_box.addLayout(argLayout) horizontal_box.addLayout(watchLayout) horizontal_box.setStretchFactor(argLayout, 2) horizontal_box.setStretchFactor(watchLayout, 3) vertical_box.addLayout(horizontal_box) vertical_box.addLayout(grid_box) self.parent.setLayout(vertical_box)