Exemple #1
0
def get_switch_info(ea):
    '''ea_t -> switch_info_ex_t'''
    sw = idaapi.get_switch_info_ex(ea)
    if sw is None:
        raise NoSwitchError('ea at %s has no switch info' % atoa(ea))
    else:
        return sw
Exemple #2
0
def handleJmpTable(I, inst, new_eas):
    si = idaapi.get_switch_info_ex(inst)
    jsize = si.get_jtable_element_size()
    jstart = si.jumps

    # only handle size 4 cases
    if jsize != 4:
        raise Exception("Jump table size not 4!")
        return

    DEBUG("\tJMPTable Start: {0:x}\n".format(jstart))
    seg_start = idc.SegStart(jstart)

    if seg_start != idc.BADADDR:
        I.jump_table.offset_from_data = jstart - seg_start
        DEBUG("\tJMPTable offset from data: {:x}\n".format(I.jump_table.offset_from_data))

    I.jump_table.zero_offset = 0
    i = 0
    entries = si.get_jtable_size()
    for i in xrange(entries):
        je = readDword(jstart+i*jsize)
        I.jump_table.table_entries.append(je)
        if je not in RECOVERED_EAS and isStartOfFunction(je):
            new_eas.add(je)
        DEBUG("\t\tAdding JMPTable {0}: {1:x}\n".format(i, je))
Exemple #3
0
def get_switch_info(ea):
    '''ea_t -> switch_info_ex_t'''
    sw = idaapi.get_switch_info_ex(ea)
    if sw is None:
        raise NoSwitchError('ea at %s has no switch info' % atoa(ea))
    else:
        return sw
Exemple #4
0
def handleJmpTable(I, inst, new_eas):
    si = idaapi.get_switch_info_ex(inst)
    jsize = si.get_jtable_element_size()
    jstart = si.jumps

    # accept 32-bit jump tables in 64-bit, for now
    valid_sizes = [4, getBitness()/8]
    readers = { 4: readDword,
                8: readQword }

    if jsize not in valid_sizes:
        raise Exception("Jump table is not a valid size: {}".format(jsize))
        return

    DEBUG("\tJMPTable Start: {0:x}\n".format(jstart))
    seg_start = idc.SegStart(jstart)

    if seg_start != idc.BADADDR:
        I.jump_table.offset_from_data = jstart - seg_start
        DEBUG("\tJMPTable offset from data: {:x}\n".format(I.jump_table.offset_from_data))

    I.jump_table.zero_offset = 0
    i = 0
    entries = si.get_jtable_size()
    for i in xrange(entries):
        je = readers[jsize](jstart+i*jsize)
        I.jump_table.table_entries.append(je)
        if je not in RECOVERED_EAS and isStartOfFunction(je):
            new_eas.add(je)
        DEBUG("\t\tAdding JMPTable {0}: {1:x}\n".format(i, je))
Exemple #5
0
    def _calc_cases(self):
        si = idaapi.get_switch_info_ex(self._ea)
        results = idaapi.calc_switch_cases(self._ea, si)
        if not results:
            raise SarkNotASwitch("Seems like 0x{:08X} is not a switch jump instruction.".format(self._ea))

        return results
Exemple #6
0
def InsSwitchInfo(i):
    switch_info = idaapi.get_switch_info_ex(i)
    if switch_info is None:
        return False, None, None

    cases = idaapi.calc_switch_cases(i, switch_info)
    return bool(cases), switch_info, cases
Exemple #7
0
def handleJmpTable(I, inst, new_eas):
    si = idaapi.get_switch_info_ex(inst)
    jsize = si.get_jtable_element_size()
    jstart = si.jumps

    # accept 32-bit jump tables in 64-bit, for now
    valid_sizes = [4, getBitness() / 8]
    readers = {4: readDword, 8: readQword}

    if jsize not in valid_sizes:
        raise Exception("Jump table is not a valid size: {}".format(jsize))
        return

    DEBUG("\tJMPTable Start: {0:x}\n".format(jstart))
    seg_start = idc.SegStart(jstart)

    if seg_start != idc.BADADDR:
        I.jump_table.offset_from_data = jstart - seg_start
        DEBUG("\tJMPTable offset from data: {:x}\n".format(
            I.jump_table.offset_from_data))

    I.jump_table.zero_offset = 0
    i = 0
    entries = si.get_jtable_size()
    for i in xrange(entries):
        je = readers[jsize](jstart + i * jsize)
        I.jump_table.table_entries.append(je)
        if je not in RECOVERED_EAS and isStartOfFunction(je):
            new_eas.add(je)
        DEBUG("\t\tAdding JMPTable {0}: {1:x}\n".format(i, je))
