示例#1
0
def is_code_ea(ea):
    if idaapi.cvar.inf.procname == "ARM":
        # In case of ARM code in THUMB mode we sometimes get pointers with thumb bit set
        flags = idaapi.get_full_flags(ea & -2)  # flags_t
    else:
        flags = idaapi.get_full_flags(ea)
    return idaapi.is_code(flags)
示例#2
0
文件: utils.py 项目: Midi12/SusanRTTI
 def ForceQword(self, ea):
     if ea != BADADDR and ea != 0:
         if not isQwrd(get_full_flags(ea)):
             MakeUnknown(ea, 8, DOUNK_SIMPLE)
             MakeQword(ea)
         if isOff0(get_full_flags(ea)) and GetFixupTgtType(ea) == -1:
             # remove the offset
             OpHex(ea, 0)
示例#3
0
def ArrayItems(*args):
    """
    Enumerate array items

    @param ea:    address of the array you want the items enumerated, defaults to here()

    @return: list of each item in the array.

    Example::

        for ea in ArrayItems():
           pname= GetString(Dword(ea))
           MakeName(Dword(ea+4)&~1, "task_%s" % pname)
           MakeName(Dword(ea+8), "taskinfo_%s" % pame)
           MakeName(Dword(ea+12), "stack_%s" % pame)


    Assuming the cursor is on an array of structs, in which the
    first struct item points to a name, this will name the other
    items in the struct.
    """
    ea = args[0] if len(args) > 0 else idc.here()

    s = idc.ItemSize(ea)
    ss = idaapi.get_data_elsize(ea, idaapi.get_full_flags(ea))

    n = s / ss

    for i in xrange(n):
        yield ea + i * ss
示例#4
0
def Code(*args):
    """
    Enumerate code bytes

    @param <range>: see getrange

    @return: list of addresses of code bytes

    Example::

        for ea in Code():
            MakeUnkn(ea, DOUNK_EXPAND)
            Wait()

    Will delete all code in the selected area.


        len(list(MakeUnkn(ea, DOUNK_EXPAND) and Wait() for ea in enumerators.Code(idaapi.getseg(here()))))

    will delete all code in the current segment, and can be pasted in the command area of ida

    """
    (first, last) = getrange(args)

    ea = first
    # explicitly testing first byte, since find_code
    # implicitly sets SEARCH_NEXT flag
    if ea < last and not idaapi.is_code(idaapi.get_full_flags(ea)):
        ea = idaapi.find_code(ea, idaapi.SEARCH_DOWN)
    while ea != idaapi.BADADDR and ea < last:
        yield ea
        ea = idaapi.find_code(ea, idaapi.SEARCH_DOWN)
示例#5
0
def Undefs(*args):
    """
    Enumerate undefined bytes

    @param <range>: see getrange

    @return: list of addresses of undefined bytes

    Example::

        for ea in Undefs((FirstSeg(), BADADDR)):
            if isCode(GetFlags(PrevHead(ea))) and (ea%4)!=0 and iszero(ea, 4-(ea%4)):
                MakeAlign(ea, 4-(ea%4), 2)

    Will add alignment directives after code.
    """
    (first, last) = getrange(args)

    ea = first
    # explicitly testing first byte, since find_unknown
    # implicitly sets SEARCH_NEXT flag
    if ea < last and not ida_bytes.is_unknown(idaapi.get_full_flags(ea)):
        ea = idaapi.find_unknown(ea, idaapi.SEARCH_DOWN)
    while ea != idaapi.BADADDR and ea < last:
        yield ea
        ea = idaapi.find_unknown(ea, idaapi.SEARCH_DOWN)
示例#6
0
文件: utils.py 项目: Midi12/SusanRTTI
 def isVtable(self, addr):
     function = self.get_ptr(addr)
     # Check if vtable has ref and its first pointer lies within code segment
     if f_has_xref(
             get_full_flags(addr)
     ) and function >= self.text.start_ea and function <= self.text.end_ea:
         return True
     return False
