Beispiel #1
0
 def processIMethods(self, offst, size):
     sz = ida_struct.get_struc_size(ida_struct.get_struc_id("imethod"))
     comm = []
     for i in xrange(size):
         comm.append(self.processIMethod(offst + i * sz))
     idc.set_cmt(offst, "\n".join(comm), 0)
     return comm
Beispiel #2
0
    def rename(self, name=None):
        """
        Renames (and comments) the string variable in IDA.

        :param str name: New name to given encoded string. (defaults to decoded_string)
        """
        name = name or self.display_name
        if not name:
            logger.warning(
                'Unable to rename encoded string due to no decoded string: {!r}'.format(self))

        # Set name and comment in stack variable.
        comment = '"{}"'.format(name[:self._MAX_COMMENT_LENGTH])
        if len(name) > self._MAX_COMMENT_LENGTH:
            comment += ' (truncated)'
        if self.frame_id and self.stack_offset:
            idc.set_member_cmt(self.frame_id, self.stack_offset, comment, repeatable=1)
            var_name = re.sub('[^_$?@0-9A-Za-z]', '_', name[:self._MAX_NAME_LENGTH])  # Replace invalid characters
            if not var_name:
                raise ValueError('Unable to calculate var_name for : {!r}'.format(self))
            var_name = 'a' + var_name.capitalize()
            idc.set_member_name(self.frame_id, self.stack_offset, var_name)

        # Add a comment where the string is being used.
        if self.string_reference:
            idc.set_cmt(self.string_reference, comment, 1)
def resolve_all_APIs(resolve_ea, mode):
    if resolve_ea is None:
        print('resolve fails..')
        return

    for ref in idautils.CodeRefsTo(resolve_ea, 1):
        # only 1 ref

        curr_ea = ref
        while True:
            prev_instruction_ea = idc.prev_head(curr_ea)
            if mode == 1:
                if idc.print_insn_mnem(prev_instruction_ea) == 'push':
                    hash_val = idc.get_operand_value(prev_instruction_ea, 0)
                    if hash_val in export_hashes:
                        print(hex(ref) + ' : ' + export_hashes[hash_val])
                        idc.set_cmt(ref, export_hashes[hash_val], 0)
                    break
            else:
                if idc.print_insn_mnem(prev_instruction_ea) == 'mov':
                    hash_val = idc.get_operand_value(prev_instruction_ea, 1)
                    print(hex(hash_val))
                    if hash_val in export_hashes:
                        print(hex(ref) + ' : ' + export_hashes[hash_val])
                        idc.set_cmt(ref, export_hashes[hash_val], 0)
                    break
            curr_ea = prev_instruction_ea
Beispiel #4
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)
Beispiel #5
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)
Beispiel #6
0
def add_arg_descr(function, segment_ea, arg_description_format):
    """ Name address in added segment annotated with argument descriptions.

    Arguments:
    function -- function object
    segment_ea -- start looking for empty byte to annotate from this ea

    Return:
    next possible free address to add information to
    """
    # No arguments
    if len(function.arguments) == 0:
        return segment_ea
    for argument in function.arguments:
        try:
            free_ea = get_segment_end_ea(segment_ea)
        except FailedToExpandSegmentException as e:
            raise e

        fields = {
            "function_name": function.name,
            "function_dll": function.dll,
            "argument_name": argument.name,
        }
        name = arg_description_format.format(**fields)
        if not name_exists(name):
            g_logger.debug(' Adding name {} at {}'.format(name, hex(free_ea)))
            idaapi.set_name(free_ea, name)
            description = argument.description[:MAX_ARG_DESCR_LEN]
            idc.set_cmt(free_ea, format_comment(description), 0)
        else:
            g_logger.debug(' Name %s already exists' % name)
    return (free_ea + 1)
Beispiel #7
0
 def markupLine(self, loc, sym):
     comm = '%s!%s' % (sym.libName, sym.symbolName)
     logger.debug("Making comment @ 0x%08x: %s", loc, comm)
     if using_ida7api:
         idc.set_cmt(loc, str(comm), False)
     else:
         idc.MakeComm(loc, str(comm))
