Exemple #1
0
def set_input(trace, inbufs):
    inbufs = set(inbufs)
    for i, te in trace:
        uses_set = set(uses(te))
        if uses_set & inbufs:
            defs = defines(te)
            assert len(defs) == 1
            te.op = "IFLO_SET_INPUT"
            te.args = [defs[0], 0]
Exemple #2
0
def set_input(trace, inbufs):
    inbufs = set(inbufs)
    for i, te in trace:
        uses_set = set(uses(te))
        if uses_set & inbufs:
            defs = defines(te)
            assert len(defs) == 1
            te.op = "IFLO_SET_INPUT"
            te.args = [defs[0], 0]
Exemple #3
0
def multislice(insns, worklist, output_track=False, debug=False):
    wlist = worklist[:]
    wlist.sort()
    start, bufs = wlist.pop()
    
    if wlist:
        next_i, next_bufs = wlist.pop()
    else:
        next_i = -1

    if start == -1: start = len(insns) - 1
    if output_track: outbufs = set(bufs)
    
    if not quiet:
        widgets = ['Slicing: ', Percentage(), ' ', Bar(marker=RotatingMarker()), ' ', ETA()]
        pbar = ProgressBar(widgets=widgets, maxval=start+1).start()

    work = set(bufs)
    if debug: print "Initial working set:", work
    for i in range(start, -1, -1):
        #print "Examining instruction",i,"(working set: %d)" % len(work)
        if not quiet: pbar.update(start-i+1)
        insn = insns[i]
        if i == next_i:
            work |= set(next_bufs)
            if wlist:
                next_i, next_bufs = wlist.pop()

        defs_set = set(defines(insn))
        uses_set = set(uses(insn))

        if debug: print repr(insn)

        if defs_set & work:
            if debug: print "Overlap with working set: %s" % (defs_set & work)
            work -= defs_set
            work |= uses_set
            if debug: print "Adding to slice: %s" % repr(insn)
            if debug: print "Current WS:", work
            
            # TODO: allow multiple outputs by separating outbufs into
            # a dict of (label => memrange) pairs
            if output_track and defs_set & outbufs:
                if debug: print "Accounted for %d of %d output bytes" % (len(defs_set & outbufs), len(outbufs))
                if debug: print "Instruction: %s" % repr(insn)
                outbufs -= defs_set
                insn.set_output_label("out")
        
            insn.mark()

    if debug: print "Working set at end:", work
Exemple #4
0
def dynslice(insns, bufs, start=-1, output_track=False, debug=False):
    """Perform a dynamic data slice.
       
       Perform a dynamic data slice of a trace with respect to a set of
       buffers. This is basically the algorithm described in the
       K-Tracer paper.

       insns: a list of tuples: (index, TraceEntry)
       bufs: a list of outputs to be tracked
       start: an optional point in the trace at which to begin analysis.
           By default, analysis begins at the last instruction in the
           trace.
       ouput_track: mark instructions that define data in the output set.
           This calls TraceEntry.set_output_label().
       debug: enable debugging information

       Returns: a list of tuples: (index, TraceEntry)
    """
    if start == -1: start = len(insns) - 1
    if output_track: outbufs = set(bufs)

    work = set(bufs)
    slice = []
    for i, insn in reversed(insns[:start + 1]):
        defs_set = set(defines(insn))
        uses_set = set(uses(insn))

        if debug: print repr(insn)

        if defs_set & work:
            if debug: print "Overlap with working set: %s" % (defs_set & work)
            work = (work - defs_set) | uses_set
            if debug: print "Adding to slice: %s" % repr(insn)

            # TODO: allow multiple outputs by separating outbufs into
            # a dict of (label => memrange) pairs
            if output_track and defs_set & outbufs:
                outbufs -= defs_set
                insn.set_output_label("out")

            slice.insert(0, (i, insn))

    if debug: print "Working set at end:", work
    return slice
Exemple #5
0
def dynslice(insns, bufs, start=-1, output_track=False, debug=False):
    """Perform a dynamic data slice.
       
       Perform a dynamic data slice of a trace with respect to a set of
       buffers. This is basically the algorithm described in the
       K-Tracer paper.

       insns: a list of tuples: (index, TraceEntry)
       bufs: a list of outputs to be tracked
       start: an optional point in the trace at which to begin analysis.
           By default, analysis begins at the last instruction in the
           trace.
       ouput_track: mark instructions that define data in the output set.
           This calls TraceEntry.set_output_label().
       debug: enable debugging information

       Returns: a list of tuples: (index, TraceEntry)
    """
    if start == -1: start = len(insns) - 1
    if output_track: outbufs = set(bufs)

    work = set(bufs)
    slice = []
    for i, insn in reversed(insns[:start + 1]):
        defs_set = set(defines(insn))
        uses_set = set(uses(insn))

        if debug: print repr(insn)

        if defs_set & work:
            if debug: print "Overlap with working set: %s" % (defs_set & work)
            work = (work - defs_set) | uses_set
            if debug: print "Adding to slice: %s" % repr(insn)

            # TODO: allow multiple outputs by separating outbufs into
            # a dict of (label => memrange) pairs
            if output_track and defs_set & outbufs:
                outbufs -= defs_set
                insn.set_output_label("out")

            slice.insert(0, (i, insn))

    if debug: print "Working set at end:", work
    return slice
