예제 #1
0
    def get_asm_comments(self):
        cmts = []
        for seg in idautils.Segments():
            seg_name = idc.SegName(seg)
            ea = idc.SegStart(seg)
            end = idc.SegEnd(seg)
            while ea < end:
                if ea != idc.BADADDR:
                    cmt = idc.GetCommentEx(ea, True)  # repeatable comments
                    if cmt:
                        if not self.check_isin_filter(cmt):
                            current_cmt = [
                                "%s:%-16X" % (seg_name, ea), 'R',
                                idc.GetDisasm(ea), cmt
                            ]
                            cmts.append(current_cmt)
                            self.n += 1

                    cmt2 = idc.GetCommentEx(ea, False)  # usual comments
                    if cmt2:
                        if not self.check_isin_filter(cmt2):
                            current_cmt = [
                                "%s:%-16X" % (seg_name, ea), 'N',
                                idc.GetDisasm(ea), cmt2
                            ]
                            cmts.append(current_cmt)
                            self.n += 1
                ea = idc.next_head(ea, end)
        return cmts
예제 #2
0
def find_exported_eas():
    """Find the address of all exported functions. Exported functions are
  entrypoints into this program that external code can execute."""
    exported_eas = set()
    for index, ordinal, ea, name in idautils.Entries():

        # Not sure how this happens, but IDA seemed to treat
        # `obstack_alloc_failed_handler` in `call cs:[obstack_alloc_failed_handler]`
        # as an entrypoint.
        num_data_refs = len(tuple(idautils.DataRefsTo(ea)))
        num_code_refs = len(tuple(idautils.CodeRefsTo(ea, True)))
        num_code_refs += len(tuple(idautils.CodeRefsTo(ea, True)))
        if num_data_refs and not num_code_refs:
            log.warning(
                "Ignoring entrypoint {:08x}, it's only referenced by data".
                format(ea))
            continue

        if not has_segment_type(ea, idc.SEG_CODE):
            log.warning(
                "Ignoring entrypoint {:08x}, it is not in a code segment".
                format(ea))
            continue

        if not idc.hasName(ea):
            old_name = name
            if name.startswith("."):
                name = idc.GetCommentEx(ea, 0)

            log.info("Renaming `{}` at {:08x} to `{}`".format(
                old_name, ea, name))
            idc.MakeName(ea, name)

    return exported_eas
예제 #3
0
def get_alternative_symnbol_name(ea):
  comment = idc.GetCommentEx(ea, 0) or ""
  for comment_line in comment.split("\n"):
    comment_line = comment_line.replace(";", "").strip()
    mstr = comment_line.split("'")
    return mstr[1] + "'" + mstr[2]
  return None
 def report_strings(self,
                    strs,
                    stack,
                    stack_min_value=None,
                    stack_max_value=None):
     ''' Parses and returns Stack strings as Strings '''
     for char_width in xrange(1, MAX_CHARACTER_WIDTH + 1):
         parsed_strs = self.parse_strings(stack, stack_min_value,
                                          stack_max_value, char_width)
         for string, eas, length in parsed_strs:
             startEA, endEA = self.find_start_and_end(eas)
             for string_obj in strs:
                 if string_obj[2] == string and string_obj[
                         0] == startEA and string_obj[1] == endEA:
                     break
             else:  # if we didn't break
                 strs.add((startEA, endEA, string))
                 old_cmt = idc.GetCommentEx(eas[0], 0)
                 old_cmt = '' if not old_cmt else old_cmt
                 if not is_string_ascii(string):
                     new_cmt = string.encode('hex')
                     new_cmt = old_cmt + '\nStack String (hex): ' + new_cmt
                 else:
                     new_cmt = string.encode('string-escape').replace(
                         '\\x00', '\nStack String: ')
                     new_cmt = old_cmt + '\nStack String: ' + new_cmt
                 new_cmt += '\nSize: ' + str(length)
                 new_cmt = '\n'.join(list(set(
                     new_cmt.split('\n'))))  # Remove duplicates.
                 idc.MakeComm(eas[0], str(new_cmt).strip('\r\n'))
