Python idc.GetDisasm() Examples

The following are 16 code examples of idc.GetDisasm(). You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may also want to check out all available functions/classes of the module idc , or try the search function .
Example #1
Source File: interesting_xor.py    From idataco with GNU General Public License v3.0 6 votes vote down vote up
def find_interesting_xors(self):
        next_xor = idc.FindText(idc.MinEA(), idc.SEARCH_DOWN|idc.SEARCH_NEXT, 0, 0, "xor")
        while next_xor != idc.BADADDR:
            if idc.GetOpnd(next_xor, 0) != idc.GetOpnd(next_xor, 1):
                entry = {"func":"", "addr": next_xor, "loop":False, "disasm": idc.GetDisasm(next_xor)}
                func = idaapi.get_func(next_xor)
                if func:
                    entry["func"] = idaapi.get_name(idc.BADADDR, func.startEA)
                    heads = idautils.Heads(next_xor, func.endEA)
                    lxors = []
                    for head in heads:
                        if idc.GetMnem(head).startswith('j'):
                            jmp_addr = idc.GetOperandValue(head,0)
                            if jmp_addr < next_xor and jmp_addr > func.startEA:
                                entry["loop"] = True
                                break
                self._interesting_xors.append(entry)
            next_xor = idc.FindText(idc.NextHead(next_xor), idc.SEARCH_DOWN|idc.SEARCH_NEXT, 0, 0, "xor") 
Example #2
Source File: Reef.py    From Reef with GNU General Public License v3.0 6 votes vote down vote up
def find_xrefs_from( self, func_ea ):
    
        xrefs = []

        for item in idautils.FuncItems( func_ea ):
            
            ALL_XREFS = 0
            for ref in idautils.XrefsFrom( item, ALL_XREFS ):
                    
                if ref.type not in XrefsFromFinder.XREF_TYPE2STR:
                    continue
                
                if ref.to in idautils.FuncItems( func_ea ):
                    continue
                
                disas = idc.GetDisasm( item )
                curr_xref = XrefFrom( item, ref.to, ref.type, disas )
                xrefs.append( curr_xref )
                
        return xrefs 
Example #3
Source File: IDAMetrics_static.py    From IDAmetrics with BSD 2-Clause "Simplified" License 6 votes vote down vote up
def is_operand_called(self, op, bbl):
        '''
        The function checks whether operand used for call instruction in the
        following instructions or not.
        @op - operand
        @bbl - list of instructions in bbl
        @return - True if used
        '''
        for instr in bbl:
            instr_type = GetInstructionType(int(instr,16))
            if instr_type == CALL_INSTRUCTION or\
               instr_type == BRANCH_INSTRUCTION:
                instr_ops = self.get_instr_operands(int(instr, 16))
                if op in instr_ops:
                    return True
                #trying to replace ds: and check it again
                op = op.replace("ds:","")
                comment = idc.GetDisasm(int(instr,16))
                if comment != None and op in comment:
                    return True
        return False 
Example #4
Source File: mykutils.py    From flare-ida with Apache License 2.0 6 votes vote down vote up
def emit_fnbytes_python(fva=None, warn=True):
    """Emit function bytes as Python code with disassembly in comments.

    Args:
        fva (numbers.Integral): function virtual address.
            Defaults to here() if that is the start of a function, else
            defaults to the start of the function that here() is a part of.
        warn (bool): enable interactive warnings

    Returns:
        str: Python code you can spruce up and paste into a script.
    """
    header = 'instrs_{name} = (\n'
    footer = ')'
    indent = '    '

    def _emit_instr_python(va, the_bytes, size):
        disas = idc.GetDisasm(va)
        return "'%s' # %s\n" % (binascii.hexlify(the_bytes), disas)

    return _emit_fnbytes(_emit_instr_python, header, footer, indent, fva, warn) 