Beispiel #8
0
	def set_jit_info(self, method_id, start):

		end = self.get_func_end(start)

		if (end < start or end - start > self.jit_max_size):
			return

		method = next((x for x in self.as3dump if x["id"] == method_id), None)

		if (method is None):
			return

		stackvars = self.get_stack_vars(start, end)
		save_eip = self.get_save_eip(method, stackvars)

		ea = start
		while (ea < end):
	
			if ("ebp" in idc.print_operand(ea, 0) and idc.get_operand_type(ea, 1) == idc.o_imm):
	
				op0 = idc.get_operand_value(ea, 0)
				op1 = idc.get_operand_value(ea, 1)
	
				if (op0 == save_eip):
					idc.set_cmt(ea, method["instructions"][op1], 0)
		
			ea += idc.get_item_size(ea)
Beispiel #9
0
    def process(self, nids, symbols):

        if self.INFO > Relocation.R_X86_64_ORBIS_GOTPCREL_LOAD:
            self.INDEX = self.INFO >> 32
            self.INFO &= 0xFF
            symbol = next(value for key, value in enumerate(symbols)
                          if key + 2 == self.INDEX)[1]
        else:
            self.INDEX = 0

        # String (Offset) == Base + AddEnd (B + A)
        if self.type() == 'R_X86_64_RELATIVE':
            idaapi.put_qword(self.OFFSET, self.ADDEND)
            idaapi.create_data(self.OFFSET, FF_QWORD, 0x8, BADNODE)

        # Object
        if self.type() in [
                'R_X86_64_64', 'R_X86_64_GLOB_DAT', 'R_X86_64_DTPMOD64',
                'R_X86_64_DTPOFF64'
        ]:

            # Resolve the NID...
            idc.set_cmt(self.OFFSET, 'NID: ' + symbol, False)
            object = nids.get(symbol[:11], symbol)

            # Rename the Object...
            idc.set_name(self.OFFSET, object,
                         SN_NOCHECK | SN_NOWARN | SN_FORCE)

        return self.type()
Beispiel #10
0
    def resolve_symbols(self, dll):
        tmpdir = tempfile.gettempdir().replace('\\', '/') + '/'
        # File who will first contain ordinals then symbols
        tmpfile = tmpdir + "dotNIETsymbols.txt"
        tmplog = tmpdir + "dotNIETlogs.txt"
        # Destination path for a copy of SharedLibrary.dll
        tmpdll = tmpdir + os.path.basename(dll)
        # Path to the idat binary, needed to parse a remote idb
        idat = idc.idadir().replace('\\','/') + '/' + 'idat' + \
               ['64' if utils.is_x64(dll) else ''][0]

        if os.getenv("windir") is not None:
            idat += '.exe'
        # script called along with idat in order to parse SharedLibrary.idb
        parsing_script_path = '"' + os.path.dirname(os.path.realpath(__file__)).replace('\\','/')\
                              + '/dotNIET/resolve.py"'

        # we first copy SharedLibrary.dll to tmp to be sure we are in a
        # writable location
        shutil.copyfile(dll, tmpdll)

        # we have to use temporary files because of the ida headless stuff...
        # pretty dirty
        ordinals = []
        with open(tmpfile, 'w') as f:
            for i in range(self.nb_symbols):
                ordinals.append((idaapi.get_qword(self.ordinals + i * 8)
                                 & ~0x8000000000000000) * 4)
            f.write(",".join([str(x) for x in ordinals]))

        # be prepared to wait as this will load the binary + pdb
        idaapi.msg("Starting parsing of %d symbols...\n" % self.nb_symbols)
        subprocess.run([idat, "-L" + tmplog, "-c", "-A", "-S" + \
                        parsing_script_path + " " + tmpfile, tmpdll],
                        creationflags=subprocess.CREATE_NO_WINDOW,
                        check=True)

        # we read back tmpfile which now contains symbols
        symbols = []
        with open(tmpfile, 'r') as f:
            symbolsArray = f.read()
            symbols = symbolsArray.split(',')

        # we first have to undef structure as it is an array and ida will
        # refuse to set names within it
        idc.del_items(self.ordinals)
        idc.set_cmt(self.ordinals - 8, "Custom imports from SharedLibrary.dll",
                    0)
        # we then apply the symbols at this very same location (start of .idata)
        for i in range(self.nb_symbols):
            idc.set_name(self.ordinals + i * 8, symbols[i],
                         SN_NOCHECK | SN_FORCE | SN_NODUMMY)

        # finally we remove our temp files
        os.remove(tmpfile)
        os.remove(tmpdll)
        # ida generate a db
        os.remove(tmpdll + '.i64')
        # if everything went smoothly, we should not need this anymore
        os.remove(tmplog)