예제 #5
0
def common_cmt(ea, funclist, prefix=None, offset=0, override=False):
    if not funclist:
        return
    cmt = set()
    for func in funclist:
        name = idc.get_func_off_str(func + offset)
        cmt.add(name)
    try:
        scmt = ' '.join(cmt)
    except Exception as e:
        print(e)
        return

    if prefix:
        scmt = prefix + scmt
    if not override:
        socmt = idc.GetCommentEx(ea, 0)
        if socmt:
            ocmt = []
            if prefix and socmt.startswith(prefix):
                socmt = socmt[len(prefix):]
            oldcmt = socmt.strip().split("\n")
            for _cmt in oldcmt:
                ocmt.extend(_cmt.split(' '))
            ocmt = set(ocmt)
            ocmt -= cmt
        else:
            ocmt = None
        if ocmt:
            scmt += "\n" + ' '.join(ocmt)
    idc.MakeComm(ea, scmt)
예제 #6
0
 def _extract_cmnts(self, repeatable):
     commdict = {}
     for func_item in self._func_items:
         i = int(func_item) - int(self._first_addr)
         comm = idc.GetCommentEx(func_item, repeatable)
         if (comm != None):
             commdict[i] = comm
     return commdict
예제 #7
0
파일: hooks.py 프로젝트: Spl3en/ipad
 def cmt_changed(self, ea, rep):
     cmt = idc.GetCommentEx(ea, rep)
     self.ctrl._handle_action({
         'action': 'cmt_changed',
         'ea': ea,
         'rep': rep,
         'cmt': cmt
     })
     return 0
예제 #8
0
 def get_jlocs(self, sw):
     jlocs = []
     ncases = sw.ncases if sw.jcases == 0 else sw.jcases
     for i in range(ncases):
         addr = idc.Dword(sw.jumps+i*4)
         name = idaapi.get_name(idc.BADADDR, addr)
         comm = idc.GetCommentEx(idc.LocByName(name), 1)
         comm = comm[comm.find('case'):] if comm is not None and comm.startswith('jumptable') else comm
         jlocs.append((name, idc.LocByName(name), comm))
     return jlocs
예제 #9
0
def get_alternative_symbol_name(ea):
  comment = idc.GetCommentEx(ea, 0) or ""
  for comment_line in comment.split("\n"):
    comment_line = comment_line.replace(";", "").strip()
    if not comment_line:
      continue
    mstr = comment_line.split("'")
    if 3 <= len(mstr):
      return mstr[1] + "'" + mstr[2]
  return None
예제 #10
0
 def yacheck_data_comments(self):
     eas = yaunit.load('data_comments')
     i = 0
     for offset in range(0, 3):
         for cmt, rpt, post, ant in tests_data:
             ea = eas[i]
             logger.debug(
                 "checking data comment at 0x%08X : %r, %r, %r, %r" %
                 (ea, cmt, rpt, post, ant))
             i += 1
             if cmt != None:
                 self.assertEqual(idc.GetCommentEx(ea, False), cmt)
             if rpt != None:
                 self.assertEqual(idc.GetCommentEx(ea, True), rpt)
             if post != None:
                 for j, txt in enumerate(post.split('\n')):
                     self.assertEqual(idc.LineB(ea, j), txt)
             if ant != None:
                 for j, txt in enumerate(ant.split('\n')):
                     self.assertEqual(idc.LineA(ea, j), txt)
예제 #11
0
    def _merge_cmnts(self, comments, repeatable):
        for ea_rel in comments:
            ea = int(ea_rel) + self._first_addr
            comment = comments[ea_rel]
            current_comment = idc.GetCommentEx(ea, repeatable)

            if current_comment is None:
                current_comment = ""

            final_comment = current_comment + "; REDB: " + comment
            self._embed_comment(ea, final_comment, repeatable)
            idaapi.refresh_idaview_anyway()
예제 #12
0
def push_comms():
    global skel_conn
    commBL = [
        "size_t", "int", "LPSTR", "char", "char *", "lpString", "unsigned int",
        "void *", "indirect table for switch statement", "this",
        "jump table for switch statement", "switch jump"
    ]
    for i in range(idc.MinEA(), idc.MaxEA()):
        if idc.GetCommentEx(
                i, 0) is not None and not idc.GetCommentEx(i, 0) in commBL:
            if not skel_conn.push_comment(i, idc.GetCommentEx(i, 0)):
                return -1
        elif idc.GetCommentEx(
                i, 1) is not None and not idc.GetCommentEx(i, 1) in commBL:
            if not skel_conn.push_comment(i, idc.GetCommentEx(i, 1)):
                return -1
    for function_ea in idautils.Functions(idc.MinEA(), idc.MaxEA()):
        fName = idc.GetFunctionName(function_ea)
        if hasSubNoppedPrefix(fName) is False:
            if not skel_conn.push_name(function_ea, fName):
                g_logger.error("Error sending function name %s" % (fName))
        # if idc.GetFunctionCmt(function_ea,0) != "":
        #    push_change("idc.SetFunctionCmt",shex(function_ea),idc.GetFunctionCmt(i,0))
        # elif idc.GetFunctionCmt(function_ea,1) != "":
        #    push_change("idc.SetFunctionCmt",shex(function_ea),idc.GetFunctionCmt(function_ea,1))
    return