Exemple #8
0
def switches(fn):
    fn = top(fn)
    for ea in iterate(fn):
        x = idaapi.get_switch_info_ex(ea)
        if x:
            yield switch_t(x)
        continue
    return
Exemple #9
0
def switches(fn):
    fn = top(fn)
    for ea in iterate(fn):
        x = idaapi.get_switch_info_ex(ea)
        if x:
            yield switch_t(x)
        continue
    return
Exemple #10
0
 def find_all_switch_jumps(self):
     self._switch_dict = defaultdict(list)
     next_switch = idc.FindBinary(idc.MinEA(), idc.SEARCH_DOWN|idc.SEARCH_NEXT, "ff 24")
     while next_switch != idc.BADADDR:
         sw = idaapi.get_switch_info_ex(next_switch)
         if idc.GetMnem(next_switch).startswith("jmp") and sw:
             ic = self.get_jlocs(sw)
             self._switch_dict[idaapi.get_func_name(next_switch)].append((next_switch, sw.ncases, ic))
         next_switch = idc.FindBinary(idc.NextHead(next_switch), idc.SEARCH_DOWN|idc.SEARCH_NEXT, "ff 24")
Exemple #11
0
    def _calc_cases(self):
        si = idaapi.get_switch_info_ex(self._ea)
        results = idaapi.calc_switch_cases(self._ea, si)
        if not results:
            raise exceptions.SarkNotASwitch(
                "Seems like 0x{:08X} is not a switch jump instruction.".format(
                    self._ea))

        return results
Exemple #12
0
 def find_all_switch_jumps(self):
     self._switch_dict = defaultdict(list)
     next_switch = idc.FindBinary(idc.MinEA(), idc.SEARCH_DOWN|idc.SEARCH_NEXT, "ff 24")
     while next_switch != idc.BADADDR:
         sw = idaapi.get_switch_info_ex(next_switch)
         if idc.GetMnem(next_switch).startswith("jmp") and sw:
             ic = self.get_jlocs(sw)
             self._switch_dict[idaapi.get_func_name(next_switch)].append((next_switch, sw.ncases, ic))
         next_switch = idc.FindBinary(idc.NextHead(next_switch), idc.SEARCH_DOWN|idc.SEARCH_NEXT, "ff 24")
Exemple #13
0
def isJmpTable(ea):
    insn_t = idautils.DecodeInstruction(ea)
    is_jmp = insn_t.itype in [idaapi.NN_jmp, idaapi.NN_jmpfi, idaapi.NN_jmpni]

    if not is_jmp: return False

    if idaapi.get_switch_info_ex(ea):
        return True

    return False
Exemple #14
0
def isJmpTable(ea):
    insn_t = idautils.DecodeInstruction(ea)
    is_jmp = insn_t.itype in [idaapi.NN_jmp, idaapi.NN_jmpfi, idaapi.NN_jmpni]

    if not is_jmp:
        return False

    if idaapi.get_switch_info_ex(ea):
        return True

    return False
def find_switch(func_ea):
    # get all chunks that belong to a function, because apparently they're not contiguous or some shit
    for (start_ea, end_ea) in idautils.Chunks(func_ea):
        for head in idautils.Heads(start_ea, end_ea):
            switch = idaapi.get_switch_info_ex(head)

            if switch != None:
                log('found switch @ %x, cases: %d' %
                    (head, switch.get_jtable_size()))
                return (head, switch)

    return (None, None)
