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)
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)
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))
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)
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)
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))