Exemplo n.º 1
0
def append_comment(ea, s, repeatable=False):
    """
    add the given string as a (possibly repeating) comment to the given address.
    does not add the comment if it already exists.
    adds the comment on its own line.

    Args:
      ea (int): the address at which to add the comment.
      s (str): the comment text.
      repeatable (bool): if True, set a repeatable comment.

    """
    # see: http://blogs.norman.com/2011/security-research/improving-ida-analysis-of-x64-exception-handling

    if repeatable:
        string = idc.get_cmt(ea, 1)
    else:
        string = idc.get_cmt(ea, 0)

    if not string:
        string = s  # no existing comment
    else:
        if s in string:  # ignore duplicates
            return
        string = string + "\\n" + s

    if repeatable:
        idc.set_cmt(ea, string, 1)
    else:
        idc.set_cmt(ea, string, 0)
Exemplo n.º 2
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
             self.assertEqual(idc.get_cmt(ea, False), cmt)
             self.assertEqual(idc.get_cmt(ea, True), rpt)
             self.assertEqual(self.get_extra(ea, idc.E_NEXT), post)
             self.assertEqual(self.get_extra(ea, idc.E_PREV), ant)
Exemplo n.º 3
0
        def do_unpatch_call(va_callsite):
            size = idc.get_item_size(va_callsite)
            ida_xref.del_cref(va_callsite, fva_stub, 0)
            cmt = idc.get_cmt(va_callsite, 0)

            newcmt = cmt

            # Remove automated comments
            if newcmt.startswith(g_patched_call_cmt):
                newcmt = newcmt[newcmt.find('\n') + 1:]
                if newcmt.find('\n') == -1:
                    newcmt = ''
                else:
                    newcmt = newcmt[newcmt.find('\n') + 1:]
                if newcmt.startswith(g_cmt_pointed):
                    if newcmt.find('\n') == -1:
                        newcmt = ''
                    else:
                        newcmt = newcmt[newcmt.find('\n') + 1:]

            if newcmt != cmt:
                idc.set_cmt(va_callsite, newcmt, 0)

            if idc.get_operand_type(va_callsite, 0) == ida_ua.o_mem:
                patch_import(va_callsite, idc.BADADDR)
            elif idc.get_operand_type(va_callsite, 0) == ida_ua.o_reg:
                va_imp = self._get_imp_for_register_call(va_callsite)
                if va_imp:
                    patch_pointer_width(va_imp, idc.BADADDR)
            else:
                revert_patch(va_callsite, size)
Exemplo n.º 4
0
 def set_name(addr, name):
     # FIXME creates unnamed_178 etc. instead of proper function name in IDA 7.2 on CYW20735
     name = name.replace("sub_", "unnamed_")
     cmt = idc.get_cmt(addr, 0)
     name_cmt = "fcn.%s" % name
     if cmt:
         name_cmt = cmt + ", " + name_cmt
     idc.set_cmt(addr, name_cmt, 0)
     if not add_names:
         return
     if name.isupper():
         try:
             # hackish way to stop warning about hex import
             # FIXME leave 'sub_' intact if it already exists
             # FIXME do not set the name to the hex prologue because it has duplicates, set it to
             #       'pp_{position}' instead
             a = int(name, 16)
             """continue"""
         except ValueError:
             pass
     ok = idc.set_name(addr, name, idc.SN_CHECK)
     if not ok:
         data = (name, size, addr)
         failed_fncs.append((data, "name"))
         print("{0:#x}: cannot add name, {1}".format(addr, name))
         countername_Fail = countername_Fail + 1
     else:
         imported_functions[addr].add(name)
Exemplo n.º 5
0
    def execute_comment(comment):
        """
            Thread safe comment wrapper
        """
        def make_rpt():
            """
                Inserting a comment
            """
            ida_bytes.set_cmt(comment["address"],
                              comment["data"].encode('ascii', 'replace'), 1)

        cmt = idc.get_cmt(comment["address"], 0)
        if cmt != comment["data"] and idc.get_cmt(comment["address"],
                                                  1) != comment["data"]:
            logger.debug("[x] Adding comment %s @ 0x%x ", comment["data"],
                         comment["address"])
            return idaapi.execute_sync(make_rpt, idaapi.MFF_FAST)
        return None
 def activate(self, ctx):
     pos = idc.get_screen_ea()
     # Get current comment for this instruction and remove the C define from it, if present
     comment = idc.get_cmt(pos, 0)
     code = get_operand_value(pos)
     define = ioctl_decoder.get_define(code)
     comment = comment.replace(define, "")
     idc.set_cmt(pos, comment, 0)
     # Remove the ioctl from the valid list and add it to the invalid list to avoid 'find_all_ioctls' accidently re-indexing it.
     ioctl_tracker.remove_ioctl(pos, code)
