Ejemplo n.º 1
0
def retrieve_ea_list_set(cond_list):
    """
    Args:
        cond_list: List of conditions to determine the address.

    Returns:
        A list of set of found addresses. Each set of addresses corresponds to a condition.
    """
    found_addr_list_set = []    # List of set of found addresses.

    for cond in cond_list:
        print("{0}".format(cond))
        split_cond = cond.split(':')
        
        if(len(split_cond) != 2):
            print("Condition is malformed. It should be of form <type>:<value> but I am getting {0}".format(split_cond))
            exit(1)

        cond_type = split_cond[0]
        cond_value = split_cond[1]

        curr_addr = idc.get_inf_attr(INF_MIN_EA) # Get start of addr of entire binary
        end_addr = idc.get_inf_attr(INF_MAX_EA) # Get end of addr of entire binary

        cond_found_addr_set = set()
        while(curr_addr < end_addr):
            (result_addr_set, curr_addr) = process_cond(cond_type, cond_value, curr_addr)
            cond_found_addr_set |= result_addr_set
            print("cond_found_addr_set: {0} result_addr_set: {1}".format(cond_found_addr_set, result_addr_set))   

        found_addr_list_set.append(cond_found_addr_set)

    return found_addr_list_set
Ejemplo n.º 2
0
def find_binary_instruction_start(
    search_start_location,
    search_direction,
    target,
    min_location=idc.get_inf_attr(idc.INF_MIN_EA),
    max_location=idc.get_inf_attr(idc.INF_MAX_EA)):
    """
    Description:
        Given a starting location, target, and direction, find an instruction starting with the target bytes.

    Input:
        search_start_location - The EA to start searching at
        search_direction - either idc.SEARCH_UP or idc.SEARCH_DOWN
        target - The target as space separated bytes (i.e. '55' for 'push ebp')
        min_location - The minimum EA to accept results for (default: idc.get_inf_attr(idc.INF_MIN_EA))
        max_location - The maximum EA to accept results for (default: idc.get_inf_attr(idc.INF_MAX_EA))

    Output:
        Returns the first matching location if found, otherwise idc.BADADDR
    """
    target = target.upper()
    while search_start_location < max_location:
        ea = idc.find_binary(search_start_location, search_direction, target)
        if (min_location <= ea < max_location
                and ea == idc.get_item_head(ea) and idc.get_bytes(
                    ea,
                    idc.get_item_size(ea)).encode('hex').upper().startswith(
                        target.replace(' ', ''))):
            return ea
        else:
            search_start_location = ea + (1 if search_direction
                                          == idc.SEARCH_DOWN else -1)
    return idc.BADADDR
Ejemplo n.º 3
0
def is_valid_ea(ea):
    """
    Description:
        Returns true for valid EAs, False for invalid ones.

    Input:
        ea - The EA to check

    Output:
        True if the EA is valid, False if it is not
    """
    return ea not in (None, idc.BADADDR) and idc.get_inf_attr(
        idc.INF_MIN_EA) <= ea <= idc.get_inf_attr(idc.INF_MAX_EA)
Ejemplo n.º 4
0
 def demangle(self, name):
     mask = idc.get_inf_attr(idc.INF_SHORT_DEMNAMES)
     demangled = idc.demangle_name(name, mask)
     if demangled is None:
         return name
     else:
         return demangled
Ejemplo n.º 5
0
    def run(self, arg):
        # 查找需要的函数
        ea, ed = getSegAddr()
        search_result = []
        for func in idautils.Functions(ea, ed):
            try:
                functionName = str(idaapi.ida_funcs.get_func_name(func))
                demangled = idc.demangle_name(functionName,
                                              idc.get_inf_attr(
                                                  idc.INF_SHORT_DN))
                functionName = demangled if demangled else functionName
                if len(list(idautils.FuncItems(func))) > 10:
                    # 如果是thumb模式,地址+1
                    arm_or_thumb = idc.get_sreg(func, "T")
                    if arm_or_thumb:
                        func += 1
                    search_result.append([hex(func), functionName])
            except:
                pass

        so_path, so_name = getSoPathAndName()
        search_result = [f"{so_name}!{a}!{b}" for a, b in search_result]
        search_result = "\n".join(search_result)

        save_path = os.path.join(so_path, so_name.split(".")[0] + ".txt")
        with open(save_path, "w", encoding="utf-8")as F:
            F.write(search_result)

        print("使用方法如下:")
        print(f"frida-trace -UF -z {save_path}")