Beispiel #11
0
def import_objects(objs, add_names=True, always_thumb=True):
    """
    Create IDA function and data according to symbol definitions.
    Create name if add_name is True

    :param add_names: Create name for symbols?

    """

    failed_objs = []
    for name, size, addr, _ in objs:
        if not is_data_start(addr):
            if size:
                ok = idaapi.create_data(addr, idc.FF_BYTE, size, 0)
            else:
                ok = idc.create_byte(addr)
            if not ok:
                reason = "Could not create data at {addr:#x}".format(addr=addr)
                data = (name, size, addr)
                failed_objs.append((data, reason))
                """continue"""
        idc.set_cmt(addr, "obj.%s" % name, 0)
        if add_names:
            ok = idc.set_name(addr, name, idc.SN_CHECK)
            if not ok:
                reason = "Could not add name {name} at {addr:#x}".format(
                    name=name, addr=addr)
                data = (name, size, addr)
                failed_objs.append((data, reason))
    print("waiting for ida to finish analysis")
    ida_auto.auto_wait()
    print("ida finished import")
    return failed_objs
def decryptor(index, call_addr):
    decrypted_string = ""
    current_struct_start = struct_start + 8 * index
    current_struct_bytes = idc.get_bytes(current_struct_start, 8)
    print(current_struct_bytes.hex())
    #structure parsing and xoring
    key = int.from_bytes(current_struct_bytes[0:1],
                         byteorder='little',
                         signed=False)
    length = int.from_bytes(current_struct_bytes[2:4],
                            byteorder='little',
                            signed=False)
    buffer_string_addr = int.from_bytes(current_struct_bytes[4:8],
                                        byteorder='little',
                                        signed=False)
    print(hex(key), hex(length), hex(buffer_string_addr))
    #decrypting
    for i in range(0, length):
        decrypted_string += chr(key
                                ^ idc.get_wide_byte(buffer_string_addr + i))
    print(decrypted_string)
    #commenting assembly view
    idc.set_cmt(call_addr, decrypted_string, 0)
    #commenting decompile view on the same address as assembly view
    cfunc = idaapi.decompile(call_addr)
    tl = idaapi.treeloc_t()
    tl.ea = call_addr
    tl.itp = idaapi.ITP_SEMI
    cfunc.set_user_cmt(tl, decrypted_string)
    cfunc.save_user_cmts()
Beispiel #13
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)
Beispiel #14
0
def treat_element():
    "Display an element"
    global graphs, comments, sol_nb, settings, addr, ir_arch, ircfg

    try:
        graph = next(graphs)
    except StopIteration:
        comments = {}
        print("Done: %d solutions" % (sol_nb))
        return

    sol_nb += 1
    print("Get graph number %02d" % sol_nb)
    filename = os.path.join(tempfile.gettempdir(), "solution_0x%08x_%02d.dot" % (addr, sol_nb))
    print("Dump the graph to %s" % filename)
    open(filename, "w").write(graph.graph.dot())

    for node in graph.relevant_nodes:
        try:
            offset = ircfg.blocks[node.loc_key][node.line_nb].instr.offset
        except IndexError:
            print("Unable to highlight %s" % node)
            continue
        comments[offset] = comments.get(offset, []) + [node.element]
        idc.set_color(offset, idc.CIC_ITEM, settings.color)

    if graph.has_loop:
        print('Graph has dependency loop: symbolic execution is inexact')
    else:
        print("Possible value: %s" % next(iter(viewvalues(graph.emul(ir_arch)))))

    for offset, elements in viewitems(comments):
        idc.set_cmt(offset, ", ".join(map(str, elements)), 0)
Beispiel #15
0
def clean_lines():
    "Remove previous comments"
    global comments
    for offset in comments:
        idc.set_color(offset, idc.CIC_ITEM, 0xffffff)
        idc.set_cmt(offset, "", 0)
    comments = {}
Beispiel #16
0
    def handle_offset(self, offset):
        #Check if we already parse this
        if offset in self.type_addr:
            return
        print ("Processing: %x" % offset)
        self.type_addr.append(offset)

        #Set type and get name
        idc.SetType(offset, "type")
        name = self.getName(offset)
        idc.set_cmt(offset, name, 0)

        #get kind name
        kind_name = self.getKindEnumName(offset)
        print (kind_name)
        if name[0] == "*" and kind_name != "PTR":
            name = name[1:]
        name = Utils.relaxName(name)
        Utils.rename(offset, name)
        self.betterTypePlease(offset)
        sid = ida_struct.get_struc_id("type")
        addr = self.getPtrToThis(sid, offset)
        if addr != 0:
            addr = self.getOffset(addr)
            self.handle_offset(addr)
        return
        if kind_name != "FUNC":
            self.processUncommon(sid, offset)