Example #5
Source File: mykutils.py    From flare-ida with Apache License 2.0 6 votes vote down vote up
def emit_fnbytes_c(fva=None, warn=True):
    """Emit function bytes as C code with disassembly in comments.

    Args:
        fva (numbers.Integral): function virtual address.
            Defaults to here() if that is the start of a function, else
            defaults to the start of the function that here() is a part of.
        warn (bool): enable interactive warnings

    Returns:
        str: C code you can spruce up and paste into a script.
    """

    header = 'unsigned char *instrs_{name} = {{\n'
    footer = '};'
    indent = '\t'

    def _emit_instr_for_c(va, the_bytes, size):
        disas = idc.GetDisasm(va)
        buf = ''.join(['\\x%s' % (binascii.hexlify(c)) for c in the_bytes])
        return '"%s" /* %s */\n' % (buf, disas)

    return _emit_fnbytes(_emit_instr_for_c, header, footer, indent, fva, warn) 
Example #6
Source File: dsc_fix.py    From dsc_fix with GNU General Public License v3.0 6 votes vote down vote up
def get_bad_addresses(verbose=True):
    """ gets all the unmapped addressed from IDA's database """
    ret = []
    curEa = idc.MinEA()
    while True:
        if verbose:
            print "[+] getting more bad addresses 0x%08X" % (curEa)
        # the regex "(DC[DQ]| B.*) +0x" will retrieve the following:
        # 1. DCD 0x...
        # 2. DCQ 0x...
        # 3. B   0x.....
        # 4. BL  0x....
        curEa = get_next_bad_addr(curEa, "(DC[DQ]| B.*) +0x")
        if curEa == idc.BADADDR:
            break
        if verbose:
            print "[+] found bad address at 0x%08X" % (curEa)
        dcd = idc.GetDisasm(curEa)
        res = re.findall("0x\w{8,}", dcd)
        for r in res:
            ret.append(int(r, 16))
    if verbose:
        print "[+] found %d bad addresses" % len(ret)
    return ret 
Example #7
Source File: ida_utils.py    From idasec with GNU Lesser General Public License v2.1 5 votes vote down vote up
def dump(self):
        return '\n'.join([idc.GetDisasm(x) for x in self.instrs]) 
Example #8
Source File: ida_utils.py    From idasec with GNU Lesser General Public License v2.1 5 votes vote down vote up
def dump_alive(self):
        return '\n'.join([idc.GetDisasm(x) for x in self.instrs if self.instrs_status[x] == Status.ALIVE]) 
Example #9
Source File: ida_utils.py    From idasec with GNU Lesser General Public License v2.1 5 votes vote down vote up
def safe_path_to(self, addr):
        path = self.full_path_to(addr)  # Start from the full path
        i = -1
        for ea, k in zip(path, range(len(path))):  # Compute i such that it is safe
            nb_preds = len([x for x in idautils.CodeRefsTo(ea, True)])
            if nb_preds > 1:
                i = k
            elif idc.GetDisasm(ea).startswith("call"):
                i = k+1
        print i
        if i == -1:
            return path
        else:
            return path[i:] 