예제 #13
0
def is_runtime_external_data_reference(ea):
    """This can happen in ELF binaries, where you'll have somehting like
  `stdout@@GLIBC_2.2.5` in the `.bss` section, where at runtime the
  linker will fill in the slot with a pointer to the real `stdout`.

  IDA discovers this type of reference, but it has no real way to
  cross-reference it to anything, because the target address will
  only exist at runtime."""
    comment = idc.GetCommentEx(ea, 0)
    if comment and "Copy of shared data" in comment:
        return True
    else:
        return False
예제 #14
0
 def parse_ivar(self, ea):
     cmt = idc.GetCommentEx(ea, True)
     if cmt:
         type = cmt.split()[0]
         self._ivars[ea] = type
         if type in self._ivars_2:
             self._ivars_2[type].append(ea)
         else:
             self._ivars_2[type] = [
                 ea,
             ]
     else:
         print 'CANNOT GET CMT OF IVAR: '.format(hex(ea))
예제 #15
0
        def postprocess(self):
            try:
                if "MakeComment" in self.cmdname:
                    if idc.Comment(self.addr) is not None:
                        self.skel_conn.push_comment(self.addr,
                                                    idc.Comment(self.addr))
                    if idc.GetFunctionCmt(self.addr, 0) != "":
                        self.skel_conn.push_comment(
                            self.addr, idc.GetFunctionCmt((self.addr), 0))
                elif "MakeRptCmt" in self.cmdname:
                    if idc.GetCommentEx(self.addr, 1) != "":
                        self.skel_conn.push_comment(
                            self.addr, idc.GetCommentEx(self.addr, 1))
                    if idc.GetFunctionCmt(self.addr, 1) != "":
                        self.skel_conn.push_comment(
                            self.addr, idc.GetFunctionCmt(self.addr, 1))

                elif self.cmdname == "MakeFunction":
                    if idc.GetFunctionAttr(self.addr, 0) is not None:
                        pass
                        #push_change("idc.MakeFunction", shex(idc.GetFunctionAttr(
                        #    self.addr, 0)), shex(idc.GetFunctionAttr(self.addr, 4)))
                elif self.cmdname == "DeclareStructVar":
                    print "Fixme : declare Struct variable"
                elif self.cmdname == "SetType":
                    newtype = idc.GetType(self.addr)
                    if newtype is None:
                        newtype = ""
                    else:
                        newtype = SkelUtils.prepare_parse_type(
                            newtype, self.addr)
                        self.skel_conn.push_type(int(self.addr), newtype)
                    # XXX IMPLEMENT
                elif self.cmdname == "OpStructOffset":
                    print "Fixme, used when typing a struct member/stack var/data pointer to a struct offset "
            except KeyError:
                pass
            return 0
예제 #16
0
def is_external_vtable_reference(ea):
    """ It checks the references of external vtable in the .bss section, where
      it is referred as the `Copy of shared data`. There is no way to resolve
      the cross references for these vtable as the target address will only
      appear during runtime.

      It is introduced to avoid lazy initilization of runtime typeinfo variables
      which gets referred by the user-defined exception types.
  """
    if not is_runtime_external_data_reference(ea):
        return False

    comment = idc.GetCommentEx(ea, 0)
    if comment and "Alternative name is '`vtable" in comment:
        return True
    else:
        return
예제 #17
0
def is_tls(ea):
    if is_invalid_ea(ea):
        return False

    if is_tls_segment(ea):
        return True

    # Something references `ea`, and that something is commented as being a
    # `TLS-reference`. This comes up if you have an thread-local extern variable
    # declared/used in a binary, and defined in a shared lib. There will be an
    # offset variable.
    for source_ea in _drefs_to(ea):
        comment = idc.GetCommentEx(source_ea, 0)
        if isinstance(comment, str) and "TLS-reference" in comment:
            return True

    return False
