예제 #1
0
    def instrument_init_array(self):
        #XXX: yet todo
        # this one is old version for x86, needs to be converted
        section = self.rewriter.container.sections[".init_array"]
        constructor = DataCell.instrumented(".quad {}".format(sp.ASAN_INIT_FN),
                                            8)
        section.cache.append(constructor)

        if ".fini_array" not in self.rewriter.container.sections:
            finiarr = DataSection(".fini_array", 0, 0, "")
            self.rewriter.container.add_section(finiarr)

        fini = self.rewriter.container.sections[".fini_array"]
        destructor = DataCell.instrumented(
            ".quad {}".format(sp.ASAN_DEINIT_FN), 8)
        fini.cache.append(destructor)

        initfn = Function(sp.ASAN_INIT_FN, ASAN_INIT_LOC, 0, "")
        initfn.set_instrumented()
        initcode = InstrumentedInstruction(
            '\n'.join(sp.MODULE_INIT).format(global_count=self.global_count),
            None, None)
        initfn.cache.append(initcode)
        self.rewriter.container.add_function(initfn)

        finifn = Function(sp.ASAN_DEINIT_FN, ASAN_DEINIT_LOC, 0, "")
        finifn.set_instrumented()
        finicode = InstrumentedInstruction(
            '\n'.join(sp.MODULE_DEINIT).format(global_count=self.global_count),
            None, None)
        finifn.cache.append(finicode)
        self.rewriter.container.add_function(finifn)
예제 #2
0
    def do_instrument(self):

        for faddr, fn in self.rewriter.container.functions.items():
            if fn.name in skipped_functions: continue
            if fn.name == "main":
                # we call afl_maybe_log the first time just after the main
                # preamble so that the forkserver is started as soon as possible
                # but not before main
                fn.cache[2].instrument_before(
                    self.get_mem_instrumentation(fn.cache[2], idx,
                                                 free_registers))
            for idx, instruction in enumerate(fn.cache):

                if instruction.mnemonic.startswith("b") and idx + 1 < len(
                        fn.cache):
                    next_instruction = fn.cache[
                        idx +
                        1]  # we need to instrument the instruction after the branch
                    if "invalid" in str(next_instruction): continue
                    free_registers = fn.analysis['free_registers'][
                        idx + 1] if fn.analysis else None
                    iinstr = self.get_mem_instrumentation(
                        next_instruction, idx + 1, free_registers)
                    next_instruction.instrument_before(iinstr)

        payload = main_payload_arm.format(
            FORKSRV_FD=FORKSRV_FD,
            FORKSRV_FD_1=FORKSRV_FD_1,
            AFL_STATUS_FLAGS=(FORKSRV_OPT_ENABLED | FS_OPT_MAPSIZE
                              | get_map_size(MAP_SIZE)))
        afl_sec = Section(".afl_sec", 0x200000, 0, None)
        afl_sec.cache.append(DataCell.instrumented(payload, 0))

        persistent_addr = os.getenv("AFL_PERSISTENT_ADDR", default=None)
        if persistent_addr is not None:
            self.instrument_persistent(persistent_addr)
            persistent_payload = persistent_instrumentation.format(
                persistent_function=persistent_addr,
                PERSISTENT_SIGNATURE=PERSISTENT_SIGNATURE)
            persistent_cycles = os.getenv("AFL_PERSISTENT_CYCLES",
                                          default=1000)
            persistent_payload_loop = persistent_loop.format(
                PERSISTENT_CYCLES=persistent_cycles,
                PREV_LOC_MEMSET_SIZE=PREV_LOC_MEMSET_SIZE,
                SIGSTOP_NUM=SIGSTOP_NUM,
                MAP_SIZE=MAP_SIZE)
            afl_sec.cache.append(DataCell.instrumented(persistent_payload, 0))
            afl_sec.cache.append(
                DataCell.instrumented(persistent_payload_loop, 0))

        self.rewriter.container.add_data_section(afl_sec)
예제 #3
0
    def to_instrumented(self):
        results = [
            ".quad {}".format(self.location),
            ".quad {}".format(self.sz),
            ".quad {}".format(self.sz_with_rz),
            ".quad {}".format(self.name),
            ".quad {}".format(self.mod_name),
            ".quad {}".format(self.has_dynamic_init),
            ".quad {}".format(0),
        ]

        return list(map(lambda x: DataCell.instrumented(x, 8), results))
