Esempio n. 1
0
 def dref_range_fixer(startEA, endEA):
     for line in sark.lines(startEA, endEA):
         for xref in line.xrefs_to:
             if xref.iscode or xref.frm == idc.BADADDR or str(xref.type) != 'Data_Text': # only try to fix data references from code in ROM of the Data_Text type (as created by the dumb seq xref routine above)
                 continue
             logger.debug("fixing xref (type:%s) to %s from ROM:%x" % (xref.type, safe_name(line.ea), xref.frm))
             sark.Line(xref.frm).comments.repeat = str(sark.Line(xref.frm).comments.repeat).replace("0x%x" % line.ea, safe_name(line.ea))
     return
Esempio n. 2
0
def apply_enum_by_name(enum, member_name):
    member_value = enum.members[member_name].value
    for line in sark.lines(*sark.get_selection()):
        for operand in line.insn.operands:
            if operand.type.is_imm:
                if operand.imm == member_value:
                    idc.OpEnumEx(line.ea, operand.n, enum.eid, enum.members[member_name].serial)

            elif operand.type.is_displ or operand.type.is_phrase:
                if operand.addr == member_value:
                    idc.OpEnumEx(line.ea, operand.n, enum.eid, enum.members[member_name].serial)
Esempio n. 3
0
def _get_min_block_ranges(rgs, reg):
    if len(rgs) == 0:
        return rgs

    debug('Ranges before:')
    for s, e in rgs:
        debug('\t%x:%x' % (s, e))

    rgs_d = {}
    rgs_new = []
    rgs_new2 = []
    #assumption - rgs is sorted
    s_first_blk, _ = rgs[0]
    func_start = sark.Function(s_first_blk).start_ea

    #if range between ranges (or between function start and first range) doesn't contain the reg - add it as range
    curr_s = func_start
    for s_blk, e_blk in rgs:
        dontextend = False
        for l in sark.lines(curr_s, s_blk):
            if (oregami_gen.proc_ops.is_load(l.ea, reg)
                    or oregami_gen.proc_ops.is_store(l.ea, reg)
                ):  #reg was used in line - range cannot include this
                dontextend = True
                break

        if not dontextend:
            rgs_new += [(curr_s, s_blk)]

        rgs_new += [(s_blk, e_blk)]
        curr_s = e_blk

    #if ranges are right after each other - make them one range
    while len(rgs_new) > 0:
        #print rgs_new
        s_blk, e_blk = rgs_new[0]
        rgs_new = rgs_new[1:]

        #while next ranges are consecutive, eat them up
        while len(rgs_new) > 0:
            s_blk2, e_blk2 = rgs_new[0]
            if e_blk != s_blk2:
                break

            e_blk = e_blk2
            rgs_new = rgs_new[1:]

        rgs_new2 += [(s_blk, e_blk)]

    debug('Ranges after:')
    for s, e in rgs_new2:
        debug('\t%x:%x' % (s, e))

    return rgs_new2
Esempio n. 4
0
def apply_enum_by_name(enum, member_name):
    member_value = enum.members[member_name].value
    for line in sark.lines(*sark.get_selection()):
        for operand in line.insn.operands:
            if operand.type.is_imm:
                if operand.imm == member_value:
                    idc.OpEnumEx(line.ea, operand.n, enum.eid,
                                 enum.members[member_name].serial)

            elif operand.type.is_displ or operand.type.is_phrase:
                if operand.addr == member_value:
                    idc.OpEnumEx(line.ea, operand.n, enum.eid,
                                 enum.members[member_name].serial)