示例#7
0
文件: utils.py 项目: Midi12/SusanRTTI
 def xref_or_find(self, addr, allow_many=False):
     lrefs = list(DataRefsTo(addr))
     if len(lrefs) == 0:
         lrefs = list(idautils.refs(addr, self.ptrfirst, self.ptrnext))
     if len(lrefs) > 1 and not allow_many:
         print("too many xrefs to %08X" % addr)
         return []
     lrefs = [r for r in lrefs if not isCode(get_full_flags(r))]
     return lrefs
示例#8
0
def findend(ea):
    ea0 = ea
    while True:
        ea = idc.NextAddr(ea)
        if XrefsTo(ea):
            break
        if idaapi.get_full_flags(ea) & idc.FF_ANYNAME:
            break
    return ea - ea0
示例#9
0
文件: utils.py 项目: Midi12/SusanRTTI
 def ForcePtr(self, ea, delta=0):
     if self.x64:
         self.ForceQword(ea)
     else:
         self.ForceDword(ea)
     if GetFixupTgtType(ea) != -1 and isOff0(get_full_flags(ea)):
         # don't touch fixups
         return
     pv = self.get_ptr(ea)
     if pv != 0 and pv != BADADDR:
         # apply offset again
         if idaapi.is_spec_ea(pv):
             delta = 0
         OpOffEx(ea, 0, [REF_OFF32, REF_OFF64][self.x64], -1, 0, delta)
示例#10
0
def locate_functions(segm):
    ss = find_probable_string_start(segm)
    print("[+] Strings = %s" % ss)
    for i in ["7F 23 03 D5", "BD A9", "BF A9"]:
        ea = segm.start_ea
        while ea != BADADDR:
            ea = ida_search.find_binary(ea, segm.end_ea, i, 16,
                                        ida_search.SEARCH_DOWN)
            if ea != BADADDR and ea <= ss:
                ea -= 2

                if (ea % 4) == 0 and idaapi.get_full_flags(ea) < 0x200:
                    # print("[+] Defining a function at 0x%x" % (ea))
                    ida_funcs.add_func(ea)

                ea += 4
示例#11
0
def Heads(*args):
    """
    Enumerate array items

    @param <range>: see getrange

    @return: list of all heads

    """
    (first, last) = getrange(args)

    ea = first
    if ea < last and not idaapi.is_head(idaapi.get_full_flags(ea)):
        ea = idaapi.next_head(ea, last)
    while ea != BADADDR and ea < last:
        yield ea
        ea = idaapi.next_head(ea, last)
示例#12
0
def NotTails(*args):
    """
    Enumerate array items

    @param <range>: see getrange

    @return: list of all not-tails

    Note that NotTails includes all Heads plus all undefined bytes

    """
    (first, last) = getrange(args)

    ea = first
    if ea < last and idaapi.is_tail(idaapi.get_full_flags(ea)):
        ea = idaapi.next_not_tail(ea)
    while ea != BADADDR and ea < last:
        yield ea
        ea = idaapi.next_not_tail(ea)
示例#13
0
def NonFuncs(*args):
    """
    Enumerate code which is not in a function

    @param <range>: see getrange

    @return: list of addresses containing code, but not in a function

    Example::

        for ea in NonFuncs((FirstSeg(), BADADDR)):
            if not MakeFunction(ea):
                Jump(ea)
                break
            Wait()

    Will try to change non-function code to function
    until MakeFunction fails
    """

    (first, last) = getrange(args)

    ea = first
    while ea != idaapi.BADADDR and ea < last:
        nextcode = idaapi.find_code(ea,
                                    idaapi.SEARCH_NEXT | idaapi.SEARCH_DOWN)
        thischunk = idaapi.get_fchunk(ea)
        nextchunk = idaapi.get_next_fchunk(ea)
        if thischunk:
            ea = thischunk.end_ea
        elif idaapi.is_code(idaapi.get_full_flags(ea)):
            yield ea
            ea = idaapi.next_head(ea, last)
        elif nextchunk is None:
            return
        elif nextcode < nextchunk.start_ea:
            yield nextcode
            ea = nextcode
        else:
            ea = nextchunk.end_ea
