5f19ec3bc4
i don't think running the unit tests really adds anything given that we have proper integration tests working, and it just introduces another build dependency and possibility for spurious breakage.
136 lines
5.4 KiB
Nix
136 lines
5.4 KiB
Nix
{ stdenv, stdenvNoCC, fetchFromGitHub, callPackage, makeWrapper
|
|
, clang_9, llvm_9, gcc, which, libcgroup, python, perl, gmp
|
|
, file, wine ? null, fetchpatch
|
|
}:
|
|
|
|
# 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 { inherit aflplusplus; };
|
|
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 = "2.65c";
|
|
|
|
src = fetchFromGitHub {
|
|
owner = "AFLplusplus";
|
|
repo = "AFLplusplus";
|
|
rev = version;
|
|
sha256 = "1np2a3kypb2m8nyv6qnij18yzn41pl8619jzydci40br4vxial9l";
|
|
};
|
|
enableParallelBuilding = true;
|
|
|
|
# Note: libcgroup isn't needed for building, just for the afl-cgroup
|
|
# script.
|
|
nativeBuildInputs = [ makeWrapper which clang_9 gcc ];
|
|
buildInputs = [ llvm_9 python gmp ]
|
|
++ stdenv.lib.optional (wine != null) python.pkgs.wrapPython;
|
|
|
|
|
|
postPatch = ''
|
|
# Replace the CLANG_BIN variables with the correct path
|
|
substituteInPlace llvm_mode/afl-clang-fast.c \
|
|
--replace "CLANGPP_BIN" '"${clang_9}/bin/clang++"' \
|
|
--replace "CLANG_BIN" '"${clang_9}/bin/clang"' \
|
|
--replace 'getenv("AFL_PATH")' "(getenv(\"AFL_PATH\") ? getenv(\"AFL_PATH\") : \"$out/lib/afl\")"
|
|
|
|
# Replace "gcc" and friends with full paths in afl-gcc
|
|
# Prevents afl-gcc picking up any (possibly incorrect) gcc from the path
|
|
substituteInPlace src/afl-gcc.c \
|
|
--replace '"gcc"' '"${gcc}/bin/gcc"' \
|
|
--replace '"g++"' '"${gcc}/bin/g++"' \
|
|
--replace '"gcj"' '"gcj-UNSUPPORTED"' \
|
|
--replace '"clang"' '"clang-UNSUPPORTED"' \
|
|
--replace '"clang++"' '"clang++-UNSUPPORTED"'
|
|
'';
|
|
|
|
makeFlags = [ "PREFIX=$(out)" ];
|
|
buildPhase = ''
|
|
common="$makeFlags -j$NIX_BUILD_CORES"
|
|
make all $common
|
|
make radamsa $common
|
|
make -C gcc_plugin CC=${gcc}/bin/gcc CXX=${gcc}/bin/g++ $common
|
|
make -C llvm_mode $common
|
|
make -C qemu_mode/libcompcov $common
|
|
make -C qemu_mode/unsigaction $common
|
|
'';
|
|
|
|
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.
|
|
cp ${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 <<END
|
|
#!${stdenv.shell}
|
|
echo $out/lib/afl/libcompcov.so
|
|
END
|
|
chmod +x $out/bin/get-afl-qemu-libcompcov-so
|
|
cp ${libdislocator}/bin/get-libdislocator-so $out/bin/
|
|
cp ${libtokencap}/bin/get-libtokencap-so $out/bin/
|
|
|
|
# Install the cgroups wrapper for asan-based fuzzing.
|
|
cp examples/asan_cgroups/limit_memory.sh $out/bin/afl-cgroup
|
|
chmod +x $out/bin/afl-cgroup
|
|
substituteInPlace $out/bin/afl-cgroup \
|
|
--replace "cgcreate" "${libcgroup}/bin/cgcreate" \
|
|
--replace "cgexec" "${libcgroup}/bin/cgexec" \
|
|
--replace "cgdelete" "${libcgroup}/bin/cgdelete"
|
|
|
|
patchShebangs $out/bin
|
|
|
|
'' + stdenv.lib.optionalString (wine != null) ''
|
|
substitute afl-wine-trace $out/bin/afl-wine-trace \
|
|
--replace "qemu_mode/unsigaction" "$out/lib/afl"
|
|
chmod +x $out/bin/afl-wine-trace
|
|
|
|
# qemu needs to be fed ELFs, not wrapper scripts, so we have to cheat a bit if we
|
|
# detect a wrapped wine
|
|
for winePath in ${wine}/bin/.wine ${wine}/bin/wine; do
|
|
if [ -x $winePath ]; then break; fi
|
|
done
|
|
makeWrapperArgs="--set-default 'AFL_WINE_PATH' '$winePath'" \
|
|
wrapPythonProgramsIn $out/bin ${python.pkgs.pefile}
|
|
'';
|
|
|
|
installCheckInputs = [ perl file ];
|
|
doInstallCheck = true;
|
|
installCheckPhase = ''
|
|
# replace references to tools in build directory with references to installed locations
|
|
substituteInPlace test/test.sh \
|
|
--replace '../libcompcov.so' '`$out/bin/get-afl-qemu-libcompcov-so`' \
|
|
--replace '../libdislocator.so' '`$out/bin/get-libdislocator-so`' \
|
|
--replace '../libtokencap.so' '`$out/bin/get-libtokencap-so`'
|
|
perl -pi -e 's|(?<!\.)(?<!-I)(\.\./)([^\s\/]+?)(?<!\.c)(?<!\.s?o)(?=\s)|\$out/bin/\2|g' test/test.sh
|
|
cd test && ./test.sh
|
|
'';
|
|
|
|
passthru = {
|
|
inherit libdislocator libtokencap;
|
|
qemu = aflplusplus-qemu;
|
|
};
|
|
|
|
meta = {
|
|
description = ''
|
|
AFL++ is a heavily enhanced version of AFL, incorporating many features and
|
|
improvements from the community.
|
|
'';
|
|
homepage = "https://aflplus.plus";
|
|
license = stdenv.lib.licenses.asl20;
|
|
platforms = ["x86_64-linux" "i686-linux"];
|
|
maintainers = with stdenv.lib.maintainers; [ ris mindavi ];
|
|
};
|
|
};
|
|
in aflplusplus
|