Ejemplo n.º 6
0
def build_export_table(linlist, winlist):
    instance = (int, long) if version_info[0] < 3 else int
    for i, v in enumerate(linlist):
        if isinstance(v, instance):
            linlist = linlist[:i]  # Skipping thisoffs
            break

    listnode = linlist[:]

    for i, v in enumerate(linlist):
        name = str(v)
        if name.startswith("__cxa"):
            listnode[i] = None
            continue

        s = "L{:<6}".format(i)
        try:
            s += " W{}".format(winlist.index(name))
        except:
            pass

        funcname = idc.demangle_name(name, idc.get_inf_attr(idc.INF_SHORT_DN))
        s = "{:<16} {}".format(s, funcname)
        listnode[i] = s

    return [i for i in listnode if i != None]
Ejemplo n.º 7
0
def write_exact_comp(strdict, funcdict, myfuncs):
	global FOUND_FUNCS
	update_window("Writing exact comparisons")
	count = 0

	for strippedname, strippedlist in get_bcompat_iter(strdict):
		if not ida_funcs.get_func_name(myfuncs[strippedname]).startswith("sub_"):
			continue

		possibilities = []
		strippedlist = sorted(strippedlist)
		for symname, symlist in get_bcompat_iter(funcdict):
			if strippedlist == sorted(symlist):
				possibilities.append(str(symname))
			else:
				continue

			if len(possibilities) >= 2:
				break

		if len(possibilities) != 1:
			continue

		if possibilities[0] not in FOUND_FUNCS and possibilities[0] not in myfuncs:
#			print(ida_funcs.get_func_name(myfuncs[strippedname]))
			idc.set_name(myfuncs[strippedname], possibilities[0], ida_name.SN_FORCE)
			count += 1

			FOUND_FUNCS.add(possibilities[0])
			update_window("Writing exact comparisons")
		elif DEBUG:
			print("{} is probably wrong!".format(idc.demangle_name(possibilities[0], idc.get_inf_attr(idc.INF_SHORT_DN))))

	return count
Ejemplo n.º 8
0
    def demangle_name(self):
        """
            Property which return the demangle name of the function.

            :return str: The demangle name of the function.
        """
        return idc.demangle_name(self.name, idc.get_inf_attr(idc.INF_SHORT_DN))
Ejemplo n.º 9
0
		def update(self, ctx):

			if (idc.get_inf_attr(idc.INF_PROCNAME) != "metapc"):
				return AST_DISABLE

			if (ctx.action == 'klfdb:run'):
				if (idc.get_process_state() == idc.DSTATE_SUSP):
					return AST_ENABLE
				return AST_DISABLE
	
			elif (ctx.action == 'klfdb:runnext'):
				if (idc.get_process_state() == idc.DSTATE_SUSP):
					return AST_ENABLE
				return AST_DISABLE
	
			elif (ctx.action == 'klfdb:delbpts'):
				return AST_ENABLE

			elif (ctx.action == 'klfdb:setbpts'):
				return AST_ENABLE
	
			elif (ctx.action == 'klfdb:ignore'):
				return AST_ENABLE

			elif (ctx.action == 'klfdb:loadmap'):
				return AST_ENABLE

			elif (ctx.action == 'klfdb:delmap'):
				return AST_ENABLE

			return AST_DISABLE
Ejemplo n.º 10
0
    def renamed(self, *args):
        logger.debug("[IDB Hook] Something is renamed")
        ea, new_name, is_local_name = args
        min_ea = idc.get_inf_attr(idc.INF_MIN_EA)
        max_ea = idc.get_inf_attr(idc.INF_MAX_EA)
        if ea >= min_ea and ea <= max_ea:
            if is_local_name:
                logger.warning("Local names are unimplemented")
            else:
                auto = idaapi.has_auto_name(idaapi.get_flags(ea))
                dummy = idaapi.has_dummy_name(idaapi.get_flags(ea))
                if not dummy and not auto:
                    self.skel_conn.push_name(ea, new_name)
        else:
            logger.warning("ea outside program...")

        return ida_idp.IDB_Hooks.renamed(self, *args)
Ejemplo n.º 11
0
    def demangle_name(self):
        """
            Property which return the demangle name of the element.

            :return str: The demangle name of the element or None if there is
                no demangle version of the name.
        """
        return idc.demangle_name(self.name, idc.get_inf_attr(idc.INF_SHORT_DN))