예제 #18
0
파일: __init__.py 프로젝트: s3ul/flare-ida
def get_segment_end_ea(ea):
    """ Return address where next MSDN info can be written to in added
    segment.

    Argument:
    ea -- effective address within added segment where search starts
    """
    addr = ea
    while idc.GetCommentEx(addr, 0) is not None:
        addr = addr + 1
    if addr > idc.get_segm_end(ea):
        g_logger.debug('Address {} out of segment bounds. Expanding segment.'
                       .format(hex(addr)))
        try:
            expand_segment(ea)
        except FailedToExpandSegmentException as e:
            g_logger.warning(e.message)
            raise e
    else:
        return addr
예제 #19
0
def find_arg_ea(ea_call, arg_name):
    """ Return ea of argument by looking backwards from library function
    call.

    Arguments:
    ea_call -- effective address of call
    arg_name -- the argument name to look for
    """
    # the search for previous instruction/data will stop at the specified
    # address (inclusive)
    prev_instr = idc.PrevHead(ea_call, ea_call - PREVIOUS_INSTR_DELTA)
    while prev_instr > (ea_call - ARG_SEARCH_THRESHOLD) and \
            prev_instr != idaapi.BADADDR:
        # False indicates not to look for repeatable comments
        comment = idc.GetCommentEx(prev_instr, False)
        if comment == arg_name:
            return prev_instr
        prev_instr = idc.PrevHead(prev_instr,
                                  prev_instr - PREVIOUS_INSTR_DELTA)
    raise ArgumentNotFoundException(
        '  Argument {} not found within threshold'.format(arg_name))
예제 #20
0
    def export(self, vtables):
        """
        @vtables: List of tuples with vtable information
                  [(ins_addr, vtable), ... ]
                  
        There is a small mistake. Some .data references will be tagged as being 
        vtables. This is due to the way we detect them on pin. In IDA pro it should
        be easy to mark just only the ones that refer to .text but I could not find
        a way to get that information from idapython.
        """

        # We build a dictionary with the ins addr referencing the vtable as the key
        dict_ = {}
        for vtable in vtables:
            # Add all the vtable references found while tracing to the set
            dict_.setdefault(vtable[0], set()).add(vtable[1])

        for (key, val) in dict_.iteritems():
            prev_comment = idc.GetCommentEx(vtable[0], False)

            # Check if we already have commented this line. This will avoid duplicating info.
            if not prev_comment or "VTables found:" in prev_comment:
                prev_comment = "VTables found:\n"

            prev_comment += "\n".join(map(lambda x: "0x%.8x" % x, val))

            # vtable[0] == instruction address
            idc.MakeComm(key, prev_comment)

            # Check if we already have a cross reference
            for v in val:
                if key in [ref.frm for ref in XrefsTo(v, 0)]:
                    continue

                # Add a data reference
                if add_dref(key, v, dr_R) != True:
                    idaapi.msg(
                        "Could not create cross reference from %x to %x\n" %
                        (key, v))
예제 #21
0
        def db_read(cls, address, key=None, repeatable=0):
            result = comment.toDict( idc.GetCommentEx(address, repeatable) )

            name = idc.NameEx(address, address)
            if name:
                result['__name__'] = name

            # defaults
            if '__color__' not in result:
                c = cls.color(address)
                if c is not None:
                    result['__color__'] = c
            if '__address__' not in result:
                result['__address__'] = address

            if '__context__' not in result:
                result['__context__'] = idc.GetFunctionAttr(address, idc.FUNCATTR_START)
            if '__sp__' not in result:
                result['__sp__'] = idc.GetSpd(address)

            if key is not None:
                return result[key]
            return result
예제 #22
0
    def export(self, resolved_branches):
        dict_ = {}
        for r in resolved_branches:
            dict_.setdefault(r[0], set()).add(r[1])

        for key, val in dict_.iteritems():
            prev_comment = idc.GetCommentEx(key, False)

            if not prev_comment or "Resolved:" in prev_comment:
                prev_comment = "Resolved:\n"

            for v in val:
                prev_comment += "%s : %.8x\n" % (GetAddressName(v), v)

                # Check if we already have a cross reference
                if key in [ref.frm for ref in XrefsTo(v, 0)]:
                    continue

                if AddCodeXref(key, v, fl_CN) != True:
                    idaapi.msg(
                        "Could not create cross reference from %x to %x\n" %
                        (key, v))

            idc.MakeComm(key, prev_comment)