示例#14
0
def BytesThat(*args):
    """
    Enumerate array items

    @param <range>: see getrange
    @param callable: function which tests the flags

    @return: list of all addresses where callable(GetFlags(ea)) is True

    """
    (first, last) = getrange(args)
    i = getcallablepos(args)
    if i < 0:
        raise Exception("missing callable")

    callable = args[i]

    ea = first
    if ea < last and not callable(idaapi.get_full_flags(ea)):
        ea = idaapi.nextthat(ea, last, callable)
    while ea != BADADDR and ea < last:
        yield ea
        ea = idaapi.nextthat(ea, last, callable)
示例#15
0
文件: utils.py 项目: Midi12/SusanRTTI
 def force_name(self, ea, name):
     if isTail(get_full_flags(ea)):
         MakeUnknown(ea, 1, DOUNK_SIMPLE)
     MakeNameEx(ea, name, SN_NOWARN)
示例#16
0
 def flags(self):
     """`FF_*` Flags. See `bytes.hpp`."""
     return idaapi.get_full_flags(self.ea)
示例#17
0
    def block(self, block):
        """
        Returns a tuple: ([formal, block, signatures], [fuzzy, block, signatures], set([unique, immediate, values]), [called, function, names])
        """
        formal = []
        fuzzy = []
        functions = []
        immediates = []

        ea = block.start_ea
        insn = idaapi.insn_t()
        while ea < block.end_ea:
            idaapi.decode_insn(insn, ea)

            # Get a list of all data/code references from the current instruction
            drefs = [x for x in idautils.DataRefsFrom(ea)]
            crefs = [x for x in idautils.CodeRefsFrom(ea, False)]

            # Add all instruction mnemonics to the formal block hash
            formal.append(idc.print_insn_mnem(ea))

            # If this is a call instruction, be sure to note the name of the function
            # being called. This is used to apply call-based signatures to functions.
            #
            # For fuzzy signatures, we can't use the actual name or EA of the function,
            # but rather just want to note that a function call was made.
            #
            # Formal signatures already have the call instruction mnemonic, which is more
            # specific than just saying that a call was made.
            if idaapi.is_call_insn(ea):
                for cref in crefs:
                    func_name = idc.get_name(cref, ida_name.GN_VISIBLE)
                    if not func_name:
                        continue
                    functions.append(func_name)
                    fuzzy.append('funcref')
            # If there are data references from the instruction, check to see if any of them
            # are strings. These are looked up in the pre-generated strings dictionary.
            #
            # String values are easily identifiable, and are used as part of both the fuzzy
            # and the formal signatures.
            #
            # It is more difficult to determine if non-string values are constants or not;
            # for both fuzzy and formal signatures, just use "data" to indicate that some data
            # was referenced.
            elif drefs:
                for dref in drefs:
                    if dref in self.strings:
                        formal.append(self.strings[dref].value)
                        fuzzy.append(self.strings[dref].value)
                    else:
                        formal.append('dataref')
                        fuzzy.append('dataref')
            # If there are no data or code references from the instruction, use every operand as
            # part of the formal signature.
            #
            # Fuzzy signatures are only concerned with interesting immediate values, that is, values
            # that are greater than 65,535, are not memory addresses, and are not displayed as
            # negative values.
            elif not drefs and not crefs:
                for n in range(0, len(idaapi.insn_t().ops)):
                    opnd_text = idc.print_operand(ea, n)
                    formal.append(opnd_text)

                    if idaapi.insn_t().ops[n].type != idaapi.o_imm or opnd_text.startswith('-'):
                        continue

                    if idaapi.insn_t().ops[n].value < 0xFFFF:
                        continue

                    if idaapi.get_full_flags(idaapi.insn_t().ops[n].value) != 0:
                        continue

                    fuzzy.append(str(idaapi.insn_t().ops[n].value))
                    immediates.append(idaapi.insn_t().ops[n].value)

            ea = idc.next_head(ea)

        return self.sighash(''.join(formal)), self.sighash(''.join(fuzzy)), immediates, functions