Beispiel #17
0
 def add_stub_func(va, sc, nm):
     idaapi.patch_bytes(va, binascii.unhexlify(sc))
     idc.create_insn(va)
     idc.add_func(va)
     mykutils.makename_safe(va, self._stubname(nm))
     cmt = ('%s implementation generated by FLARE Code Grafter' % (nm))
     idc.set_cmt(va, cmt, 1)
Beispiel #18
0
def references(function_location, decoding_str):
    """decodes all decoded strings by a given function by applying decoding_str
       to every byte.
       decoding_str should contain encoded_byte, for example:
       decode.references(0x401000, "(encoded_byte ^ 0xA2) + 0x21")"""
    for xref in idautils.XrefsTo(function_location):
        ea = xref.frm
        # The function needs to be defined for get_arg_addrs to work
        args = idaapi.get_arg_addrs(ea)
        encoded = idc.get_operand_value(args[0], 0)
        decoded = idc.get_operand_value(args[1], 0)

        decoded_str = ""
        i = 0
        encoded_byte = ida_bytes.get_wide_byte(encoded)
        while encoded_byte != 0:
            decoded_byte = eval(decoding_str)
            decoded_str += chr(decoded_byte)
            ida_bytes.patch_byte(decoded + i, decoded_byte)
            i += 1
            encoded_byte = ida_bytes.get_wide_byte(encoded + i)

        ida_bytes.create_strlit(decoded, i, STRTYPE_C)
        idc.set_cmt(ea, f"Decoded: {decoded_str}", 0)
        print(f"##At {hex(ea)} decoded: {decoded_str}")
Beispiel #19
0
 def createUserTypeStruct(self, addr, name, size, self_size):
     fields = []
     sid = ida_struct.get_struc_id("structField")
     sz = ida_struct.get_struc_size(sid)
     sid_type = ida_struct.get_struc_id("type")
     fields = []
     curr_offset = 0
     idc.set_cmt(addr, name, 0)
     for i in range(size):
         fieldname = self.nameFromOffset(self.getPtr(sid, addr+i*sz,"Name"))
         type_addr = self.getPtr(sid, addr+i*sz, "typ")
         typename = self.getType(type_addr)
         size = self.getPtr(sid_type, type_addr, "size")
         if fieldname == "" or fieldname is None:
             fieldname = "unused_"+Utils.id_generator()
         offset = self.getStructFieldOffset(sid, addr+i*sz)
         print(f"Get offset: {offset:x}")
         if offset != curr_offset:
             print("Offset missmatch.Got %d expected %d. Adding padding..." % (curr_offset, offset))
             if offset < curr_offset:
                 raise("Too many bytes already")
             while offset != curr_offset:
                 fields.append(("padding", "char"))
                 curr_offset += 1
         curr_offset += size
         if size != 0:
             offset_kind = idc.get_member_offset(sid_type, "kind")
             kind_of_type = self.getKindEnumName(type_addr)
             print(kind_of_type)
             if kind_of_type == "STRUCT_": #Disabled for now
                 name_type = self.getName(type_addr)
                 while name_type[0] == "*":
                     name_type = name_type[1:]
                 name_type = Utils.relaxName(name_type)
                 name_type = "ut_" + name_type
                 #print("setting type %s" % name_type)
                 fields.append((fieldname, name_type))
             elif kind_of_type == "STRING":
                 fields.append((fieldname, "string"))
             elif kind_of_type == "SLICE":
                 fields.append((fieldname, "slice"))
             elif kind_of_type == "INTERFACE":
                 fields.append((fieldname, "__iface"))
             else:
                 fields.append((fieldname, "char [%d]" % size))
     if curr_offset != self_size:
         print("%x: Structure size mismatch: %x" % (addr, curr_offset))
         if self_size < curr_offset:
                 raise("Too many bytes already")
         while self_size != curr_offset:
             fields.append(("padding", "char"))
             curr_offset += 1    
     new_type = [(name, fields)]
     self.settings.structCreator.createTypes(new_type)
     new_type_sid = ida_struct.get_struc_id(name)
     sz = ida_struct.get_struc_size(new_type_sid)
     if sz != self_size:
         print("%x" % addr   )
         raise("Error at creating structure")