Ejemplo n.º 12
0
    def search_bytes_addr(byt,
                          start_ea=None,
                          end_ea=None,
                          down=True,
                          nxt=True):
        """
            Static method for searching a sequence of bytes. This will search
            for the bytes which ever the data type is.

            This is a wrapper on the ``ida_search.find_binary`` (previously
            ``FindBinary``) function from IDA with a radix of 16.

            The byte should be represented in hexadecimal seperated by space.
            A ``?`` can be put for replacing a byte, for example:
            ``41 8B 44 ? 20``.

            :param byt: A string representing a sequence of byte.
            :param start_ea: The address at which to start the search, if
                ``None`` the current address will be used.
            :param end_ea: The address at which to stop the search, if
                ``None`` the maximum or minimum (depending of searching up or
                down) will be used.
            :param down: If True (the default) search below the given
                address, if False search above.
            :param nxt: If True (the default) the current element will not
                be included in the search.
            :return: The address at which the byte sequence is present or
                ``None`` if no element were found during the search.
        """
        if start_ea is None:
            start_ea = ida_kernwin.get_screen_ea()
        if down:
            fl = ida_search.SEARCH_DOWN
            if end_ea is None:
                end_ea = idc.get_inf_attr(idc.INF_MAX_EA)
        else:
            fl = ida_search.SEARCH_UP
            if end_ea is None:
                end_ea = idc.get_inf_attr(idc.INF_MIN_EA)
        if nxt:
            fl |= ida_search.SEARCH_NEXT
        r = ida_search.find_binary(start_ea, end_ea, byt, 16, fl)
        if r == idc.BADADDR:
            return None
        else:
            return r
Ejemplo n.º 13
0
def vtable_symbol_get_class(symbol):
    """Get the class name for a vtable symbol."""
    try:
        demangled = idc.demangle_name(symbol, idc.get_inf_attr(idc.INF_SHORT_DEMNAMES))
        pre, post = demangled.split("`vtable for'", 1)
        assert pre == ''
        return post
    except:
        return None
Ejemplo n.º 14
0
def get_func_postname(name):
    unmangled = idc.demangle_name(name, idc.get_inf_attr(idc.INF_SHORT_DN))
    if unmangled is None:
        return ""

    if unmangled[:unmangled.find("(")].rfind("::") != -1:
        unmangled = unmangled[unmangled[:unmangled.find("(")].rfind("::") + 2:]

    return unmangled
Ejemplo n.º 15
0
def get_func_argnames(name):
    unmangled = idc.demangle_name(name, idc.get_inf_attr(idc.INF_SHORT_DN))
    if unmangled is None:
        return ""

    if unmangled.find("(") != -1:
        unmangled = unmangled[unmangled.find("("):]

    return unmangled
Ejemplo n.º 16
0
 def __init__(self):
     super(FunctionsPlus, self).__init__()
     if idc.get_inf_attr(idc.INF_PROCNAME).lower() != 'metapc':
         print('Functions+ warning: not tested in this configuration')
     self.tree = None
     self.icon = 135
     # Enable this if you want to see extra information about function
     self.show_extra_fields = False
     self.cols = Cols(self.show_extra_fields)
Ejemplo n.º 17
0
 def name(self):
     name = idc.get_name(self.address)
     if ida_name.is_valid_typename(name):
         return name
     demangled_name = idc.demangle_name(name,
                                        idc.get_inf_attr(idc.INF_SHORT_DN))
     if not demangled_name:
         raise ValueError("Couldn't demangle name: {} at 0x{:x}".format(
             name, self.address))
     return common.demangled_name_to_c_str(demangled_name)
Ejemplo n.º 18
0
    def demangle(cls, name):
        '''
        Demangles name.
        '''

        mask = idc.get_inf_attr(idc.INF_SHORT_DN)
        demangled = idc.demangle_name(name, mask)
        if demangled is None:
            return name
        return demangled
Ejemplo n.º 19
0
 def init(self):
     """
     Init plugin function
     """
     if idc.get_inf_attr(idc.INF_FILETYPE) != idc.FT_PE:
         # skip if it's not a PE
         return idaapi.PLUGIN_SKIP
     ComIDA.log("'%s' loaded. %s activates/deactivates synchronization." %
                (ComIDA.wanted_name, ComIDA.wanted_hotkey))
     return idaapi.PLUGIN_KEEP
Ejemplo n.º 20
0
def _getArgsDescription(ea: int) -> str:
    name = demangle_name(get_func_name(ea), get_inf_attr(INF_SHORT_DN))  # get from mangled name
    if not name:
        name = get_type(ea)  # get from type
        if not name:
            return parse_function_args(ea)  # cannot get params from the mangled name
    args_start = name.find('(')
    if args_start is not None and args_start != (-1):
        return name[args_start:]
    return ""