Example #10
Source File: static_opaque_analysis.py    From idasec with GNU Lesser General Public License v2.1 5 votes vote down vote up
def refine_results(self):
        likely_retag = 0
        fp_retag = 0
        fn_retag = 0
        for rtn_addr, candidates in self.functions_candidates.items():
            for addr in sorted(candidates):
                res = self.results[addr]
                val = sum([x in res.predicate for x in ["(0 :: 2)", "7x", "7y", u"²"]])
                final_status = res.status
                alive, dead = res.alive_branch, res.dead_branch
                if res.status == self.po.NOT_OPAQUE:
                    if val != 0:
                        fn_retag += 1
                        final_status = self.po.OPAQUE
                        jmp_target = [x for x in idautils.CodeRefsFrom(addr, 0)][0]
                        next_target = [x for x in idautils.CodeRefsFrom(addr, 1) if x != jmp_target][0]
                        alive, dead = (next_target, jmp_target) if idc.GetDisasm(addr)[:2] == "jz" else (jmp_target, next_target)
                        self.functions_spurious_instrs[rtn_addr].update(res.dependency+[addr])
                elif res.status == self.po.OPAQUE:
                    if val == 0:
                        fp_retag += 1
                        final_status = self.po.NOT_OPAQUE
                elif res.status == self.po.LIKELY:
                    if val == 0:
                        final_status = self.po.NOT_OPAQUE
                    else:
                        final_status = self.po.OPAQUE
                        jmp_target = [x for x in idautils.CodeRefsFrom(addr, 0)][0]
                        next_target = [x for x in idautils.CodeRefsFrom(addr, 1) if x != jmp_target][0]
                        alive, dead = (next_target, jmp_target) if idc.GetDisasm(addr)[:2] == "jz" else (jmp_target, next_target)
                        self.functions_spurious_instrs[rtn_addr].update(res.dependency+[addr])
                    likely_retag += 1
                self.results[addr] = AddrRet(final_status, res.k, res.dependency, res.predicate, res.distance, alive, dead)
        print "Retag: FP->OK:%d" % fp_retag
        print "Retag: FN->OP:%d" % fn_retag
        print "Retag: Lkl->OK:%d" % likely_retag 
Example #11
Source File: line.py    From Sark with MIT License 5 votes vote down vote up
def disasm(self):
        """Line Disassembly"""
        return idc.GetDisasm(self.ea) 
Example #12
Source File: colorizer.py    From deREferencing with GNU General Public License v3.0 5 votes vote down vote up
def get_disasm(self, ea):
        d = idc.GetDisasm(ea)[:config.max_string_len]
        return self.strip_disas_spaces(d) 
Example #13
Source File: imports.py    From idataco with GNU General Public License v3.0 4 votes vote down vote up
def renameDword(self):
        proc_addr = self._import_table.item(self._import_table.currentRow(), 3).text()
        proc_name = str(self._import_table.item(self._import_table.currentRow(), 2).text())
        renamed = 0
        if proc_addr:
            try:
                proc_addr = int(proc_addr, 16)
                proc_bin_str = " ".join([x.encode("hex") for x in struct.pack("<I", proc_addr)])
                next_dword = idc.FindBinary(idc.MinEA(), idc.SEARCH_DOWN|idc.SEARCH_NEXT, proc_bin_str)
                while next_dword != idc.BADADDR:
                    log.debug("Trying to fix-up 0x{:08x}".format(next_dword))
                    # DWORDs can be "inaccessible" for many reasons and it requires "breaking up" the data blobs
                    # and manually fixing them

                    # Reason 1: In a dword array in an unknown section
                    if idc.isUnknown(next_dword):
                        idc.MakeUnkn(next_dword, idc.DOUNK_EXPAND)
                        idc.MakeDword(next_dword)
                    # Reason 2: In a dword array in a data section
                    elif idc.isData(next_dword):
                        hd = idc.ItemHead(next_dword)
                        idc.MakeDword(hd)
                        idc.MakeDword(next_dword)
                    # Reason 3: In a dword array in a code section (validate via "dd <dword>,")
                    elif idc.isCode(next_dword) and idc.GetDisasm(next_dword).startswith("dd "):
                        hd = idc.ItemHead(next_dword)
                        idc.MakeDword(hd)
                        idc.MakeDword(next_dword)

                    # Only perform
                    if idc.Name(next_dword).startswith(("off_", "dword_")) or idc.Name(next_dword) == "":
                        success = idc.MakeNameEx(next_dword, proc_name, idc.SN_NOWARN|idc.SN_NON_AUTO)
                        i = 0
                        new_proc_name = proc_name
                        while not success and i < 10:
                            new_proc_name = "{}{}".format(proc_name, i)
                            success = idc.MakeNameEx(next_dword, new_proc_name, idc.SN_NOWARN|idc.SN_NON_AUTO)
                            i += 1
                        if success:
                            renamed += 1
                            item = self._import_table.item(self._import_table.currentRow(), 5)
                            item.setText("{}, {}".format(str(item.text()), new_proc_name))
                            log.debug("DWORD @ 0x{:08x} now has name {}".format(next_dword, new_proc_name))
                        else:
                            log.error("Unable to auto-rename successfully, terminating search")
                            break
                    else: log.debug("Value at 0x{:08x} does not meet renaming requirements".format(next_dword))
                    next_dword = idc.FindBinary(next_dword+4, idc.SEARCH_DOWN|idc.SEARCH_NEXT, proc_bin_str)
            except Exception, e:
                log.error("Error encountered: {}".format(e))
            log.debug("Renamed {:d} instances of {}".format(renamed, proc_name)) 