Exemple #16
0
def analyse_indirect_jump(block, jump_inst, blocks):
  """Analyse an indirect jump and try to determine its targets."""
  log.info("Analysing indirect jump at {:08x}".format(jump_inst.ea))
  si = idaapi.get_switch_info_ex(jump_inst.ea)
  target_eas = set()
  if si:
    num_targets = si.get_jtable_size()
    log.info("IDA identified a jump table at {:08x} with {} targets".format(
        jump_inst.ea, num_targets))
    target_eas.update(idautils.CodeRefsFrom(jump_inst.ea, True))

  for target_ea in target_eas:
    block = program.get_basic_block(target_ea)
    block.address_is_taken = True
Exemple #17
0
def analyse_indirect_jump(block, jump_inst, blocks):
    """Analyse an indirect jump and try to determine its targets."""
    log.info("Analysing indirect jump at {:08x}".format(jump_inst.ea))
    si = idaapi.get_switch_info_ex(jump_inst.ea)
    target_eas = set()
    if si:
        num_targets = si.get_jtable_size()
        log.info(
            "IDA identified a jump table at {:08x} with {} targets".format(
                jump_inst.ea, num_targets))
        target_eas.update(idautils.CodeRefsFrom(jump_inst.ea, True))

    for target_ea in target_eas:
        block = program.get_basic_block(target_ea)
        block.address_is_taken = True
Exemple #18
0
def handleJmpTable(I, F, inst, new_eas):
    si = idaapi.get_switch_info_ex(inst)
    jsize = si.get_jtable_element_size()
    jstart = si.jumps

    # try to fix a problem with IDA, which
    # doesn't recognise completely switch
    if jstart == 0xffffffff:
        jstart = list(DataRefsFrom(inst))[0]

    # only handle size 4 cases
    if jsize != 4:
        raise Exception("Jump table size not 4!")
        return

    DEBUG("\tJMPTable Start: {0:x}\n".format(jstart))
    if I is not None:
        I.jump_table.zero_offset = 0

    jmpt = JmpTable(addr=jstart, function=F)

    # Return empty object - jump tables disabled
    return jmpt

    i = 0
    data = idaapi.get_many_bytes(jstart+i*jsize, 4)
    #TODO: fix this
    if data is None:
        return jmpt

    je = struct.unpack('<I', data)[0]
    while i < si.ncases:
        if I is not None:
            I.jump_table.table_entries.append(je)
            if je not in RECOVERED_EAS:
                new_eas.add(je)

            DEBUG("\t\tAdding JMPTable {0}: {1:x}\n".format( i, je))
        else:
            new_eas.add(je)

        jmpt.add_entry(je)

        i += 1
        je = struct.unpack('<I', idaapi.get_many_bytes(jstart+i*jsize, 4))[0]

    return jmpt
Exemple #19
0
def preprocessBinary():
    # loop through every instruction and
    # keep a list of jump tables references in the
    # data section. These are used so we can
    # avoid generating unwanted function entry points
    for seg_ea in idautils.Segments():
        for head in idautils.Heads(seg_ea, idc.SegEnd(seg_ea)):
            if idc.isCode(idc.GetFlags(head)):
                si = idaapi.get_switch_info_ex(head)
                if si is not None and isUnconditionalJump(head):
                    DEBUG("Found a jmp based switch at: {0:x}\n".format(head))
                    esize = si.get_jtable_element_size()
                    base = si.jumps
                    count = si.get_jtable_size()
                    for i in xrange(count):
                        fulladdr = base+i*esize
                        DEBUG("Address accessed via JMP: {:x}\n".format(fulladdr))
                        ACCESSED_VIA_JMP.add(fulladdr)
def find_unanalyzed_jump_table(start_ea, end_ea):
    """ Return address of first unanalyzed jump table between start_ea
        and end_ea
    """
    ea = start_ea
    while ea <= end_ea:
        # Find jmp, where first operand == NextHead(jmp_ea).  If no 
        # switch_info_ex_t object at jmp_ea, return jmp_ea

        is_jmp_insn = (idc.GetMnem(ea) == "jmp")
        not_switch_table = (idaapi.get_switch_info_ex(ea) == None)
        next_ea = idc.NextHead(ea, end_ea)
        jmp_target_next_insn = (next_ea == idc.GetOperandValue(ea, 0))

        if is_jmp_insn and jmp_target_next_insn and not_switch_table:
            return ea

        ea = next_ea

    return idc.BADADDR