Exemple #6
0
def linked_vars(insns, sink, source, start=-1, end=0, debug=False):
    if debug: print "Linking vars sink: %s source: %s between trace positions %d and %d" % (sink, source, end, start)
    if start == -1: start = len(insns) - 1

    work = set([sink])
    for i,insn in reversed(insns[end:start+1]):
        defs_set = set(defines(insn))
        uses_set = set(uses(insn))
        # For this one special case we DON'T want to track
        # the derivation of the address of a buffer.
        if is_memop(insn):
            uses_set -= set(["A0"])

        if defs_set & work:
            work = (work - defs_set) | uses_set
            if debug: print i,repr(insn)

    if debug: print "Working set at end:", work
    return source in work
Exemple #7
0
def linked_vars(insns, sink, source, start=-1, end=0, debug=False):
    if debug:
        print "Linking vars sink: %s source: %s between trace positions %d and %d" % (
            sink, source, end, start)
    if start == -1: start = len(insns) - 1

    work = set([sink])
    for i, insn in reversed(insns[end:start + 1]):
        defs_set = set(defines(insn))
        uses_set = set(uses(insn))
        # For this one special case we DON'T want to track
        # the derivation of the address of a buffer.
        if is_memop(insn):
            uses_set -= set(["A0"])

        if defs_set & work:
            work = (work - defs_set) | uses_set
            if debug: print i, repr(insn)

    if debug: print "Working set at end:", work
    return source in work
Exemple #8
0
for i in xrange(len(trace) - 1, -1, -1):
    idx, insn = trace[i]
    if (insn.op == 'IFLO_OPS_MEM_LDL_T0_A0'
            or insn.op == 'IFLO_OPS_MEM_LDL_T1_A0'):
        memb_addr = insn.args[1]
        memb_val = insn.args[2]
        #print "Pointer dereference => Read 4 bytes at %#x = %#x" % (memb_addr,memb_val)

        # Tiny version of dynamic slicing -- track A0 until it comes from somewhere else
        j = i
        work = set(['A0'])
        slice = []
        while True:
            j -= 1
            _, trcent = trace[j]
            defs_set = set(defines(trcent))
            uses_set = set(uses(trcent))
            if defs_set & work:
                work = (work - defs_set) | uses_set
                slice.append((j, trcent))
            if 'A0' not in work: break

        valid = False
        objbase = UInt(memb_addr)
        for i, s in slice[:-1]:
            if s.op == "IFLO_ADDL_A0_IM":
                objbase -= UInt(s.args[0])
            elif s.op == "IFLO_ADDL_A0_SEG":
                pass
            elif s.op == "IFLO_MOVL_A0_IM":
                objbase -= UInt(s.args[0])
Exemple #9
0
for i in xrange(len(trace)-1,-1,-1):
    idx, insn = trace[i]
    if (insn.op == 'IFLO_OPS_MEM_LDL_T0_A0' or insn.op == 'IFLO_OPS_MEM_LDL_T1_A0'):
        memb_addr = insn.args[1]
        memb_val = insn.args[2]
        #print "Pointer dereference => Read 4 bytes at %#x = %#x" % (memb_addr,memb_val)

        # Tiny version of dynamic slicing -- track A0 until it comes from somewhere else
        j = i
        work = set(['A0'])
        slice = []
        while True:
            j -= 1
            _ , trcent = trace[j]
            defs_set = set(defines(trcent))
            uses_set = set(uses(trcent))
            if defs_set & work:
                work = (work - defs_set) | uses_set
                slice.append((j,trcent))
            if 'A0' not in work: break

        valid = False
        objbase = UInt(memb_addr)
        for i,s in slice[:-1]:
            if s.op == "IFLO_ADDL_A0_IM":
                objbase -= UInt(s.args[0])
            elif s.op == "IFLO_ADDL_A0_SEG":
                pass
            elif s.op == "IFLO_MOVL_A0_IM":
                objbase -= UInt(s.args[0])