Example #1
0
    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)
Example #2
0
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
Example #3
0
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))
Example #4
0
def get_screen_ea():
    return idc.get_screen_ea()
Example #5
0
    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
Example #6
0
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)
Example #7
0
    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)
Example #8
0
 def req_cursor(self, hash):
     print('[*] request IDA Pro cursor position')
     addr = idc.get_screen_ea()
     self.notice_broker('cmd', "\"cmd\":\"%s\"" % addr)
     return
Example #9
0
        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()
Example #10
0
        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
Example #11
0
    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)
Example #12
0
 def _current_function(self):
     return idaapi.get_func(idc.get_screen_ea()).start_ea
Example #13
0
        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
Example #14
0
    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()
Example #15
0
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
Example #17
0
    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
Example #18
0
 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)
Example #19
0
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
Example #21
0
def get_screen_ea():
    if idaapi.IDA_SDK_VERSION <= 699:
        cursor = idc.GetScreenEA()
    else:
        cursor = idc.get_screen_ea()
    return cursor
Example #22
0
def get_rva() -> int:
    ea = idc.get_screen_ea()
    base = idaapi.get_imagebase()
    rva = ea - base
    return rva
Example #23
0
 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
Example #24
0
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)
Example #25
0
 def cmd_get_cursor_pos(self):
     return self.fmt_addr(idc.get_screen_ea())
Example #26
0
    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)