Пример #1
0
def get_changed_bytes(functions):
    """Applies all the randomizations on each function and returns the
    superset of the changed bytes for each technique (coverage)."""

    swap_b, preserv_b, equiv_b, reorder_b = set(), set(), set(), set()

    for f in filter(lambda x: x.level != -1, functions.itervalues()):
        # swap
        swap.liveness_analysis(f.code)
        live_regs = swap.get_reg_live_subsets(f.instrs, f.code, f.igraph)
        swap.split_reg_live_subsets(live_regs, f.code)
        swaps = swap.get_reg_swaps(live_regs)
        swap_b |= swap.do_single_swaps(swaps, gen_patched=False)

        # preserv
        preservs, avail_regs = preserv.get_reg_preservations(f)
        preserv_b |= preserv.do_reg_preservs(f.instrs,
                                             f.blocks,
                                             preservs,
                                             avail_regs,
                                             gen_patched=False)

        # equiv
        equiv_b |= equiv.do_equiv_instrs(f.instrs, gen_patched=False)

        # reorder
        reorder_b |= reorder.do_reordering(f.blocks, gen_patched=False)

    return swap_b, preserv_b, equiv_b, reorder_b
Пример #2
0
def get_changed_bytes(functions):
    """Applies all the randomizations on each function and returns the
    superset of the changed bytes for each technique (coverage)."""

    swap_b, preserv_b, equiv_b, reorder_b = set(), set(), set(), set()

    for f in filter(lambda x: x.level != -1, functions.itervalues()):
        # swap
        swap.liveness_analysis(f.code)
        live_regs = swap.get_reg_live_subsets(f.instrs, f.code, f.igraph)
        swap.split_reg_live_subsets(live_regs, f.code)
        swaps = swap.get_reg_swaps(live_regs)
        swap_b |= swap.do_single_swaps(swaps, gen_patched=False)

        # preserv
        preservs, avail_regs = preserv.get_reg_preservations(f)
        preserv_b |= preserv.do_reg_preservs(f.instrs, f.blocks, preservs,
                                             avail_regs, gen_patched=False)

        # equiv
        equiv_b |= equiv.do_equiv_instrs(f.instrs, gen_patched=False)

        # reorder
        reorder_b |= reorder.do_reordering(f.blocks, gen_patched=False)

    return swap_b, preserv_b, equiv_b, reorder_b
Пример #3
0
    def testAll(self):

        funcs = inp.load_data(self.INPUT)

        for ea, f in funcs.iteritems():
            if ea == self.FUNC:
                break
        else:
            self.fail("could not find MD5Update at %x" % self.FUNC)

        # analyze
        levels = func.classify_functions(funcs)
        func.analyze_functions(funcs, levels)

        # swap
        swap.liveness_analysis(f.code)
        live_regs = swap.get_reg_live_subsets(f.instrs, f.code, f.igraph)
        swap.split_reg_live_subsets(live_regs, f.code)
        swaps = swap.get_reg_swaps(live_regs)
        swap.do_single_swaps(swaps, gen_patched=True)

        # preserv
        preservs, avail_regs = preserv.get_reg_preservations(f)
        preserv.do_reg_preservs(f.instrs,
                                f.blocks,
                                preservs,
                                avail_regs,
                                gen_patched=True)
        # equiv
        equiv.do_equiv_instrs(f.instrs, gen_patched=True)

        # reorder
        reorder.do_reordering(f.blocks, gen_patched=True)

        # check the numner of generated files
        print self.assertEqual(len(glob.glob(self.GEN_FILES)), 50)

        for genf in glob.glob(self.GEN_FILES):
            output = util.run("%s %s" % (self.PROG, genf), 10)
            self.assertTrue(self.EXPECT in output,
                            "%s: %s %s" % (genf, self.EXPECT, output))
        # remove the generated files
        map(os.remove, glob.glob(self.GEN_FILES))