def make_comment(pos, string):
    """
    Creates a comment with contents `string` at address `pos`.
    If the address is already commented append the new comment to the existing comment
    """

    current_comment = idc.get_cmt(pos, 0)
    if not current_comment:
        idc.set_cmt(pos, string, 0)
    elif string not in current_comment:
        idc.set_cmt(pos, current_comment + " " + string, 0)
Exemplo n.º 8
0
 def cmt_changed(self, *args):
     """
         A comment changed somewhere
     """
     addr, rpt = args
     logger.debug("Changed cmt at 0x%x rpt is %d",
                  addr, rpt)
     cmt = idc.get_cmt(addr, rpt)
     if not SkelUtils.filter_coms_blacklist(cmt):
         self.skel_conn.push_comment(addr, cmt)
     return ida_idp.IDB_Hooks.cmt_changed(self, *args)
Exemplo n.º 9
0
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.get_segm_name(start))
        ea = start
        while ea < idc.get_segm_end(start):
            bbbb = list(struct.unpack("BBBB", idc.get_bytes(ea, 4)))
            for const in non_sparse_consts:
                if bbbb != const["byte_array"][:4]:
                    continue
                if map(lambda x:ord(x), idc.get_bytes(ea, len(const["byte_array"]))) == const["byte_array"]:
                    print(("0x%0" + str(digits) + "X: found const array %s (used in %s)") % (ea, const["name"], const["algorithm"]))
                    idc.set_name(ea, const["name"])
                    if const["size"] == "B":
                        idc.create_byte(ea)
                    elif const["size"] == "L":
                        idc.create_dword(ea)
                    elif const["size"] == "Q":
                        idc.create_qword(ea)
                    idc.make_array(ea, len(const["array"]))
                    ea += len(const["byte_array"]) - 4
                    break
            ea += 4

        ea = start
        if idc.get_segm_attr(ea, idc.SEGATTR_TYPE) == 2:
            while ea < idc.get_segm_end(start):
                d = ida_bytes.get_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 ida_bytes.get_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.get_cmt(idc.prev_head(ea), 0)
                        if cmt:
                            idc.set_cmt(idc.prev_head(ea), cmt + ' ' + const["name"], 0)
                        else:
                            idc.set_cmt(idc.prev_head(ea), const["name"], 0)
                        ea = tmp
                        break
                ea += 1
    print("[*] finished")
Exemplo n.º 10
0
 def execute_comment(comment):
     """
         Thread safe comment wrapper
     """
     def make_rpt():
         """
             Inserting a comment
         """
         ida_bytes.set_cmt(
             comment["address"],
             comment["data"].encode(
                 'ascii',
                 'replace'),
             1)
     cmt = idc.get_cmt(comment["address"], 0)
     if cmt != comment["data"] and idc.get_cmt(
             comment["address"], 1) != comment["data"]:
         logger.debug(
             "[x] Adding comment %s @ 0x%x ",
             comment["data"],
             comment["address"])
         return idaapi.execute_sync(make_rpt, idaapi.MFF_FAST)
     return None
Exemplo n.º 11
0
    def get_func_item(self, offset):
        while True:
            ea = get_func_item(offset)
            skip = False

            def getlen(x):
                return len(x) if x else 0

            for x in [False, True]:
                skip |= getlen(idc.get_func_cmt(ea, x))
                skip |= getlen(idc.get_cmt(ea, x))
            for x in [idc.E_PREV, idc.E_NEXT]:
                skip |= getlen(self.get_extra(ea, x))
            if not skip:
                return ea
Exemplo n.º 12
0
def append_comment(va, new_cmt, repeatable=False):
    """
    Append a comment to an address in IDA Pro.
    :param va: comment address
    :param new_cmt: comment string
    :param repeatable: if True, append as repeatable comment
    :return: True if success
    """
    cmt = idc.get_cmt(va, repeatable)
    if not cmt:
        # no existing comment
        cmt = new_cmt
    else:
        if new_cmt in cmt:
            # comment already exists
            return True
        cmt = cmt + "\n" + new_cmt
    return idc.set_cmt(va, cmt, repeatable)