예제 #23
0
 def getComment(self, ea):
     return idc.GetCommentEx(ea, False)
예제 #24
0
 def getComment(self, ea):
     res = idc.GetCommentEx(ea, False)
     if not res:
         return ""
     else:
         return res
예제 #25
0
    flow_insns = []

    while cur_addr <= end:
        next_instr = idc.NextHead(cur_addr, end)

        #get size instr
        if next_instr > end:
            size = end - cur_addr
        else:
            size = next_instr - cur_addr

        #get assembly and comments
        curr_asm = hex(cur_addr).rstrip("L") + "   " + idc.GetDisasm(
            cur_addr).split(';')[0]
        try:
            curr_asm += '   ;' + idc.GetCommentEx(cur_addr, True).replace(
                '\n', ' ')
        except:
            pass
        curr_asm += '\n'
        asm += curr_asm

        #get first byte of instruction
        opc = hex(ord(idc.GetManyBytes(cur_addr, 1)))[2:]
        if len(opc) < 2:
            opc = '0' + opc
        ops += opc

        #get instruction bytes
        insns_list.append(
            (cur_addr, base64.b64encode(idc.GetManyBytes(cur_addr, size))))
예제 #26
0
    def postprocess(self):
        global skel_conn
        try:
            if self.cmdname == "MakeComment":
                if idc.GetCommentEx(self.addr, 0) is not None:
                    skel_conn.push_comment(self.addr,
                                           idc.GetCommentEx((self.addr), 0))
                elif idc.GetCommentEx(self.addr, 1) is not None:
                    skel_conn.push_comment(self.addr,
                                           idc.GetCommentEx((self.addr), 1))
                elif idc.GetFunctionCmt(self.addr, 0) != "":
                    skel_conn.push_comment(self.addr,
                                           idc.GetCommentEx((self.addr), 0))
                elif idc.GetFunctionCmt(self.addr, 1) != "":
                    skel_conn.push_comment(
                        self.addr,
                        idc.GetFunctionCmt(self.addr,
                                           1).replace("\n", "\\n").replace(
                                               "\"", "\\\""))
            if self.cmdname == "MakeRptCmt":
                if idc.GetCommentEx(self.addr, 0) is not None:
                    skel_conn.push_comment(
                        self.addr,
                        idc.GetCommentEx(self.addr,
                                         0).replace("\n", "\\n").replace(
                                             "\"", "\\\""))
                elif idc.GetCommentEx(self.addr, 1) is not None:
                    skel_conn.push_comment(
                        self.addr,
                        idc.GetCommentEx(self.addr,
                                         1).replace("\n", "\\n").replace(
                                             "\"", "\\\""))
                elif idc.GetFunctionCmt(self.addr, 0) != "":
                    skel_conn.push_comment(
                        self.addr,
                        idc.GetFunctionCmt(self.addr,
                                           0).replace("\n", "\\n").replace(
                                               "\"", "\\\""))
                elif idc.GetFunctionCmt(self.addr, 1) != "":
                    skel_conn.push_comment(
                        self.addr,
                        idc.GetFunctionCmt(self.addr,
                                           1).replace("\n", "\\n").replace(
                                               "\"", "\\\""))
            elif self.cmdname == "MakeName":
                # idc.Jump(self.addr)
                if (idc.GetFunctionAttr(self.addr, 0) == self.addr):
                    fname = GetFunctionName(self.addr)
                    if fname != "":
                        if not CheckDefaultValue(fname):
                            skel_conn.push_name(self.addr, fname)
                else:
                    fname = idc.GetTrueName(self.addr)
                    if fname != "" and not CheckDefaultValue(fname):
                        skel_conn.push_name(
                            self.addr,
                            fname.replace("\n", "\\n").replace("\"", "\\\""))
                    else:
                        # ok, on regarde ce qui est pointe
                        if GetOpType(self.addr, 0) in [o_near, o_imm, o_mem]:
                            if GetOpType(self.addr,
                                         1) in [o_near, o_imm, o_mem]:
                                print "[P] You must be on the top of function or at the global address to set the name in log file"
                            else:
                                add = idc.GetOperandValue(self.addr, 0)
                                fname = idc.GetTrueName(add)
                                if fname != "" and not CheckDefaultValue(
                                        fname):
                                    skel_conn.push_name(
                                        add,
                                        fname.replace("\n", "\\n").replace(
                                            "\"", "\\\""))
                                else:
                                    print "[P] You must be on the top of function or at the global address to set the name in log file"
                        elif GetOpType(self.addr, 1) in [o_near, o_imm, o_mem]:
                            add = idc.GetOperandValue(self.addr, 1)
                            fname = idc.GetTrueName(add)
                            if fname != "" and not CheckDefaultValue(fname):
                                skel_conn.push_name(
                                    add,
                                    fname.replace("\n",
                                                  "\\n").replace("\"", "\\\""))
                            else:
                                print "[P] You must be on the top of function or at the global address to set the name in log file"

            elif self.cmdname == "MakeFunction":
                if idc.GetFunctionAttr(self.addr, 0) is not None:
                    pass
                    #push_change("idc.MakeFunction", shex(idc.GetFunctionAttr(
                    #    self.addr, 0)), shex(idc.GetFunctionAttr(self.addr, 4)))
            elif self.cmdname == "DeclareStructVar":
                print "Fixme : declare Struct variable"
            elif self.cmdname == "AddStruct":
                print "Fixme : adding structure"
            elif self.cmdname == "SetType":
                newtype = idc.GetType(self.addr)
                if newtype is None:
                    newtype = ""
                else:
                    newtype = prepare_parse_type(newtype, self.addr)
                push_change("idc.SetType", shex(self.addr), newtype)
            elif self.cmdname == "OpStructOffset":
                print "Fixme, used when typing a struct member/stack var/data pointer to a struct offset "
        except KeyError:
            pass
        return 0