Пример #4
0
def randomize(input_file):
    # get the changed byte sets
    functions = inp.get_functions(input_file)
    levels = func.classify_functions(functions)
    func.analyze_functions(functions, levels)

    global_diffs = []
    changeable = 0

    for f in filter(lambda x: x.level != -1, functions.itervalues()):
        # skip the SEH prolog and epilog functions .. they cause trouble
        if "_SEH_" in f.name:    
            continue

        diffs = []

        # swap (register reassignment with CFG): RUNTIME ERROR
        # This application has requested the Runtime to terminate it in an unsusal way.
        # Please Contact the application's support team for more information
        swap.liveness_analysis(f.code)
        live_regs = swap.get_reg_live_subsets(f.instrs, f.code, f.igraph)
        swaps = swap.get_reg_swaps(live_regs)
        swap.do_single_swaps(swaps, False, diffs)

        # preserv (reordering of register preservation): ERROR
        preservs, avail_regs = preserv.get_reg_preservations(f)
        preserv.do_reg_preservs(f.instrs, f.blocks, preservs, avail_regs, False, diffs)

        # equiv (automic instruction substitution): GOOD
        equiv.do_equiv_instrs(f.instrs, False, diffs)

        # reorder (intra basic block reordering): GOOD
        reorder.do_reordering(f.blocks, False, diffs)

        if diffs:
            changeable += len(list(itertools.chain(*diffs)))
            global_diffs.extend(random.choice(diffs))

    inp.patch(global_diffs, "rand", False)

    print "changed %d bytes of at least %d changeable" % (len(global_diffs), changeable)
    print "(not counting all possible reorderings and preservations)"
Пример #5
0
    def testExecutePreserv(self):

        GEN_FILES = TEST + "testlib/testlib_patched-preserv*.dll"

        # fill in the reg_pairs list (needed by preserv)
        self.f.analyze_registers({})
        preservs, avail_regs = preserv.get_reg_preservations(self.f)
        changed_bytes = preserv.do_reg_preservs(self.f.instrs,
                                                self.f.blocks,
                                                preservs,
                                                avail_regs,
                                                gen_patched=True)
        # check the number of changed bytes
        self.assertEqual(len(changed_bytes), 17)
        # check the numner of generated files
        self.assertEqual(len(glob.glob(GEN_FILES)), 1)
        # check the output of the generated files
        for genf in glob.glob(GEN_FILES):
            output = util.run("%s %s" % (self.PROG, genf), 10)
            self.assertTrue(self.EXPECT in output,
                            "%s: %s %s" % (genf, self.EXPECT, output))
        # remove the generated files
        map(os.remove, glob.glob(GEN_FILES))
Пример #6
0
            func_gads[g.func_ea] = []
        func_gads[g.func_ea].append(g)

    for func_ea, gadgets in func_gads.iteritems():
        # there is nothing we can do ..
        if func_ea == None:
            continue

        f = functions[func_ea]

        # do analysis!
        swap.liveness_analysis(f.code)
        live_regs = swap.get_reg_live_subsets(f.instrs, f.code, f.igraph)
        swap.split_reg_live_subsets(live_regs, f.code)
        swaps = swap.get_reg_swaps(live_regs)
        preservs, avail_regs = preserv.get_reg_preservations(f)

        for g in gadgets:

            print "0x%08x (%s%s) # %s" % (g.start, color[g.red],
                                          overlap[g.overlap], g.string)

            if g.red:
                continue

            if g.func_ea != g.end_func_ea:
                print "gadget spans in two or more functions!"

            entropy, eliminated = get_entropy(f, g, live_regs, swaps, preservs,
                                              avail_regs)
Пример #7
0
            func_gads[g.func_ea] = []
        func_gads[g.func_ea].append(g)

    for func_ea, gadgets in func_gads.iteritems():
        # there is nothing we can do ..
        if func_ea == None:
            continue

        f = functions[func_ea]

        # do analysis!
        swap.liveness_analysis(f.code)
        live_regs = swap.get_reg_live_subsets(f.instrs, f.code, f.igraph)
        swap.split_reg_live_subsets(live_regs, f.code)
        swaps = swap.get_reg_swaps(live_regs)
        preservs, avail_regs = preserv.get_reg_preservations(f)

        for g in gadgets:

            print "0x%08x (%s%s) # %s" % (g.start,
                                          color[g.red], overlap[g.overlap], g.string)

            if g.red:
                continue

            if g.func_ea != g.end_func_ea:
                print "gadget spans in two or more functions!"

            entropy, eliminated = get_entropy(f, g, live_regs, swaps, preservs, avail_regs)

            expl_entropy *= entropy