Exemple #21
0
def handleJmpTable(I, inst, new_eas):
    si = idaapi.get_switch_info_ex(inst)
    jsize = si.get_jtable_element_size()
    jstart = si.jumps

    # only handle size 4 cases
    if jsize != 4:
        raise Exception("Jump table size not 4!")
        return

    DEBUG("\tJMPTable Start: {0:x}\n".format(jstart))
    I.jump_table.zero_offset = 0
    i = 0
    entries = si.ncases
    for i in xrange(entries):
        je = readDword(jstart+i*jsize)
        I.jump_table.table_entries.append(je)
        if je not in RECOVERED_EAS: 
            new_eas.add(je)
        DEBUG("\t\tAdding JMPTable {0}: {1:x}\n".format(i, je))
Exemple #22
0
def handleJmpTable(I, inst, new_eas):
    si = idaapi.get_switch_info_ex(inst)
    jsize = si.get_jtable_element_size()
    jstart = si.jumps

    # only handle size 4 cases
    if jsize != 4:
        raise Exception("Jump table size not 4!")
        return

    DEBUG("\tJMPTable Start: {0:x}\n".format(jstart))
    I.jump_table.zero_offset = 0
    i = 0
    je = idc.GetFixupTgtOff(jstart+i*jsize)
    while je != -1:
        I.jump_table.table_entries.append(je)
        if je not in RECOVERED_EAS: 
            new_eas.add(je)
        DEBUG("\t\tAdding JMPTable {0}: {1:x}\n".format( i, je))
        i += 1
        je = idc.GetFixupTgtOff(jstart+i*jsize)
Exemple #23
0
def handleJmpTable(I, inst, new_eas):
    si = idaapi.get_switch_info_ex(inst)
    jsize = si.get_jtable_element_size()
    jstart = si.jumps

    # only handle size 4 cases
    if jsize != 4:
        raise Exception("Jump table size not 4!")
        return

    DEBUG("\tJMPTable Start: {0:x}\n".format(jstart))
    I.jump_table.zero_offset = 0
    i = 0
    je = idc.GetFixupTgtOff(jstart + i * jsize)
    while je != -1:
        I.jump_table.table_entries.append(je)
        if je not in RECOVERED_EAS:
            new_eas.add(je)
        DEBUG("\t\tAdding JMPTable {0}: {1:x}\n".format(i, je))
        i += 1
        je = idc.GetFixupTgtOff(jstart + i * jsize)
def findFuncsByInitializeMethodMetadata():
    global GetMethodInfoFromIndex
    global GetStringLiteralFromIndex
    finituseage = getNamedFunc("InitializeMethodMetadata")

    def findFirstCall(startAddr, endAddr):
        while 1:
            line = sark.Line(startAddr)
            for xref in line.xrefs_from:
                if repr(xref.type
                        ) != "Ordinary_Flow" and sark.Function.is_function(
                            xref.to):
                    return xref.to
            startAddr += len(line.bytes)
            if target >= endAddr:
                break
        return None

    for line in finituseage.lines:
        switch_info = idaapi.get_switch_info_ex(line.ea)
        if switch_info:
            case3 = idc.Dword(switch_info.jumps + 2 * 4)
            case5 = idc.Dword(switch_info.jumps + 4 * 4)
            case6 = idc.Dword(switch_info.jumps + 5 * 4)
            if case3 == case6:
                target = switch_info.jumps + case3
                taddr = findFirstCall(target, finituseage.endEA)
                if taddr:
                    # print "find GetMethodInfoFromIndex at", hex(int(taddr))
                    idc.set_name(taddr, "GetMethodInfoFromIndex",
                                 SN_NOWARN | SN_NOCHECK)
                    GetMethodInfoFromIndex = int(taddr)
            target = switch_info.jumps + case5
            taddr = findFirstCall(target, finituseage.endEA)
            if taddr:
                # print "find GetStringLiteralFromIndex at", hex(int(taddr))
                idc.set_name(taddr, "GetStringLiteralFromIndex",
                             SN_NOWARN | SN_NOCHECK)
                GetStringLiteralFromIndex = int(taddr)
            break