Exemplo n.º 13
0
def append_comment(va, new_cmt, repeatable=False):
    """
    Append a comment to an address in IDA Pro.
    :param va: comment address
    :param new_cmt: comment string
    :param repeatable: if True, append as repeatable comment
    :return: True if success
    """
    cmt = idc.get_cmt(va, repeatable)
    if not cmt:
        # no existing comment
        cmt = new_cmt
    else:
        if new_cmt in cmt:
            # comment already exists
            return True
        cmt = cmt + "\n" + new_cmt
    return idc.set_cmt(va, cmt, repeatable)
Exemplo n.º 14
0
 def imp_cb(ea, name, ord):
     if name in funcs:
         for xref in idautils.XrefsTo(ea):
             call_addr = xref.frm
             caller_name = idc.get_func_name(call_addr)
             prev = idc.prev_head(call_addr)
             for _ in range(10):
                 if idc.get_cmt(prev, 0) == 'Tag' and idc.get_operand_type(
                         prev, 1) == 5:
                     tag_raw = idc.get_operand_value(prev, 1)
                     tag = ''
                     for i in range(3, -1, -1):
                         tag += chr((tag_raw >> 8 * i) & 0xFF)
                     if tag in tags.keys():
                         tags[tag].add(caller_name)
                     else:
                         tags[tag] = set([caller_name])
                     break
                 prev = idc.prev_head(prev)
     return True