예제 #27
0
 def getRptComment(self, ea):
     return idc.GetCommentEx(ea, True)
예제 #28
0
    def _profile_function(self):
        current_ea = idc.ScreenEA()
        current_function = idc.GetFunctionName(current_ea)
        current_function_ea = idc.LocByName(current_function)

        if current_function:
            self.function = current_function

        ea = start_ea = idc.GetFunctionAttr(current_function_ea,
                                            idc.FUNCATTR_START)
        end_ea = idc.GetFunctionAttr(current_function_ea, idc.FUNCATTR_END)

        self.highlighted = idaapi.get_highlighted_identifier()

        while ea < end_ea and ea != idc.BADADDR and self.highlighted:

            i = 0
            match = False
            optype = self.READ
            comment = None

            idaapi.decode_insn(ea)

            mnem = idc.GetMnem(ea)

            if self.highlighted in mnem:
                match = True
            elif idaapi.is_call_insn(ea):
                for xref in idautils.XrefsFrom(ea):
                    if xref.type != 21:
                        name = idc.Name(xref.to)
                        if name and self.highlighted in name:
                            match = True
                            break
            else:
                while True:
                    opnd = idc.GetOpnd(ea, i)
                    if opnd:
                        if self.highlighted in opnd:
                            try:
                                canon_feature = idaapi.insn_t_get_canon_feature(
                                    idaapi.cmd.ityp)
                            except AttributeError:
                                insn_t = idaapi.insn_t()
                                canon_feature = insn_t.get_canon_feature()
                            match = True
                            if canon_feature & self.OPND_WRITE_FLAGS[i]:
                                optype = self.WRITE
                        i += 1
                    else:
                        break

            if not match:
                comment = idc.GetCommentEx(ea, 0)
                if comment and self.highlighted in comment:
                    match = True
                else:
                    comment = idc.GetCommentEx(ea, 1)
                    if comment and self.highlighted in comment:
                        match = True
                    else:
                        comment = None

            if match:
                if ea > current_ea:
                    direction = self.DOWN
                elif ea < current_ea:
                    direction = self.UP
                else:
                    direction = self.THIS

                self.xrefs[ea] = {
                    'offset': idc.GetFuncOffset(ea),
                    'mnem': mnem,
                    'type': optype,
                    'direction': direction,
                    'text': idc.GetDisasm(ea),
                }

            ea += idaapi.cmd.size