Exemple #25
0
def get_static_successors(inst):
  """Returns the statically known successors of an instruction."""
  branch_flows = tuple(idautils.CodeRefsFrom(inst.ea, False))

  # Direct function call. The successor will be the fall-through instruction
  # unless the target of the function call looks like a `noreturn` function.
  if inst.is_direct_function_call():
    called_ea = get_direct_branch_target(inst.ea)
    flags = idc.GetFunctionFlags(called_ea)

    if 0 < flags and (flags & idaapi.FUNC_NORET):
      log.debug("Call to noreturn function {:08x} at {:08x}".format(
          called_ea, inst.ea))
    else:
      yield inst.next_ea  # Not recognised as a `noreturn` function.

  if inst.is_call():  # Indirect function call, system call.
    yield inst.next_ea

  elif inst.is_conditional_branch():
    yield inst.next_ea
    yield get_direct_branch_target(inst.ea)

  elif inst.is_direct_jump():
    yield get_direct_branch_target(inst.ea)

  elif inst.is_indirect_jump():
    si = idaapi.get_switch_info_ex(inst.ea)
    if si:
      for case_ea in idautils.CodeRefsFrom(inst.ea, True):
        yield case_ea

  elif inst.is_fall_through():
    yield inst.next_ea

  else:
    log.debug("No static successors of {:08x}".format(inst.ea))
Exemple #26
0
def get_static_successors(inst):
    """Returns the statically known successors of an instruction."""
    branch_flows = tuple(idautils.CodeRefsFrom(inst.ea, False))

    # Direct function call. The successor will be the fall-through instruction
    # unless the target of the function call looks like a `noreturn` function.
    if inst.is_direct_function_call():
        called_ea = get_direct_branch_target(inst.ea)
        flags = idc.GetFunctionFlags(called_ea)

        if 0 < flags and (flags & idaapi.FUNC_NORET):
            log.debug("Call to noreturn function {:08x} at {:08x}".format(
                called_ea, inst.ea))
        else:
            yield inst.next_ea  # Not recognised as a `noreturn` function.

    if inst.is_call():  # Indirect function call, system call.
        yield inst.next_ea

    elif inst.is_conditional_branch():
        yield inst.next_ea
        yield get_direct_branch_target(inst.ea)

    elif inst.is_direct_jump():
        yield get_direct_branch_target(inst.ea)

    elif inst.is_indirect_jump():
        si = idaapi.get_switch_info_ex(inst.ea)
        if si:
            for case_ea in idautils.CodeRefsFrom(inst.ea, True):
                yield case_ea

    elif inst.is_fall_through():
        yield inst.next_ea

    else:
        log.debug("No static successors of {:08x}".format(inst.ea))
Exemple #27
0
 def __getinsn(cls, ea):
     res = idaapi.get_switch_info_ex(ea)
     if res is None:
         raise TypeError, "Unable to instantiate a switch_info_ex_t at branch instruction : %x" % ea
     return res