Beispiel #20
0
def enum_arg(call_addr):
    idc.set_color(call_addr, CIC_ITEM, 0x00ff00)
    arg = []
    for arg_addr in idaapi.get_arg_addrs(call_addr):
        idc.set_cmt(arg_addr, "addr: 0x%x" % (call_addr), 0)
        idc.set_color(arg_addr, CIC_ITEM, 0x00fff0)
        arg.append(find_arg(arg_addr))
    return arg
 def markupLine(self, loc, sym, useDecompiler=False):
     comm = '%s!%s' % (sym.libName, sym.symbolName)
     logger.debug("Making comment @ 0x%08x: %s", loc, comm)
     if using_ida7api:
         idc.set_cmt(loc, str(comm), False)
         if useDecompiler and idaapi.get_func(loc) != None:
             self.addDecompilerComment(loc, str(comm))
     else:
         idc.MakeComm(loc, str(comm))
Beispiel #22
0
def rename_argument(ea, function, argument, arg_description_format):
    """ Rename function's argument comment at ea based on config string. """
    fields = {
        "function_name": function.name,
        "function_dll": function.dll,
        "argument_name": argument.name,
    }
    new_arg = str(arg_description_format.format(**fields).encode('utf-8'))
    idc.set_cmt(ea, new_arg, 0)
Beispiel #23
0
    def dump_names(list_of_vtbl):
        f = open('classes_rtii_autonaming_subs.txt', 'w+')
        for cls in list_of_vtbl:
            for n, a in cls.functions.items():
                idc.set_cmt(a, cls.base_name, 0)

            print(cls.base_name)
            f.write(cls.base_name + "\n")
        f.close()
Beispiel #24
0
    def resolve(self, alphabet, nids, symbols, libraries):

        if self.INFO > Relocation.R_X86_64_ORBIS_GOTPCREL_LOAD:
            self.INDEX = self.INFO >> 32
            self.INFO &= 0xFF
            symbol = next(value for key, value in enumerate(symbols)
                          if key + 2 == self.INDEX)[1]
        else:
            self.INDEX = 0

        # Library
        try:
            lid1 = alphabet[symbol[12:13]]

            # [base64]#
            if symbol[13:14] == '#':
                library = libraries[lid1]

            # [base64][base64]#
            elif symbol[14:15] == '#':
                lid2 = alphabet[symbol[13:14]]
                library = libraries[lid1 + lid2]

            else:
                raise

        # Not a NID
        except:
            library = ''

        # Function Name (Offset) == Symbol Value + AddEnd (S + A)
        # Library Name  (Offset) == Symbol Value (S)
        # Resolve the NID...
        idc.set_cmt(idc.get_qword(self.OFFSET) - 0x6, 'NID: ' + symbol, False)
        function = nids.get(symbol[:11], symbol)

        # Rename the Jump Function...
        idc.set_name(self.OFFSET, '__imp_' + function,
                     SN_NOCHECK | SN_NOWARN | SN_FORCE)

        # Rename the Real Function...
        idc.add_func(idc.get_qword(self.OFFSET) - 0x6)
        idc.set_name(
            idc.get_qword(self.OFFSET) - 0x6, function, SN_NOCHECK | SN_NOWARN)

        try:
            import_node = idaapi.netnode(library, 0, True)
            import_node.supset(ea2node(self.OFFSET), function)

            # Requires customized loader.i / ida_loader.py(d)
            idaapi.import_module(library, None, import_node.index(), None,
                                 'linux')

        except:
            pass

        return self.type()
Beispiel #25
0
    def comment(self, value):
        """
            Setter which allow to set the value of the comment.

            :param value: The comment to set
            :type value: :class:`str`
        """
        if value is None:
            value = ""
        idc.set_cmt(self.ea, value, 0)
 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)
Beispiel #28
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")
Beispiel #29
0
def Chendo(address, members):

    for (size, name) in members:
        flags = idaapi.get_flags_by_size(size)
        idaapi.do_unknown_range(address, size, 0)

        if name == '':
            idc.make_array(address, size)
        else:
            idaapi.create_data(address, flags, size, BADNODE)

        idc.set_cmt(address, name, False)
        address += size