예제 #29
0
파일: findcrypt.py 프로젝트: nevermoe/ida
def main():
    print("[*] loading crypto constants")
    for const in non_sparse_consts:
        const["byte_array"] = convert_to_byte_array(const)

    for start in idautils.Segments():
        print("[*] searching for crypto constants in %s" % idc.SegName(start))

        ea = start
        while ea < idc.SegEnd(start):
            bbbb = list(
                struct.unpack("BBBB",
                              idc.GetManyBytes(ea, 4) or "AAAA"))
            for const in non_sparse_consts:
                if bbbb != const["byte_array"][:4]:
                    continue
                if map(
                        lambda x: ord(x),
                        idc.GetManyBytes(ea, len(const["byte_array"]))
                        or list()) == const["byte_array"]:
                    print(("0x%0" + str(digits) +
                           "X: found const array %s (used in %s)") %
                          (ea, const["name"], const["algorithm"]))
                    idc.MakeName(ea, const["name"])
                    if const["size"] == "B":
                        idc.MakeByte(ea)
                    elif const["size"] == "L":
                        idc.MakeDword(ea)
                    elif const["size"] == "Q":
                        idc.MakeQword(ea)
                    MakeArray(ea, len(const["array"]))
                    ea += len(const["byte_array"]) - 4
                    break
            ea += 4
            #print "ea: 0x%x " % ea

        ea = start
        if idc.GetSegmentAttr(ea, SEGATTR_TYPE) == 2:
            while ea < idc.SegEnd(start):
                d = idc.Dword(ea)
                for const in sparse_consts:
                    if d != const["array"][0]:
                        continue
                    tmp = ea + 4
                    for val in const["array"][1:]:
                        for i in range(8):
                            if idc.Dword(tmp + i) == val:
                                tmp = tmp + i + 4
                                break
                        else:
                            break
                    else:
                        print(("0x%0" + str(digits) +
                               "X: found sparse constants for %s") %
                              (ea, const["algorithm"]))
                        cmt = idc.GetCommentEx(idc.prev_head(ea), 0)
                        if cmt:
                            idc.CommentEx(idc.prev_head(ea),
                                          cmt + ' ' + const["name"], 0)
                        else:
                            idc.CommentEx(idc.prev_head(ea), const["name"], 0)
                        ea = tmp
                        break
                ea += 1
    print("[*] finished")
예제 #30
0
    def _profile_function(self):
        current_ea = ida_shims.get_screen_ea()
        current_function = ida_shims.get_func_name(current_ea)
        current_function_ea = ida_shims.get_name_ea_simple(current_function)

        if current_function:
            self.function = current_function

        ea = ida_shims.get_func_attr(current_function_ea, idc.FUNCATTR_START)
        end_ea = ida_shims.get_func_attr(current_function_ea, idc.FUNCATTR_END)

        self.highlighted = ida_shims.get_highlighted_identifier()

        while ea < end_ea and ea != idc.BADADDR and self.highlighted:
            i = 0
            match = False
            optype = self.READ

            insn = ida_shims.decode_insn(ea)

            mnem = ida_shims.print_insn_mnem(ea)

            if self.highlighted in mnem:
                match = True
            elif idaapi.is_call_insn(ea):
                for xref in idautils.XrefsFrom(ea):
                    if xref.type != 21:
                        name = ida_shims.get_name(xref.to)
                        if name and self.highlighted in name:
                            match = True
                            break
            else:
                while True:
                    opnd = ida_shims.print_operand(ea, i)
                    if opnd:
                        if self.highlighted in opnd:
                            canon_feature = ida_shims.get_canon_feature(insn)
                            match = True
                            if canon_feature & self.OPND_WRITE_FLAGS[i]:
                                optype = self.WRITE
                        i += 1
                    else:
                        break

            if not match:
                comment = idc.GetCommentEx(ea, 0)
                if comment and self.highlighted in comment:
                    match = True
                else:
                    comment = idc.GetCommentEx(ea, 1)
                    if comment and self.highlighted in comment:
                        match = True
                    else:
                        comment = None

            if match:
                if ea > current_ea:
                    direction = self.DOWN
                elif ea < current_ea:
                    direction = self.UP
                else:
                    direction = self.THIS

                self.xrefs[ea] = {
                    'offset': ida_shims.get_func_off_str(ea),
                    'mnem': mnem,
                    'type': optype,
                    'direction': direction,
                    'text': idc.GetDisasm(ea),
                }

            ea = ida_shims.next_head(ea)