Exemple #28
0
def name(ea=None, *args, **kwds):
    """name(ea), name(ea, string)
    First syntax returns the name at the given address.
    Second syntax changes the name at the given address.
    """
    if len(args) > 1:
        raise TypeError, "{:s}() takes exactly {!r} arguments ({:d} given)".format(
            'name', (1, 2),
            len(args) + 1 + len(kwds))
    if kwds and tuple(kwds.keys()) != ('string', ):
        raise TypeError, "{:s}() got an unexpected keyword argument '{:s}'".format(
            'name',
            filter(lambda n: n != 'string', kwds.keys())[0])

    ea = ui.current.address() if ea is None else ea
    if len(args) == 1 or kwds.has_key('string'):
        string = kwds.get('string', args[0])
        assert idaapi.SN_NOCHECK == 0, '%s.name : idaapi.SN_NOCHECK != 0' % __name__
        SN_NOLIST = idaapi.SN_NOLIST
        SN_LOCAL = idaapi.SN_LOCAL
        SN_NON_PUBLIC = idaapi.SN_NON_PUBLIC

        if idaapi.has_any_name(idaapi.getFlags(ea)):
            pass

        flags = idaapi.SN_NON_AUTO
        flags |= 0 if idaapi.is_in_nlist(ea) else idaapi.SN_NOLIST
        flags |= idaapi.SN_WEAK if idaapi.is_weak_name(
            ea) else idaapi.SN_NON_WEAK
        flags |= idaapi.SN_PUBLIC if idaapi.is_public_name(
            ea) else idaapi.SN_NON_PUBLIC

        try:
            function.top(ea)
            flags |= idaapi.SN_LOCAL
        except Exception:
            flags &= ~idaapi.SN_LOCAL

        try:
            # check if we're a label of some kind
            f = idaapi.getFlags(ea)
            if idaapi.has_dummy_name(f) or idaapi.has_user_name(f):
                # that is referenced by an array with a correctly sized pointer inside it
                (r, sidata), = ((r, type.array(r)) for r in xref.data_up(ea))
                if config.bits() == sidata.itemsize * 8 and ea in sidata:
                    # which we check to see if it's a switch_info_t
                    si, = (idaapi.get_switch_info_ex(r)
                           for r in xref.data_up(r))
                    if si is not None:
                        # because it's name has it's local flag cleared
                        flags ^= idaapi.SN_LOCAL
        except:
            pass

        res, ok = name(ea), idaapi.set_name(ea, string or "", flags)
        tag(ea, 'name', string)
        assert ok, '%s.name : unable to call idaapi.set_name(%x, %r, %x)' % (
            __name__, ea, string, flags)
        return res

    try:
        return tag(ea, 'name')
    except KeyError:
        pass
    return None
Exemple #29
0
import idautils
import idaapi
import idc

switches = []

for f in idautils.Functions():
    func = idaapi.get_func(f)

    for h in idautils.Heads(func.startEA, func.endEA):
        res = idaapi.get_switch_info_ex(h)
        if res != None:
            # number of cases
            num_cases = res.get_jtable_size()
        else:
            continue

        print '0x%08x: switch (%d cases)' % (h, num_cases)

        # get cases
        xrefs = idautils.CodeRefsFrom(h, 1)

        interesting_calls = []

        switches.append((h, num_cases, interesting_calls))


# http://dvlabs.tippingpoint.com/blog/2011/05/11/mindshare-extending-ida-custviews
class SwitchViewer(idaapi.simplecustviewer_t):
    def __init__(self, data):
    def observeSwitchTableFeatures(self, scs):
        """Observe the features of IDA-recognized switch tables, and try to detect patterns.

        Args:
            scs (list): list of (sark) code segments

        Notes
        -----
            1. Trying to observe an alignment pattern for the switch tables.
            2. Trying to observe a code pattern for the instruction before each switch table.

        Return Value:
            True iff found all of the desired features (patterns)
        """
        table_alignment_pattern = AlignmentPattern()
        observer = CodePattern()
        for sc in scs:
            # scan for known switch cases, and only from our desired record size
            for line in filter(lambda x: x.is_code, sc.lines):
                try:
                    sw = idaapi.get_switch_info_ex(line.startEA)
                    if sw is None:
                        continue
                    if sw.get_jtable_element_size() != self._record_size:
                        continue
                    # The table should be near our code (otherwise we don't care about it)
                    if abs(line.startEA - sw.jumps) > 0x100:
                        continue
                except Exception:
                    continue
                # IDA recognized the switch table exactly at the last code instruction before it
                observer.add(line)

                # Going to use the easy case
                # 1. Find the table alignment (4)
                # 2. Find the command + common args for the jump line (MOV PC, )
                # 3. Assume the table is right after this command, padded to alignment
                # 4. Count the cases as long as they point to code near us
                # 5. Don't define it as a switch table using IDA's structures (too complex)
                self._analyzer.logger.debug("Located a switch table at: 0x%x",
                                            line.startEA)
                self._analyzer.logger.debug("\tStart EA: 0x%x", sw.startea)
                self._analyzer.logger.debug("\tJump Table: 0x%x", sw.jumps)
                self._analyzer.logger.debug("\t%s", str(line))
                # table alignment
                table_alignment_pattern.add(sw.jumps)

        # check if found any
        if table_alignment_pattern.size() < 2:
            self._analyzer.logger.error(
                "Couldn't find enough switch tables in this code section...")
            return False

        # print all of the statistics
        self._analyzer.logger.info("Switch Table Results:")
        self._table_alignment = table_alignment_pattern.decide()
        self._analyzer.logger.info("Table alignment is: %d",
                                   self._table_alignment)

        if not observer.decide():
            self._analyzer.logger.error(
                "Failed to find any code pattern for the switch tables")
            return False
        else:
            self._analyzer.logger.info("Switch jump code instruction is: %s",
                                       observer)
            self._code_pattern = observer
            return True