Exemplo n.º 15
0
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.get_cmt(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
Exemplo n.º 16
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.prev_head(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.get_cmt(prev_instr, False)
        if comment == arg_name:
            return prev_instr
        prev_instr = idc.prev_head(prev_instr,
                                   prev_instr - PREVIOUS_INSTR_DELTA)
    raise ArgumentNotFoundException(
        '  Argument {} not found within threshold'.format(arg_name))
Exemplo n.º 17
0
 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:
             start_ea, end_ea = self.find_start_and_end(eas)
             for string_obj in strs:
                 if string_obj[2] == string and string_obj[0] == start_ea and string_obj[1] == end_ea:
                     break
             else:  # if we didn't break
                 strs.add((start_ea, end_ea, string))
                 old_cmt = idc.get_cmt(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.set_cmt(eas[0], str(new_cmt).strip('\r\n'), 0)
Exemplo n.º 18
0
 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 range(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:
             start_ea, end_ea = self.find_start_and_end(eas)
             for string_obj in strs:
                 if string_obj[2] == string and string_obj[0] == start_ea and string_obj[1] == end_ea:
                     break
             else:  # if we didn't break
                 strs.add((start_ea, end_ea, string))
                 old_cmt = idc.get_cmt(eas[0], 0)
                 old_cmt = "" if not old_cmt else old_cmt
                 if not is_string_ascii(string):
                     new_cmt = string.hex()
                     new_cmt = old_cmt + "\nStack String (hex): " + new_cmt
                 else:
                     new_cmt = string.decode("unicode-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.set_cmt(eas[0], str(new_cmt).strip("\r\n"), 0)
Exemplo n.º 19
0
        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
Exemplo n.º 20
0
def Comment(ea):
    return idc.get_cmt(ea, 0)
Exemplo n.º 21
0
def RptCmt(ea):
    return idc.get_cmt(ea, 1)
Exemplo n.º 22
0
 def cmt_changed(self, ea, repeatable_cmt):
     cmt = idc.get_cmt(ea, repeatable_cmt)
     cmt = '' if not cmt else cmt
     self._send_event(CmtChangedEvent(ea, cmt, repeatable_cmt))
     return 0
Exemplo n.º 23
0
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.get_segm_name(start))
        ea = start
        while ea < idc.get_segm_end(start):
            bbbb = list(struct.unpack("BBBB", idc.get_bytes(ea, 4)))
            for const in non_sparse_consts:
                if bbbb != const["byte_array"][:4]:
                    continue
                if map(lambda x: ord(x),
                       idc.get_bytes(ea, len(
                           const["byte_array"]))) == const["byte_array"]:
                    print(("0x%0" + str(digits) +
                           "X: found const array %s (used in %s)") %
                          (ea, const["name"], const["algorithm"]))
                    idc.set_name(ea, const["name"])
                    if const["size"] == "B":
                        idc.create_byte(ea)
                    elif const["size"] == "L":
                        idc.create_dword(ea)
                    elif const["size"] == "Q":
                        idc.create_qword(ea)
                    idc.make_array(ea, len(const["array"]))
                    ea += len(const["byte_array"]) - 4
                    break
            ea += 4

        ea = start
        if idc.get_segm_attr(ea, idc.SEGATTR_TYPE) == 2:
            while ea < idc.get_segm_end(start):
                d = ida_bytes.get_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 ida_bytes.get_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.get_cmt(idc.prev_head(ea), 0)
                        if cmt:
                            idc.set_cmt(idc.prev_head(ea),
                                        cmt + ' ' + const["name"], 0)
                        else:
                            idc.set_cmt(idc.prev_head(ea), const["name"], 0)
                        ea = tmp
                        break
                ea += 1
    print("[*] finished")
Exemplo n.º 24
0
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.get_segm_name(start))
        ea = start
        while ea < idc.get_segm_end(start):
            bbbb = list(struct.unpack("BBBB", idc.get_bytes(ea, 4)))
            for const in non_sparse_consts:
                if bbbb != const["byte_array"][:4]:
                    continue
                if list(
                        map(lambda x: x if type(x) == int else ord(x),
                            idc.get_bytes(ea, len(
                                const["byte_array"])))) == const["byte_array"]:
                    print(("0x%0" + str(digits) +
                           "X: found const array %s (used in %s)") %
                          (ea, const["name"], const["algorithm"]))
                    idc.set_name(ea, const["name"], ida_name.SN_FORCE)
                    if const["size"] == "B":
                        idc.create_byte(ea)
                    elif const["size"] == "L":
                        idc.create_dword(ea)
                    elif const["size"] == "Q":
                        idc.create_qword(ea)
                    idc.make_array(ea, len(const["array"]))
                    ea += len(const["byte_array"]) - 4
                    break
            ea += 4

        ea = start
        if idc.get_segm_attr(ea, idc.SEGATTR_TYPE) == idc.SEG_CODE:
            while ea < idc.get_segm_end(start):
                d = ida_bytes.get_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 ida_bytes.get_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.get_cmt(idc.prev_head(ea), 0)
                        if cmt:
                            idc.set_cmt(idc.prev_head(ea),
                                        cmt + ' ' + const["name"], 0)
                        else:
                            idc.set_cmt(idc.prev_head(ea), const["name"], 0)
                        ea = tmp
                        break
                ea += 1

    print("[*] searching for crypto constants in immediate operand")
    funcs = idautils.Functions()
    for f in funcs:
        flags = idc.get_func_flags(f)
        if (not flags & (idc.FUNC_LIB | idc.FUNC_THUNK)):
            ea = f
            f_end = idc.get_func_attr(f, idc.FUNCATTR_END)
            while (ea < f_end):
                imm_operands = []
                insn = ida_ua.insn_t()
                ida_ua.decode_insn(insn, ea)
                for i in range(len(insn.ops)):
                    if insn.ops[i].type == ida_ua.o_void:
                        break
                    if insn.ops[i].type == ida_ua.o_imm:
                        imm_operands.append(insn.ops[i].value)
                if len(imm_operands) == 0:
                    ea = idc.find_code(ea, idc.SEARCH_DOWN)
                    continue
                for const in operand_consts:
                    if const["value"] in imm_operands:
                        print(("0x%0" + str(digits) +
                               "X: found immediate operand constants for %s") %
                              (ea, const["algorithm"]))
                        cmt = idc.get_cmt(ea, 0)
                        if cmt:
                            idc.set_cmt(ea, cmt + ' ' + const["name"], 0)
                        else:
                            idc.set_cmt(ea, const["name"], 0)
                        break
                ea = idc.find_code(ea, idc.SEARCH_DOWN)
    print("[*] finished")
Exemplo n.º 25
0
    def check_fmt_function(name, addr):
        """
        Check if the format string argument is not valid
        """
        function_head = idc.get_func_attr(addr, idc.FUNCATTR_START)

        while True:
            addr = idc.prev_head(addr)
            op = idc.print_insn_mnem(addr).lower()
            dst = idc.print_operand(addr, 0)

            if op in ("ret", "retn", "jmp", "b") or addr < function_head:
                return

            c = idc.get_cmt(addr, 0)
            if c and c.lower() == "format":
                break
            elif name.endswith(("snprintf_chk", )):
                if op in ("mov", "lea") and dst.endswith(
                    ("r8", "r8d", "[esp+10h]")):
                    break
            elif name.endswith(("sprintf_chk", )):
                if op in ("mov", "lea") and (dst.endswith(
                    ("rcx", "[esp+0Ch]", "R3")) or dst.endswith("ecx")
                                             and BITS == 64):
                    break
            elif name.endswith(("snprintf", "fnprintf")):
                if op in ("mov", "lea") and (dst.endswith(
                    ("rdx", "[esp+8]", "R2")) or dst.endswith("edx")
                                             and BITS == 64):
                    break
            elif name.endswith(
                ("sprintf", "fprintf", "dprintf", "printf_chk")):
                if op in ("mov", "lea") and (dst.endswith(
                    ("rsi", "[esp+4]", "R1")) or dst.endswith("esi")
                                             and BITS == 64):
                    break
            elif name.endswith("printf"):
                if op in ("mov", "lea") and (dst.endswith(
                    ("rdi", "[esp]", "R0")) or dst.endswith("edi")
                                             and BITS == 64):
                    break

        # format arg found, check its type and value
        # get last oprend
        op_index = idc.generate_disasm_line(addr, 0).count(",")
        op_type = idc.get_operand_type(addr, op_index)
        opnd = idc.print_operand(addr, op_index)

        if op_type == idc.o_reg:
            # format is in register, try to track back and get the source
            _addr = addr
            while True:
                _addr = idc.prev_head(_addr)
                _op = idc.print_insn_mnem(_addr).lower()
                if _op in ("ret", "retn", "jmp", "b") or _addr < function_head:
                    break
                elif _op in ("mov", "lea", "ldr") and idc.print_operand(
                        _addr, 0) == opnd:
                    op_type = idc.get_operand_type(_addr, 1)
                    opnd = idc.print_operand(_addr, 1)
                    addr = _addr
                    break

        if op_type == idc.o_imm or op_type == idc.o_mem:
            # format is a memory address, check if it's in writable segment
            op_addr = idc.get_operand_value(addr, op_index)
            seg = idaapi.getseg(op_addr)
            if seg:
                if not seg.perm & idaapi.SEGPERM_WRITE:
                    # format is in read-only segment
                    return

        print("0x%X: Possible Vulnerability: %s, format = %s" %
              (addr, name, opnd))
        return ["0x%X" % addr, name, opnd]
Exemplo n.º 26
0
 def _findGraftedSegments(self):
     return [
         s for s in SegPlanner()
         if idc.get_cmt(s.start, 1) == g_seg_sig_code_grafter
     ]
Exemplo n.º 27
0
 def getComment(self):
     """
     :return: non-repeatable comment, prioritizes GUI-added comments over API added ones
     """
     return idc.get_cmt(self.ea, 0) or ''
Exemplo n.º 28
0
 def cmd_get_comment(self, addr):
     return idc.get_cmt(int(addr, 0), 0)
Exemplo n.º 29
0
 def get_comment(self, ea):
     idc.get_cmt(ea, False)
Exemplo n.º 30
0
    print("objc2_analyzer_test: TESTING COMMENTS")

    msgSendXrefs = list(
        idautils.XrefsTo(idc.get_name_ea_simple("_objc_msgSend")))
    # IDA gets the xrefs in places we are not interested
    # we rely on objc2_analyzer's new xrefs to help our testing
    if arch == "ARM":
        i = 0
        while i < len(msgSendXrefs):
            if idc.print_insn_mnem(msgSendXrefs[i].frm) != "BLX":
                del (msgSendXrefs[i])
                continue
            i += 1

    for i, x in enumerate(msgSendXrefs):
        cmt = idc.get_cmt(x.frm, False)
        if arch == "ARM":
            if cmt != ARMComments[i]:
                print("objc2_analyzer_test FAILED: incorrect comment @ %016X" %
                      x.frm)
        else:
            if cmt != comments[i]:
                print("objc2_analyzer_test FAILED: incorrect comment @ %016X" %
                      x.frm)

    impAddrs = []
    print("objc2_analyzer_test: TESTING XREFS TO IMPS")
    for imp in imps:
        addr = idc.get_name_ea_simple(imp)
        impAddrs.append(addr)
        if arch == "ARM":
Exemplo n.º 31
0
 def getComment(self, repeatable=False):
     """
     :return: data item comment, prioritizes GUI-added comments over API added ones
     """
     mode = 1 if repeatable else 0
     return idc.get_cmt(self.ea, mode) or ''
Exemplo n.º 32
0
 def cmd_get_comment(self, addr):
     c = idc.get_cmt(int(addr, 0), 0)
     if c:
         return c
     return ""