Beispiel #30
0
def get_stacked_bytes(dec_func_addr):
    func_stacked_bytes_addr_dict = {}
    xrefs = idautils.CodeRefsTo(dec_func_addr, 0)

    for xref in xrefs:
        prev_addr = idc.prev_head(xref)
        prev_addr_2 = idc.prev_head(prev_addr)

        if idc.print_insn_mnem(prev_addr_2) == "call":
            func_name = idc.print_operand(prev_addr_2, 0)
            func_addr = idc.get_name_ea_simple(func_name)
            func_stacked_bytes_addr_dict[xref] = func_addr

    # enc_mod_addr = list(set(enc_mod_addr)) # [Debug] Get unique functions only

    for xref, stacked_bytes_addr in func_stacked_bytes_addr_dict.items():
        print(f"Address: {hex(stacked_bytes_addr)}")
        func_ea = idc.get_func_attr(stacked_bytes_addr, idc.FUNCATTR_START)
        bytes_collected = bytearray()  # Collected stack string store here

        for ins in idautils.FuncItems(func_ea):
            if ida_bytes.is_code(ida_bytes.get_full_flags(ins)):
                if idc.print_insn_mnem(ins) == "mov":
                    if idc.get_operand_type(ins, 1) == idc.o_imm:
                        # disasm = idc.GetDisasm(ins) # [Debug]
                        hex_str_len = len(
                            idc.print_operand(ins, 1).lstrip("0").rstrip("h"))
                        const_hex_byte = idc.print_operand(
                            ins, 1).lstrip("0").rstrip("h")

                        if hex_str_len != 8:  # Skip if const hex byte less than 8
                            append_zero = "0" * (8 - hex_str_len)
                            const_hex_byte = append_zero + const_hex_byte
                            # print(struct.pack("<I", int(const_hex_byte, 16))) # [Debug]

                        # else:
                        # print(struct.pack("<I", int(const_hex_byte, 16))) # [Debug]
                        bytes_collected += struct.pack("<I",
                                                       int(const_hex_byte, 16))

        if len(bytes_collected) >= 1:
            cmt_str = ""
            if dec_func_addr == 0x10001253:  # fn_name_addr
                print(f"{decode_fnname(bytes_collected[4:])}")
                cmt_str = decode_fnname(bytes_collected[4:])
            elif dec_func_addr == 0x1000122B:  # mod_name_addr
                print(f"{decode_modname(bytes_collected[4:])}")
                cmt_str = decode_modname(bytes_collected[4:])
            idc.set_cmt(xref, cmt_str, 1)  # Comment near xref decoder function
        else:
            print(f"[-] {hex(stacked_bytes_addr)} addr error")
Beispiel #31
0
 def make_comments(self):
     """make comments in idb"""
     EFI_BOOT_SERVICES_ID = idc.get_struc_id("EFI_BOOT_SERVICES")
     self.get_boot_services()
     empty = True
     for service in self.gBServices:
         for address in self.gBServices[service]:
             message = f"EFI_BOOT_SERVICES->{service}"
             idc.set_cmt(address, message, 0)
             idc.op_stroff(address, 0, EFI_BOOT_SERVICES_ID, 0)
             empty = False
             print(f"[ {address:016X} ] {message}")
     if empty:
         print(" * list is empty")
Beispiel #32
0
def main(doAllFuncs=True):
    #doAllFuncs=False
    #jayutils.configLogger(__name__, logging.DEBUG)
    jayutils.configLogger(__name__, logging.INFO)
    logger = jayutils.getLogger('stackstrings')
    logger.debug('Starting up now')
    filePath = jayutils.getInputFilepath()
    if filePath is None:
        self.logger.info('No input file provided. Stopping')
        return
    vw = jayutils.loadWorkspace(filePath)
    ea = idc.here()
    res = -1
    if using_ida7api:
        res = idc.ask_yn(0, 'Use basic-block local aggregator')
    else:
        res = idc.AskYN(0, 'Use basic-block local aggregator')
    if res == idaapi.ASKBTN_CANCEL:
        print 'User canceled'
        return
    uselocalagg = (res == 1)
    ranges = getFuncRanges(ea, doAllFuncs)
    for funcStart, funcEnd in ranges:
        try:
            logger.debug('Starting on function: 0x%x', funcStart)
            stringList = runStrings(vw, funcStart, uselocalagg)    
            for node, string in stringList:
                if isLikelyFalsePositiveString(string):
                    #if it's very likely a FP, skip annotating
                    continue
                print '0x%08x: %s' % (node[0], string)
                #print '0x%08x: 0x%08x: %s %s' % (node[0], node[1], binascii.hexlify(string), string)
                if using_ida7api:
                    idc.set_cmt(node[0], string.strip(), 0)
                else:
                    idc.MakeComm(node[0], string.strip())
        except Exception, err:
            logger.exception('Error during parse: %s', str(err))
Beispiel #33
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)