Exemple #31
0
for func in idautils.Functions():
    # if 'PyEval_EvalFrameEx' == idc.GetFunctionName(func):
    if '_PyEval_EvalFrameDefault' == idc.GetFunctionName(func):
        print('[+] Found target function!')
        myfunc = func
        break


def is_user_name(ea):
    f = idc.GetFlags(ea)
    return idc.hasUserName(f)

for (startea, endea) in Chunks(myfunc):
    for head in Heads(startea, endea):
        switch_info = idaapi.get_switch_info_ex(head)
        if switch_info != None:
            num_cases = switch_info.get_jtable_size()
            # print(num_cases)
            # print 'good jump table found'
            results = idaapi.calc_switch_cases(head, switch_info)
            for idx in xrange(results.cases.size()):
                cur_case = results.cases[idx]
                ret = is_user_name(results.targets[idx])
                if ret:
                    name = idc.NameEx(BADADDR, results.targets[idx])
                    if "TARGET_" in name or "PRED_" in name:
                        for cidx in xrange(len(cur_case)):
                            number = int(cur_case[cidx])
                            name = name.replace("TARGET_", "").replace("PRED_", "")
                            if name not in jump_table:
Exemple #32
0
def switches(key=None):
    for ea in iterate(key):
        res = idaapi.get_switch_info_ex(ea)
        if res: yield switch_t(res)
    return
Exemple #33
0
import idautils
import idaapi
import idc

switches = []

for f in idautils.Functions():
    func = idaapi.get_func(f)

    for h in idautils.Heads(func.startEA, func.endEA):
        opcodes = idc.Dword(h) & 0xFFFF
        if opcodes == 0x24ff:
            # number of cases
            res = idaapi.get_switch_info_ex(h)
            if res != None:
                num_cases = res.get_jtable_size()
            else:
                continue

            print '0x%08x: switch (%d cases)' % (h, num_cases)

            # get cases
            xrefs = idautils.CodeRefsFrom(h, 1)


            interesting_calls = []
            
            switches.append((h, num_cases, interesting_calls))


Exemple #34
0
for func in idautils.Functions():
    # if 'PyEval_EvalFrameEx' == idc.GetFunctionName(func):
    if '_PyEval_EvalFrameDefault' == idc.GetFunctionName(func):
        print('[+] Found target function!')
        myfunc = func
        break


def is_user_name(ea):
    f = idc.GetFlags(ea)
    return idc.hasUserName(f)


for (startea, endea) in Chunks(myfunc):
    for head in Heads(startea, endea):
        switch_info = idaapi.get_switch_info_ex(head)
        if switch_info != None:
            num_cases = switch_info.get_jtable_size()
            # print(num_cases)
            # print 'good jump table found'
            results = idaapi.calc_switch_cases(head, switch_info)
            for idx in xrange(results.cases.size()):
                cur_case = results.cases[idx]
                ret = is_user_name(results.targets[idx])
                if ret:
                    name = idc.NameEx(BADADDR, results.targets[idx])
                    if "TARGET_" in name or "PRED_" in name:
                        for cidx in xrange(len(cur_case)):
                            number = int(cur_case[cidx])
                            name = name.replace("TARGET_",
                                                "").replace("PRED_", "")