{ lib, stdenv, stdenvNoCC, fetchFromGitHub, callPackage, makeWrapper, clang, llvm, gcc, which, libcgroup, python3, perl, gmp, file, wine ? null, cmocka, llvmPackages, }: # wine fuzzing is only known to work for win32 binaries, and using a mixture of # 32 and 64-bit libraries ... complicates things, so it's recommended to build # a full 32bit version of this package if you want to do wine fuzzing assert (wine != null) -> (stdenv.targetPlatform.system == "i686-linux"); let aflplusplus-qemu = callPackage ./qemu.nix { }; qemu-exe-name = if stdenv.targetPlatform.system == "x86_64-linux" then "qemu-x86_64" else if stdenv.targetPlatform.system == "i686-linux" then "qemu-i386" else throw "aflplusplus: no support for ${stdenv.targetPlatform.system}!"; libdislocator = callPackage ./libdislocator.nix { inherit aflplusplus; }; libtokencap = callPackage ./libtokencap.nix { inherit aflplusplus; }; aflplusplus = stdenvNoCC.mkDerivation rec { pname = "aflplusplus"; version = "4.21c"; src = fetchFromGitHub { owner = "AFLplusplus"; repo = "AFLplusplus"; rev = "refs/tags/v${version}"; hash = "sha256-DKwPRxSO+JEJYWLldnfrAYqzwqukNzrbo4R5FzJqzzg="; }; enableParallelBuilding = true; # Note: libcgroup isn't needed for building, just for the afl-cgroup # script. nativeBuildInputs = [ makeWrapper which clang gcc ]; buildInputs = [ llvm python3 gmp llvmPackages.bintools ] ++ lib.optional (wine != null) python3.pkgs.wrapPython; # Flag is already set by package and causes some compiler warnings. # warning: "_FORTIFY_SOURCE" redefined hardeningDisable = [ "fortify" ]; postPatch = '' # Don't care about this. rm Android.bp # Replace the CLANG_BIN variables with the correct path. # Replace "gcc" and friends with full paths in afl-gcc. # Prevents afl-gcc picking up any (possibly incorrect) gcc from the path. # Replace LLVM_BINDIR with a non-existing path to give a hard error when it's used. substituteInPlace src/afl-cc.c \ --replace-fail "CLANGPP_BIN" '"${clang}/bin/clang++"' \ --replace-fail "CLANG_BIN" '"${clang}/bin/clang"' \ --replace-fail '"gcc"' '"${gcc}/bin/gcc"' \ --replace-fail '"g++"' '"${gcc}/bin/g++"' \ --replace-fail 'getenv("AFL_PATH")' "(getenv(\"AFL_PATH\") ? getenv(\"AFL_PATH\") : \"$out/lib/afl\")" substituteInPlace src/afl-ld-lto.c \ --replace-fail 'LLVM_BINDIR' '"/nixpkgs-patched-does-not-exist"' # Remove the rest of the line sed -i 's|LLVM_BINDIR = .*|LLVM_BINDIR = |' utils/aflpp_driver/GNUmakefile substituteInPlace utils/aflpp_driver/GNUmakefile \ --replace-fail 'LLVM_BINDIR = ' 'LLVM_BINDIR = ${clang}/bin/' substituteInPlace GNUmakefile.llvm \ --replace-fail "\$(LLVM_BINDIR)/clang" "${clang}/bin/clang" ''; env.NIX_CFLAGS_COMPILE = toString [ # Needed with GCC 12 "-Wno-error=use-after-free" ]; makeFlags = [ "PREFIX=${placeholder "out"}" "USE_BINDIR=0" ]; buildPhase = '' runHook preBuild common="$makeFlags -j$NIX_BUILD_CORES" make distrib $common make -C qemu_mode/libcompcov $common make -C qemu_mode/unsigaction $common runHook postBuild ''; postInstall = '' # remove afl-clang(++) which are just symlinks to afl-clang-fast rm $out/bin/afl-clang $out/bin/afl-clang++ # the makefile neglects to install unsigaction cp qemu_mode/unsigaction/unsigaction*.so $out/lib/afl/ # Install the custom QEMU emulator for binary blob fuzzing. ln -s ${aflplusplus-qemu}/bin/${qemu-exe-name} $out/bin/afl-qemu-trace # give user a convenient way of accessing libcompconv.so, libdislocator.so, libtokencap.so cat > $out/bin/get-afl-qemu-libcompcov-so <