Ejemplo n.º 21
0
def _getFunctionNameAt(ea: int) -> str:
    name = get_func_name(ea)
    disable_mask = get_inf_attr(INF_SHORT_DN)
    demangled_name = demangle_name(name, disable_mask)
    if demangled_name is None:
        return name
    args_start = demangled_name.find('(')
    if args_start is None:
        return demangled_name
    return demangled_name[:args_start]
Ejemplo n.º 22
0
def mark_string(ea, name=None):
    strlen = len(idc.get_strlit_contents(ea, -1) or '')
    ida_bytes.del_items(
        ea, ida_bytes.DELIT_EXPAND | ida_bytes.DELIT_DELNAMES
        | ida_bytes.DELIT_NOCMT, strlen + 1)
    ida_bytes.create_strlit(ea, strlen + 1, idc.get_inf_attr(idc.INF_STRTYPE))
    if name:
        ida_name.set_name(ea, name, ida_name.SN_CHECK)
    idc.apply_type(ea, idc.parse_decl('char const a[]', 0), idc.TINFO_DEFINITE)
    return get_cstring(ea)
Ejemplo n.º 23
0
    def name(self):
        name = idaapi.get_name(self.addr)
        demangled_name = idc.demangle_name(name,
                                           idc.get_inf_attr(idc.INF_SHORT_DN))
        if demangled_name:
            name = demangled_name_to_c_str(demangled_name)

        if len(name) == 0:
            name = 'func_%X' % (self.addr)

        return name
Ejemplo n.º 24
0
def class_from_vtable_method_symbol(method_symbol):
    """Get the base class in a vtable method symbol.

    Extract the name of the base class from a canonical method symbol.
    """
    demangled = idc.demangle_name(method_symbol, idc.get_inf_attr(idc.INF_SHORT_DN))
    if not demangled:
        return None
    classname = demangled.split('::', 1)[0]
    if classname == demangled:
        return None
    return classname
Ejemplo n.º 25
0
def import_vtable(classname, struc):
    ea = get_vtable(classname)
    if ea == idc.BADADDR:
        return

    # Mildly adapted from Asherkin's vtable dumper
    ea = ea + 8  # Skip typeinfo and thisoffs

    funcs = []
    while ea != idc.BADADDR:
        offs = idc.get_wide_dword(ea)
        if not ida_bytes.is_code(ida_bytes.get_full_flags(offs)):
            break
        name = idc.get_name(offs, ida_name.GN_VISIBLE)
        funcs.append(name)

        ea = ida_bytes.next_not_tail(ea)


#	print(funcs)

    if not len(funcs):
        return

    strucid = add_struc_ex(classname + "_vtbl")
    vstruc = ida_struct.get_struc(strucid)
    for i in funcs:
        # Gotta do a fancy demangle, it can't have special chars
        # and there can't be multiples of the same name, so let's just jazz around all of that
        demangled = idc.demangle_name(i, idc.get_inf_attr(idc.INF_SHORT_DN))
        if demangled == None:
            demangled = i
        else:
            demangled = demangled[demangled.find("::") + 2:demangled.find("(")]
            demangled = demangled.replace("~",
                                          "_").replace("<",
                                                       "_").replace(">", "_")
        while 1:
            error = ida_struct.add_struc_member(vstruc, demangled, idc.BADADDR,
                                                idc.FF_DWORD, None, 4)

            if error == 0:
                break

            demangled += "_{}".format(
                hex(ida_struct.get_struc_last_offset(vstruc) * 4 + 4)[2:])

    # Now assign the vtable to the actual struct
    ti = idaapi.tinfo_t()
    idaapi.parse_decl(ti, None, classname + "_vtbl;", 0)
    ti.create_ptr(ti)
    ida_struct.set_member_tinfo(struc, ida_struct.get_member(struc, 0), 0, ti,
                                0)