Esempio n. 5
0
    def avr_dumb_seq_load_xrefs(startEA, endEA):
        prev = None
        for line in sark.lines(startEA, endEA):
            if prev is None:
                prev = line
                continue

            try:
                curr_insn = line.insn
                prev_insn = prev.insn
            except sark.exceptions.SarkNoInstruction:
                logger.debug("skipping @ 0x%x" % line.ea)
                prev = line
                continue

            if (len(prev_insn.operands) != 2 or len(curr_insn.operands) != 2 or
                str(prev_insn.operands[1]) == '' or str(curr_insn.operands[1]) == ''
                ):
                logger.debug("filtering: %s && %s" % (prev, line))
                prev = line
                continue

            logger.debug("testing %s && %s" % (prev, line))
            if (is_latter_of_rxN_sequential_instructions(prev, line, 0) and
                str(prev_insn.operands[1].type) == 'Immediate_Value' and str(curr_insn.operands[1].type) == 'Immediate_Value'
               ):
                idc.OpHex(prev.ea, 1)
                idc.OpHex(line.ea, 1)
                if prev_insn.mnem == 'subi' and curr_insn.mnem == 'sbci':
                    word = (int(curr_insn.operands[1].text, 0) + 1) * -256 + int(prev_insn.operands[1].text, 0) * -1
                    address = ram_segment.startEA + word

                    if (address > ram_segment.startEA + 0x2000 and address < ram_segment.endEA and
                        str(prev_insn.operands[0]) != 'YL' and str(prev_insn.operands[0].reg) != 'r28' # ignore indexed access into stack
                       ):
                        result = add_dref(line.ea, address, dr_T)
                        logger.info("%s adding dref to %s at ROM:%x \"%s\"" % ("Success" if result else "Error", safe_name(address), line.ea, line))
                        line.comments.repeat = "indexed access into %s" % safe_name(address)
                else:
                    word = int(curr_insn.operands[1].text, 0) * 256 + int(prev_insn.operands[1].text, 0)
                    address = ram_segment.startEA + word

                    if address >= ram_segment.startEA and address < ram_segment.endEA:
                        result = add_dref(line.ea, address, dr_T)
                        logger.info("%s adding dref to %s at ROM:%x \"%s\"" % ("Success" if result else "Error", safe_name(address), line.ea, line))
                        if address <= ram_segment.startEA + 32:
                            line.comments.repeat = "possible %s" % sark.Line(address).comments.repeat # use the ioport name in the comments
                        else:
                            line.comments.repeat = safe_name(address)

            prev = line
Esempio n. 6
0
def get_common_value():
    values = defaultdict(int)
    for line in sark.lines(*sark.get_selection()):
        for operand in line.insn.operands:
            if operand.type.is_imm:
                values[operand.imm] += 1

            elif operand.type.is_displ or operand.type.is_phrase:
                values[operand.addr] += 1

    # Ignore 0 as it is usually not interesting
    values[0] = 0
    # Get the most common value
    common_value = max(values.iteritems(), key=lambda x: x[1])[0]
    return common_value
Esempio n. 7
0
def get_common_value():
    values = defaultdict(int)
    for line in sark.lines(*sark.get_selection()):
        for operand in line.insn.operands:
            if operand.type.is_imm:
                values[operand.imm] += 1

            elif operand.type.is_displ or operand.type.is_phrase:
                values[operand.addr] += 1

    # Ignore 0 as it is usually not interesting
    values[0] = 0
    # Get the most common value
    common_value = max(values.iteritems(), key=lambda x: x[1])[0]
    return common_value
Esempio n. 8
0
def get_refs_blk(ea, blk_ea, dir, initstage, reg):
    superdebug = False
    if blk_ea == 0x801e7788:
        superdebug = True
        print 'Entered SUPER'

    blk = CodeBlock(blk_ea)
    if dir == FW:
        lines = sark.lines(start=ea, end=blk.end_ea)
    elif dir == BK:
        lines = sark.lines(start=blk.start_ea, end=ea, reverse=True)

    found_lines = {}
    found_breaks = {}
    found_outbreaks = {}

    stop = False
    for l in lines:
        if superdebug:
            print 'SUPER: %x' % l.ea

        if stop:
            break

        op = ''
        if proc_ops.is_load(l.ea, reg):
            op += 'r'
        if proc_ops.is_store(l.ea, reg):
            op += 'w'

        if op == '':
            continue

        if dir == FW:
            if op == 'r':
                initstage = False
            elif op == 'w':
                #found_breaks[l.ea] = op
                found_outbreaks[l.ea] = op
                stop = True
                break
            elif op == 'rw':
                if not initstage:
                    found_breaks[l.ea] = op
                    stop = True
                    break
        elif dir == BK:
            if op == 'r':
                if initstage:
                    #found_breaks[l.ea] = op
                    found_outbreaks[l.ea] = op
                    stop = True
                    break
            elif op == 'w':
                initstage = False
                stop = True
            elif op == 'rw':
                initstage = True

        found_lines[l.ea] = op

    return found_lines, found_breaks, found_outbreaks, stop, initstage