예제 #4
0
    def instrument_globals(self):
        gmap = list()
        for _, sec in self.rewriter.container.sections.items():
            location = sec.base
            appends = defaultdict(list)
            for idx, cell in enumerate(sec.cache):
                if cell.ignored or cell.is_instrumented:
                    continue

                if location in sec.named_globals:
                    self.global_count += 1
                    gobj = sec.named_globals[location][0]
                    asan_global_meta = self.new_global_metadata(gobj)
                    gmap.append(asan_global_meta)
                    # Need to add padding.
                    # Redzone below the global
                    appends[location + gobj["sz"]].append(
                        asan_global_meta.pad_down)

                location += cell.sz

            location = sec.base
            oldcache = copy.copy(sec.cache)

            for idx, cell in enumerate(oldcache):
                if cell.is_instrumented or cell.ignored:
                    continue
                if location in appends:
                    for pad in appends[location]:
                        instrumented = DataCell.instrumented(
                            ".zero {}".format(pad), pad)
                        cell.instrument_after(instrumented)
                location += cell.sz

        ds = DataSection(".data.asan", ASAN_GLOBAL_DS_BASE, 0, None)
        ds.cache.append(
            DataCell.instrumented("{}:".format(sp.ASAN_GLOBAL_DS), 0))
        for meta in gmap:
            ds.cache.extend(meta.to_instrumented())
        self.rewriter.container.add_section(ds)
예제 #5
0
    def do_instrument(self):
        #self.instrument_globals()
        instrumentation = self.instrument_mem_accesses()

        ds = DataSection(".jumps", 0x100000, 0, None, flags="ax")
        # content = """
        # .file: .string \"/tmp/countfile\"
        # .perms: .string \"w\"
        # .format: .string \"%lld\\n\"
        # .align 3
        # .counted: .quad 0x0
        # """
        ds.cache.append(DataCell.instrumented(instrumentation, 0))
        self.rewriter.container.add_section(ds)
예제 #6
0
    def do_instrument(self):
        for faddr, fn in self.rewriter.container.functions.items():
            for idx, instruction in enumerate(fn.cache):

                # if any("adrp" in str(x) for x in instruction.before):
                if "br" in instruction.mnemonic:
                    iinstr = self.count_one(instruction, idx, None)
                    instruction.instrument_before(iinstr)

                if "blr" in instruction.mnemonic:
                    iinstr = self.count_two(instruction, idx, None)
                    instruction.instrument_before(iinstr)

        ds = Section(".counter", 0x100000, 0, None, flags="aw")
        content = """
        .file: .string \"/tmp/countfile\"
        .perms: .string \"a\"
        .format: .string \"br: %lld\\nblr: %lld\\n\"
        .align 3
        .counted: .quad 0x0
        .counted2: .quad 0x0
        """
        ds.cache.append(DataCell.instrumented(content, 0))
        self.rewriter.container.add_data_section(ds)

        ds = Section(".finiamola", 0x200000, 0, None, flags="ax")
        ds.align = 0
        instrumentation = """
        // build a pointer to .perms
        adrp x1, .perms
        add x1, x1, :lo12:.perms

        // build a pointer to .file
        adrp x0, .file
        add x0, x0, :lo12:.file

        // call the libc fopen(.file, .perms)
        bl fopen

        // load .counted in x2
        adrp x2, .counted
        ldr x2, [x2, :lo12:.counted]
        // load .counted in x3
        adrp x3, .counted2
        ldr x3, [x3, :lo12:.counted2]

        // build a pointer to .format
        adrp x1, .format
        add x1, x1, :lo12:.format

        // fprintf( fopen("/tmp/countfile", "a+"), "%lld", counted);
        bl fprintf

        bl exit
        """
        ds.cache.append(DataCell.instrumented(instrumentation, 0))
        self.rewriter.container.add_data_section(ds)

        self.rewriter.container.datasections[".fini_array"].cache.append(
            DataCell.instrumented(".quad .finiamola", 0))
        f = self.rewriter.container.codesections[".fini"].functions[0]
        self.rewriter.container.functions[f].cache[0].instrument_before(
            InstrumentedInstruction(instrumentation, 0))