Ejemplo n.º 26
0
def import_vtable(typename, funcs):
	typestrucid = add_struc_ex(typename)
	typestruc = ida_struct.get_struc(typestrucid)
	vstrucid = add_struc_ex(typename + "_vtbl")
	vstruc = ida_struct.get_struc(vstrucid)

	loffs = ida_struct.get_struc_last_offset(vstruc)
	if loffs != idc.BADADDR:
		ida_struct.del_struc_members(vstruc, 0, loffs + 4)

	for i in funcs:
		demangled = idc.demangle_name(i, idc.get_inf_attr(idc.INF_SHORT_DN))
		if demangled == None:
			demangled = i
		else:
			demangled = demangled[demangled.find("::")+2:demangled.find("(")]
			# As per https://stackoverflow.com/questions/3411771/best-way-to-replace-multiple-characters-in-a-string
			# this isn't as slow as you'd think
			demangled = demangled\
				.replace("~", "_")\
				.replace("<", "_")\
				.replace(">", "_")\
				.replace(",", "_")\
				.replace("*", "_")\
				.replace(" ", "_")\
				.replace("operator==", "__eq__")\
				.replace("operator+", "__add__")\
				.replace("operator-", "__sub__")\
				.replace("operator*", "__mul__")\
				.replace("operator/", "__div__")\
				.replace("operator%", "__mod__")\
				.replace("operator<<", "__lshift__")\
				.replace("operator>>", "__rshift__")\
				.replace("operator&", "__and__")\
				.replace("operator|", "__or__")\
				.replace("operator^", "__xor__")\
				.replace("operator~", "__invert__")
		while 1:
			error = ida_struct.add_struc_member(vstruc, demangled, idc.BADADDR, idc.FF_DWORD, None, 4)

			if error == 0:
				break

			demangled += "_{}".format(hex(ida_struct.get_struc_last_offset(vstruc) + 4)[2:])

	try:
		ti = idaapi.tinfo_t()
		idaapi.parse_decl(ti, None, typename + "_vtbl;", 0)
		ti.create_ptr(ti)
		ida_struct.add_struc_member(typestruc, "__vftable", 0, idc.FF_DWORD, None, 4)
		ida_struct.set_member_tinfo(typestruc, ida_struct.get_member(typestruc, 0), 0, ti, 0)
	except:
		print("Prevented a terrible, horrible, no good, very bad crash with {}!".format(typename))
Ejemplo n.º 27
0
def method_name(symbol):
    """Get the name of the C++ method from its symbol.

    If the symbol demangles to 'Class::method(args)', this function returns 'method'.
    """
    try:
        demangled  = idc.demangle_name(symbol, idc.get_inf_attr(idc.INF_SHORT_DEMNAMES))
        func       = demangled.split('::', 1)[1]
        base       = func.split('(', 1)[0]
        return base or None
    except:
        return None
Ejemplo n.º 28
0
def method_arguments_string(symbol):
    """Get the arguments string of the C++ method from its symbol.

    If the symbol demangles to 'Class::method(arg1, arg2)', this function returns 'arg1, arg2'.
    """
    try:
        demangled  = idc.demangle_name(symbol, idc.get_inf_attr(idc.INF_LONG_DEMNAMES))
        func       = demangled.split('::', 1)[1]
        args       = func.split('(', 1)[1]
        args       = args.rsplit(')', 1)[0].strip()
        return args
    except:
        return None
Ejemplo n.º 29
0
    def create_segement(segm, offset):
        name = segm.get("name")
        if type(segm.get("start")) != int:
            start = int(segm.get("start"), 16)
            end = int(segm.get("end"), 16)
        else:
            start = segm.get("start")
            end = segm.get("end")
        R = int(segm.get("R"))
        W = int(segm.get("W"))
        X = int(segm.get("X"))
        D = int(segm.get("D"))
        L = int(segm.get("L"))
        align = int(segm.get("align"))
        base = int(segm.get("base"))
        class_ = segm.get("class")
        ad = int(segm.get("ad"))
        T = int(segm.get("T"))
        DS = int(segm.get("DS"))

        idaapi.set_segm_end(start, start, 0)

        if idaapi.is_seg(idc.get_inf_attr(idc.INF_MAX_EA), 0):
            ok = idaapi.add_segm(base, start, 0xFFFFFFFF, name, class_)
        else:
            ok = idaapi.add_segm(base, start, idc.get_inf_attr(idc.INF_MAX_EA),
                                 name, class_)

        if ok:
            idc.set_segm_attr(start, 20, align)
            perm = 0
            if R:
                perm = perm + 4
            if W:
                perm = perm + 2
            if X:
                perm = perm + 1

            idc.set_segm_attr(start, 22, perm)
Ejemplo n.º 30
0
def parse_vtable_name(address):
    name = idaapi.get_name(address)
    if idaapi.is_valid_typename(name):
        if name[0:3] == 'off':
            # off_XXXXXXXX case
            return "Vtable" + name[3:], False
        elif "table" in name:
            return name, True
        print "[Warning] Weird virtual table name -", name
        return "Vtable_" + name, False
    name = idc.demangle_name(idaapi.get_name(address),
                             idc.get_inf_attr(idc.INF_SHORT_DN))
    assert name, "Virtual table must have either legal c-type name or mangled name"
    return common.demangled_name_to_c_str(name), True