Esempio n. 9
0
def _get_min_block_ranges(rgs, reg):
    if len(rgs) == 0:
        return rgs

    logger.debug('Ranges before:')
    for s, e in rgs:
        logger.debug('\t%x:%x' % (s, e))

    rgs_new = []
    rgs_new2 = []
    # assumption - rgs is sorted
    s_first_blk, _ = rgs[0]
    func_start = sark.Function(s_first_blk).start_ea

    # if range between ranges (or between function start and first range)
    #   doesn't contain the reg - add it as range
    curr_s = func_start
    for s_blk, e_blk in rgs:
        dont_extend = False
        for line in sark.lines(curr_s, s_blk):
            # if not code - i.e. a switch-case table, then no reason to
            #   check further
            if not line.is_code:
                continue

            # Trial - if ea not in function, dont_extend
            if ((not is_func(line.ea))
                    or (sark.Function(line.ea).start_ea != func_start)):
                dont_extend = True
                break

            opbits = RegInstruction(line.ea) \
                .get_reg_op_bits(reg, op_mask=UsageBits.OP_RW |
                                 UsageBits.USAGE_MASK)

            if bool(opbits & UsageBits.USAGE_EXPLICIT) and \
                    bool(opbits & UsageBits.OP_RW):
                # reg was used in line - range cannot include this
                dont_extend = True
                break

        if (not dont_extend) and (curr_s < s_blk):
            rgs_new += [(curr_s, s_blk)]

        rgs_new += [(s_blk, e_blk)]
        curr_s = e_blk

    # if ranges are right after each other - make them one range
    while len(rgs_new) > 0:
        # print rgs_new
        s_blk, e_blk = rgs_new[0]
        rgs_new = rgs_new[1:]

        # while next ranges are consecutive, eat them up
        while len(rgs_new) > 0:
            s_blk2, e_blk2 = rgs_new[0]
            if e_blk != s_blk2:
                break

            e_blk = e_blk2
            rgs_new = rgs_new[1:]

        rgs_new2 += [(s_blk, e_blk)]

    logger.debug('Ranges after:')
    for s, e in rgs_new2:
        logger.debug('\t%x:%x' % (s, e))

    return rgs_new2
Esempio n. 10
0
from collections import OrderedDict
from collections import Counter
import random
import idaapi, idc, idautils, ida_kernwin
import sark
import json

start = 0x01440E80
end = 0x01594280
CONST_LEN = 6
VFTABLE_LEN = 12
METHODS_LIMIT = 1040
COLOR_GREEN = 0x008000
COLOR_DARK_CYAN = 0x8B8B00
COLOR_ORANGE = 0x00A5FF  # FFA500
lines = sark.lines(start, end)


class VtableClass:
    def __init__(self, line):
        self.class_lines = []
        self.ea = line.ea
        self.line = line
        self.current_line = line
        self.functions_addr = []
        self.functions = {}
        self.get_base_name()
        self.get_methods()

    def get_base_name(self):
        self.raw_name = self.line.name
Esempio n. 11
0
    #stringify
    print("Looking for possible strings in %s segment..." %
          (idc.SegName(ram_segment.startEA)))

    counter = 0
    for s in idautils.Strings():
        if s.ea >= ram_segment.startEA and s.ea < ram_segment.endEA:
            if not idc.isASCII(idc.GetFlags(s.ea)) and idc.MakeStr(
                    s.ea, idc.BADADDR):
                counter += 1
    print "created %d new ASCII strings" % counter

    #datify
    print "Converting remaining data in RAM to words..."

    for line in sark.lines(ram_segment.startEA, ram_segment.endEA):
        flags = idc.GetFlags(line.ea)

        if (idc.isUnknown(flags) or idc.isByte(flags)) and line.ea % 2 == 0:
            idc.MakeWord(line.ea)

            val = Word(line.ea)
            if val > 31:  #ignore data references to small values (like r0-r31)
                idc.OpOff(line.ea, 0, ram_segment.startEA)

    print "all lines in 0x%x - 0x%x are now words" % (ram_segment.startEA,
                                                      ram_segment.endEA)

    #pointify
    print "looking for off_{} to rename to {}_ptr"
    counter = 0