Example #14
Source File: IDAMetrics_static.py    From IDAmetrics with BSD 2-Clause "Simplified" License 4 votes vote down vote up
def get_function_args_count(self, function_ea, local_vars):
        """
        The function returns count of function arguments
        @function_ea - function entry point
        @local_vars - local variables dictionary
        @return - function arguments count
        """
        # i#9 Now, we can't identify fastcall functions.

        function_args_count = 0
        args_dict = dict()
        for local_var in local_vars:
            usage_list = local_vars.get(local_var, None)
            if usage_list == None:
                print "WARNING: empty usage list for ", local_var
                continue
            for head in usage_list:
                ops = self.get_instr_operands(int(head, 16))
                for idx, (op,type) in enumerate(ops):
                    if op.count("+") == 1:
                        value = idc.GetOperandValue(int (head, 16), idx)
                        if value < (15 * ARGUMENT_SIZE) and "ebp" in op:
                            args_dict.setdefault(local_var, []).append(head)
                    elif op.count("+") == 2:
                        if "arg" in local_var:
                            args_dict.setdefault(local_var, []).append(head)
                    else:
                        continue

        function_args_count = len(args_dict)
        if function_args_count:
            return function_args_count, args_dict

        #TODO Check previous algorithm here
        f_end = idc.FindFuncEnd(function_ea)
        f_end = idc.PrevHead(f_end, 0)
        instr_mnem = idc.GetMnem(f_end)
        #stdcall ?
        if "ret" in instr_mnem:
            ops = self.get_instr_operands(f_end)
            if len(ops) == 1:
                for op,type in ops:
                    op = op.replace("h", "")
                    function_args_count = int(op,16)/ARGUMENT_SIZE
                    return function_args_count, args_dict
        #cdecl ?
        refs = idautils.CodeRefsTo(function_ea, 0)
        for ref in refs:
            #trying to find add esp,x signature after call
            head = idc.NextHead(ref, 0xFFFFFFFF)
            if head:
                disasm = idc.GetDisasm(head)
                if "add" in disasm and "esp," in disasm:
                    ops = self.get_instr_operands(head)
                    op,type = ops[1]
                    if op:
                        op = op.replace("h", "")
                        function_args_count = int(op,16)/ARGUMENT_SIZE
                        return function_args_count, args_dict
        return function_args_count, args_dict 
