# from the maturin venv, after running 'maturin develop' in the pylibafl directory from pylibafl import sugar, qemu import lief MAX_SIZE = 0x100 BINARY_PATH = "./a.out" emu = qemu.Qemu(["qemu-x86_64", BINARY_PATH]) elf = lief.parse(BINARY_PATH) test_one_input = elf.get_function_address("LLVMFuzzerTestOneInput") if elf.is_pie: test_one_input += emu.load_addr() print("LLVMFuzzerTestOneInput @ 0x%x" % test_one_input) emu.set_breakpoint(test_one_input) emu.run() sp = emu.read_reg(qemu.regs.Rsp) print("SP = 0x%x" % sp) retaddr = int.from_bytes(emu.read_mem(sp, 8), "little") print("RET = 0x%x" % retaddr) inp = emu.map_private(0, MAX_SIZE, qemu.mmap.ReadWrite) assert inp > 0 emu.remove_breakpoint(test_one_input) emu.set_breakpoint(retaddr) def harness(b): if len(b) > MAX_SIZE: b = b[:MAX_SIZE] emu.write_mem(inp, b) emu.write_reg(qemu.regs.Rsi, len(b)) emu.write_reg(qemu.regs.Rdi, inp) emu.write_reg(qemu.regs.Rsp, sp) emu.write_reg(qemu.regs.Rip, test_one_input) emu.run() # Create a fuzzer using the launcher # with 4 instances bounds to cores 0-3 # LLMP uses port 3456 to synchronize # stdout from the target is NOT redirected to /dev/null fuzz = sugar.QemuBytesCoverageSugar( ["./in"], "./out", 3456, [0, 1, 2, 3], enable_stdout=True ) fuzz.run(emu, harness)