Example #15
Source File: code_grafter.py    From flare-ida with Apache License 2.0 4 votes vote down vote up
def _patchCalls(self):
        def do_patch_call(va):
            retval = False
            stub_loc = idc.get_name_ea_simple(self._stubname(nm))

            # Preserve original disassembly and format new comment
            old_target = idc.print_operand(va, 0)
            orig_cmt = idc.get_cmt(va, 0) or ''
            new_cmt = '%s\n\t%s' % (g_patched_call_cmt, idc.GetDisasm(va))

            if idc.get_operand_type(va, 0) == ida_ua.o_mem:
                retval = patch_import(va, self._stubname(nm))
                new_cmt += '\n%s %s to %s)' % (g_cmt_pointed, old_target,
                                               self._stubname(nm))
            elif idc.get_operand_type(va, 0) == ida_ua.o_reg:
                va_imp = self._get_imp_for_register_call(va, nm)
                if va_imp:
                    patch_pointer_width(va_imp, stub_loc)
                    retval = True
                else:
                    logger.warn('Could not find import to patch call at %s' %
                                (phex(va)))

            else:  # Usually optype 7 otherwise
                # Won't work if displacement exceeds 32-bit operand size
                call_offset_loc = va + idc.get_item_size(va)
                if abs(call_offset_loc - stub_loc) > 0x100000000:
                    msg = ('Call site at %s too far from %s (%s)' %
                           (phex(va), self._stubname(nm), phex(stub_loc)))
                    raise CodeGraftingDisplacementError(msg)
                retval = patch_call(va, self._stubname(nm))

            if retval:
                if orig_cmt:
                    new_cmt += '\n%s' % (orig_cmt)
                idc.set_cmt(va, new_cmt, 0)
                ida_xref.add_cref(va, stub_loc, ida_xref.fl_CN)

            return retval

        for names in self._emu_stubs.keys():
            for nm in names:
                va = idc.get_name_ea_simple(nm)
                mykutils.for_each_call_to(do_patch_call, va)

        for nm, aliases in g_allocators_aliases.items():
            for alias in aliases:
                # do_patch_call closure will turn <nm> into stub_<nm>
                mykutils.for_each_call_to(do_patch_call,
                                          idc.get_name_ea_simple(alias)) 
Example #16
Source File: dsc_fix.py    From dsc_fix with GNU General Public License v3.0 4 votes vote down vote up
def map_shared_bridges(dsc_file, adrfind):
    """ finds branch islands in a given dyld_shared_cache file,
        maps them to IDA's db and extract its addresses """
    dsc_file.seek(0, 2)
    filesize = dsc_file.tell()
    dsc_file.seek(0)
    ACCESS_READ = 1
    a = mmap.mmap(dsc_file.fileno(), length=filesize, access=ACCESS_READ)
    reexp = re.compile("\xcf\xfa\xed\xfe.{340,360}dyld_shared_cache_branch_islands")
    print "[+] scanning dsc for BRANCH ISLANDS"
    # this list will hold all our branch_islands segments
    branch_islands_segments = []
    jmp_to_code = collections.defaultdict(list)
    for ma in reexp.finditer(a):
        print "[+] WRITING BRANCH ISLAND: 0x%08X" % (ma.start())
        fif = FileInFile(dsc_file, ma.start())
        m = MachO_patched(fif)
        if _IN_IDA:
            for seg in m.segments:
                for sec in seg.sections:
                    idc.AddSegEx(sec.addr,
                                 sec.addr + sec.size, 0, 0,
                                 idaapi.saRelPara, idaapi.scPub,
                                 idc.ADDSEG_FILLGAP)
                    name = "branch_islands_%X%s%s" % (ma.start(), seg.segname, sec.sectname)
                    idc.RenameSeg(sec.addr, name)
                    idc.SetSegClass(sec.addr, "CODE")
                    idc.SetSegAddressing(sec.addr, 2)
                    dsc_file.seek(sec.offset)
                    memcpy(sec.addr, dsc_file.read(sec.size))
                    branch_islands_segments.append(sec.addr)
                    # make code
                    codeea = sec.addr
                    print "Going through the code!"
                    while codeea < (sec.addr + sec.size):
                        res = idc.MakeCode(codeea)
                        if not res:
                            print "[!] EA:0x%X ERR while making code" % codeea
                            codeea += 4
                            continue

                        d = idc.GetDisasm(codeea)
                        # if it's a "B     0x4dd13550"
                        if d.startswith("B "):
                            addr = d.split()[1]
                            if addr.startswith("0x"):
                                branchaddr = int(addr, 16)
                                jmp_to_code[branchaddr].append(codeea)
                                #   idc.MakeRptCmt(codeea, "0x%X was taken!" % branchaddr)

                        codeea = idc.FindUnexplored(codeea, idc.SEARCH_DOWN)
    label_and_fix_branch_islands(dsc_file, adrfind, jmp_to_code)