summary refs log tree commit diff
path: root/pkgs/development/tools/analysis
diff options
context:
space:
mode:
authorTimo Kaufmann <timokau@zoho.com>2018-10-10 23:17:53 +0200
committerTimo Kaufmann <timokau@zoho.com>2018-10-11 23:53:00 +0200
commita33dec8cd58421ed8b03b3254b5a80b42eba6d1f (patch)
treeb64ab617685bac6e76330fe90945c4a83a68fbca /pkgs/development/tools/analysis
parent34786711d94adffb60bf827a04b42c76377d9c28 (diff)
downloadnixlib-a33dec8cd58421ed8b03b3254b5a80b42eba6d1f.tar
nixlib-a33dec8cd58421ed8b03b3254b5a80b42eba6d1f.tar.gz
nixlib-a33dec8cd58421ed8b03b3254b5a80b42eba6d1f.tar.bz2
nixlib-a33dec8cd58421ed8b03b3254b5a80b42eba6d1f.tar.lz
nixlib-a33dec8cd58421ed8b03b3254b5a80b42eba6d1f.tar.xz
nixlib-a33dec8cd58421ed8b03b3254b5a80b42eba6d1f.tar.zst
nixlib-a33dec8cd58421ed8b03b3254b5a80b42eba6d1f.zip
retdec: 3.0 -> 3.2
Diffstat (limited to 'pkgs/development/tools/analysis')
-rw-r--r--pkgs/development/tools/analysis/retdec/default.nix245
-rw-r--r--pkgs/development/tools/analysis/retdec/yaracpp.nix49
2 files changed, 220 insertions, 74 deletions
diff --git a/pkgs/development/tools/analysis/retdec/default.nix b/pkgs/development/tools/analysis/retdec/default.nix
index a4c62e6fc32c..428ca259f496 100644
--- a/pkgs/development/tools/analysis/retdec/default.nix
+++ b/pkgs/development/tools/analysis/retdec/default.nix
@@ -1,121 +1,218 @@
-{ stdenv, fetchFromGitHub, fetchurl, fetchzip,
-# Native build inputs
-cmake,
-autoconf, automake, libtool,
-pkgconfig,
-bison, flex,
-groff,
-perl,
-python,
-# Runtime tools
-time,
-upx,
-# Build inputs
-ncurses,
-libffi,
-libxml2,
-zlib,
-# PE (Windows) data, huge space savings if not needed
-withPEPatterns ? false,
+{ stdenv
+, fetchFromGitHub
+, fetchzip
+, lib
+, callPackage
+, openssl
+, cmake
+, autoconf
+, automake
+, libtool
+, pkgconfig
+, bison
+, flex
+, groff
+, perl
+, python3
+, time
+, upx
+, ncurses
+, libffi
+, libxml2
+, zlib
+, withPEPatterns ? false
 }:
 
 let
-  release = "3.0";
-
+  capstone = fetchFromGitHub {
+    owner = "avast-tl";
+    repo = "capstone";
+    rev = "27c713fe4f6eaf9721785932d850b6291a6073fe";
+    sha256 = "105z1g9q7s6n15qpln9vzhlij7vj6cyc5dqdr05n7wzjvlagwgxc";
+  };
+  elfio = fetchFromGitHub {
+    owner = "avast-tl";
+    repo = "elfio";
+    rev = "998374baace397ea98f3b1d768e81c978b4fba41";
+    sha256 = "09n34rdp0wpm8zy30zx40wkkc4gbv2k3cv181y6c1260rllwk5d1";
+  };
+  keystone = fetchFromGitHub { # only for tests
+    owner = "keystone-engine";
+    repo = "keystone";
+    rev = "d7ba8e378e5284e6384fc9ecd660ed5f6532e922";
+    sha256 = "1yzw3v8xvxh1rysh97y0i8y9svzbglx2zbsqjhrfx18vngh0x58f";
+  };
+  libdwarf = fetchFromGitHub {
+    owner = "avast-tl";
+    repo = "libdwarf";
+    rev = "85465d5e235cc2d2f90d04016d6aca1a452d0e73";
+    sha256 = "11y62r65py8yp57i57a4cymxispimn62by9z4j2g19hngrpsgbki";
+  };
+  llvm = fetchFromGitHub {
+    owner = "avast-tl";
+    repo = "llvm";
+    rev = "725d0cee133c6ab9b95c493f05de3b08016f5c3c";
+    sha256 = "0dzvafmn4qs62w1y9vh0a11clpj6q3hb41aym4izpcyybjndf9bq";
+  };
+  pelib = fetchFromGitHub {
+    owner = "avast-tl";
+    repo = "pelib";
+    rev = "a7004b2e80e4f6dc984f78b821e7b585a586050d";
+    sha256 = "0nyrb3g749lxgcymz1j584xbb1x6rvy1mc700lyn0brznvqsm81n";
+  };
   rapidjson = fetchFromGitHub {
     owner = "Tencent";
     repo = "rapidjson";
     rev = "v1.1.0";
     sha256 = "1jixgb8w97l9gdh3inihz7avz7i770gy2j2irvvlyrq3wi41f5ab";
   };
+  yaracpp = callPackage ./yaracpp.nix {}; # is its own package because it needs a patch
+  yaramod = fetchFromGitHub {
+    owner = "avast-tl";
+    repo = "yaramod";
+    rev = "v2.1.2";
+    sha256 = "1rpyqzkrqvk721hf75wb7aasw5mzp9wz4j89p0x1l9p5x1b3maz3";
+  };
   jsoncpp = fetchFromGitHub {
     owner = "open-source-parsers";
     repo = "jsoncpp";
-    rev = "1.8.3";
-    sha256 = "05gkmg6r94q8a0qdymarcjlnlvmy9s365m9jhz3ysvi71cr31lkz";
+    rev = "1.8.4";
+    sha256 = "1z0gj7a6jypkijmpknis04qybs1hkd04d1arr3gy89lnxmp6qzlm";
   };
-  googletest = fetchFromGitHub {
+  googletest = fetchFromGitHub { # only for tests
     owner = "google";
     repo = "googletest";
-    rev = "release-1.8.0";
-    sha256 = "0bjlljmbf8glnd9qjabx73w6pd7ibv43yiyngqvmvgxsabzr8399";
+    rev = "83fa0cb17dad47a1d905526dcdddb5b96ed189d2";
+    sha256 = "1c2r0p9v7vz2vasy8bknfb448l6wsvzw35s8hmc5z013z5502mpk";
   };
   tinyxml2 = fetchFromGitHub {
     owner = "leethomason";
     repo = "tinyxml2";
-    rev = "5.0.1";
+    rev = "cc1745b552dd12bb1297a99f82044f83b06729e0";
     sha256 = "015g8520a0c55gwmv7pfdsgfz2rpdmh3d1nq5n9bd65n35492s3q";
   };
-  yara = fetchurl {
-     url = "https://github.com/avast-tl/yara/archive/v1.0-retdec.zip";
-     sha256 = "1bjrkgp1sgld2y7gvwrlrz5fs16521ink6xyq72v7yxj3vfa9gps";
-  };
-  openssl = fetchurl {
-    url = "https://www.openssl.org/source/openssl-1.1.0f.tar.gz";
-    sha256 = "0r97n4n552ns571diz54qsgarihrxvbn7kvyv8wjyfs9ybrldxqj";
-  };
 
-  retdec-support = fetchzip {
-    url = "https://github.com/avast-tl/retdec-support/releases/download/2017-12-12/retdec-support_2017-12-12.tar.xz";
-    sha256 = if withPEPatterns then "0pchl7hb42dm0sdbmpr8d3c6xc0lm6cs4p6g6kdb2cr9c99gjzn3"
-                               else "1hcyq6bf4wk739kb53ic2bs71gsbx6zd07pc07lzfnxf8k497mhv";
+  retdec-support = let
+    version = "2018-02-08"; # make sure to adjust both hashes (once with withPEPatterns=true and once withPEPatterns=false)
+  in fetchzip {
+    url = "https://github.com/avast-tl/retdec-support/releases/download/${version}/retdec-support_${version}.tar.xz";
+    sha256 = if withPEPatterns then "148i8flbyj1y4kfdyzsz7jsj38k4h97npjxj18h6v4wksd4m4jm7"
+                               else "0ixv9qyqq40pzyqy6v9jf5rxrvivjb0z0zn260nbmb9gk765bacy";
+    stripRoot = false;
     # Removing PE signatures reduces this from 3.8GB -> 642MB (uncompressed)
-    extraPostFetch = stdenv.lib.optionalString (!withPEPatterns) ''
-      rm -rf $out/generic/yara_patterns/static-code/pe
+    extraPostFetch = lib.optionalString (!withPEPatterns) ''
+      rm -r "$out/generic/yara_patterns/static-code/pe"
     '';
+  } // {
+    inherit version; # necessary to check the version against the expected version
   };
+
+  # patch CMakeLists.txt for a dependency and compare the versions to the ones expected by upstream
+  # this has to be applied for every dependency (which it is in postPatch)
+  patchDep = dep: ''
+    # check if our version of dep is the same version that upstream expects
+    echo "Checking version of ${dep.dep_name}"
+    expected_rev="$( sed -n -e 's|.*URL https://github.com/.*/archive/\(.*\)\.zip.*|\1|p' "deps/${dep.dep_name}/CMakeLists.txt" )"
+    if [ "$expected_rev" != '${dep.rev}' ]; then
+      echo "The ${dep.dep_name} dependency has the wrong version: ${dep.rev} while $expected_rev is expected."
+      exit 1
+    fi
+
+    # patch the CMakeLists.txt file to use our local copy of the dependency instead of fetching it at build time
+    sed -i -e 's|URL .*|URL ${dep}|' "deps/${dep.dep_name}/CMakeLists.txt"
+  '';
+
 in stdenv.mkDerivation rec {
   name = "retdec-${version}";
-  version = "${release}.0";
+
+  # If you update this you will also need to adjust the versions of the updated dependencies. You can do this by first just updating retdec
+  # itself and trying to build it. The build should fail and tell you which dependencies you have to upgrade to which versions.
+  # I've notified upstream about this problem here:
+  # https://github.com/avast-tl/retdec/issues/412
+  version = "3.2";
 
   src = fetchFromGitHub {
     owner = "avast-tl";
     repo = "retdec";
-    name = "retdec-${release}";
-    rev = "refs/tags/v${release}";
-    sha256 = "0cpc5lxg8qphdzl3gg9dx992ar35r8ik8wyysr91l2qvfhx93wks";
-    fetchSubmodules = true;
+    name = "retdec-${version}";
+    rev = "refs/tags/v${version}";
+    sha256 = "0chky656lsddn20bnm3pmz6ix20y4a0y8swwr42hrhi01vkhmzrp";
   };
 
-  nativeBuildInputs = [ cmake autoconf automake libtool pkgconfig bison flex groff perl python ];
+  nativeBuildInputs = [
+    cmake
+    autoconf
+    automake
+    libtool
+    pkgconfig
+    bison
+    flex
+    groff
+    perl
+    python3
+  ];
 
-  buildInputs = [ ncurses libffi libxml2 zlib ];
+  buildInputs = [
+    openssl
+    ncurses
+    libffi
+    libxml2
+    zlib
+  ];
 
-  prePatch = ''
-    find . -wholename "*/deps/rapidjson/CMakeLists.txt" -print0 | \
-      xargs -0 sed -i -e 's|GIT_REPOSITORY.*|URL ${rapidjson}|'
-    find . -wholename "*/deps/jsoncpp/CMakeLists.txt" -print0 | \
-      xargs -0 sed -i -e 's|GIT_REPOSITORY.*|URL ${jsoncpp}|'
-    find . -wholename "*/deps/googletest/CMakeLists.txt" -print0 | \
-      xargs -0 sed -i -e 's|GIT_REPOSITORY.*|URL ${googletest}|'
-    find . -wholename "*/deps/tinyxml2/CMakeLists.txt" -print0 | \
-      xargs -0 sed -i -e 's|GIT_REPOSITORY.*|URL ${tinyxml2}|'
+  cmakeFlags = [
+    "-DRETDEC_TESTS=ON" # build tests
+  ];
 
-    find . -wholename "*/yaracpp/deps/CMakeLists.txt" -print0 | \
-      xargs -0 sed -i -e 's|URL .*|URL ${yara}|'
+  # all dependencies that are normally fetched during build time (the subdirectories of `deps`)
+  # all of these need to be fetched through nix and the CMakeLists files need to be patched not to fetch them themselves
+  external_deps = [
+    (capstone // { dep_name = "capstone"; })
+    (elfio // { dep_name = "elfio"; })
+    (googletest // { dep_name = "googletest"; })
+    (jsoncpp // { dep_name = "jsoncpp"; })
+    (keystone // { dep_name = "keystone"; })
+    (libdwarf // { dep_name = "libdwarf"; })
+    (llvm // { dep_name = "llvm"; })
+    (pelib // { dep_name = "pelib"; })
+    (rapidjson // { dep_name = "rapidjson"; })
+    (tinyxml2 // { dep_name = "tinyxml2"; })
+    (yaracpp // { dep_name = "yaracpp"; })
+    (yaramod // { dep_name = "yaramod"; })
+  ];
 
-    find . -wholename "*/deps/openssl/CMakeLists.txt" -print0 | \
-      xargs -0 sed -i -e 's|OPENSSL_URL .*)|OPENSSL_URL ${openssl})|'
+  postPatch = (lib.concatMapStrings patchDep external_deps) + ''
+    # install retdec-support
+    echo "Checking version of retdec-support"
+    expected_version="$( sed -n -e "s|^version = '\(.*\)'$|\1|p" 'cmake/install-share.py' )"
+    if [ "$expected_version" != '${retdec-support.version}' ]; then
+      echo "The retdec-support dependency has the wrong version: ${retdec-support.version} while $expected_version is expected."
+      exit 1
+    fi
+    mkdir -p "$out/share/retdec"
+    cp -r ${retdec-support} "$out/share/retdec/support" # write permission needed during install
+    chmod -R u+w "$out/share/retdec/support"
+    # python file originally responsible for fetching the retdec-support archive to $out/share/retdec
+    # that is not necessary anymore, so empty the file
+    echo > cmake/install-share.py
 
-    cat > cmake/install-share.sh <<EOF
-      #!/bin/sh
-      mkdir -p $out/share/retdec/
-      ln -s ${retdec-support} $out/share/retdec/support
-    EOF
-    chmod +x cmake/*.sh
-    patchShebangs cmake/*.sh
-
-    substituteInPlace scripts/unpack.sh --replace '	upx -d' '	${upx}/bin/upx -d'
-    substituteInPlace scripts/config.sh --replace /usr/bin/time ${time}/bin/time
+    # call correct `time` and `upx` programs
+    substituteInPlace scripts/retdec-config.py --replace /usr/bin/time ${time}/bin/time
+    substituteInPlace scripts/retdec-unpacker.py --replace "'upx'" "'${upx}/bin/upx'"
   '';
 
   enableParallelBuilding = true;
 
-  meta = with stdenv.lib; {
+  doInstallCheck = true;
+  installCheckPhase = ''
+    ${python3.interpreter} "$out/bin/retdec-tests-runner.py"
+  '';
+
+  meta = with lib; {
     description = "A retargetable machine-code decompiler based on LLVM";
     homepage = https://retdec.com;
     license = licenses.mit;
-    maintainers = with maintainers; [ dtzWill ];
-    broken = withPEPatterns; # retdec-full is broken, 2018-04-11
+    maintainers = with maintainers; [ dtzWill timokau ];
+    platforms = ["x86_64-linux" "i686-linux"];
   };
 }
diff --git a/pkgs/development/tools/analysis/retdec/yaracpp.nix b/pkgs/development/tools/analysis/retdec/yaracpp.nix
new file mode 100644
index 000000000000..cc857b86145f
--- /dev/null
+++ b/pkgs/development/tools/analysis/retdec/yaracpp.nix
@@ -0,0 +1,49 @@
+{ stdenv
+, fetchFromGitHub
+, coreutils
+}:
+
+let
+  yara = fetchFromGitHub {
+    owner = "avast-tl";
+    repo = "yara";
+    rev = "ea101c5856941f39cad2db3012f2660d1d5c8b65";
+    sha256 = "033ssx2hql5k4pv9si043s3mjq2b748ymjzif8pg6rdwh260faky";
+  };
+in stdenv.mkDerivation rec {
+  # only fetches the yaracpp source patched to work with a local yara clone,
+  # does not build anything
+  name = "yaracpp-src-${version}";
+  version = "2018-10-09";
+  rev = "b92bde0e59e3b75bc445227e04b71105771dee8b"; # as specified in retdec/deps/yaracpp/CMakeLists.txt
+
+  src = fetchFromGitHub {
+    inherit rev;
+    owner = "avast-tl";
+    repo = "yaracpp";
+    sha256 = "0fan7q79j7s3bjmhsd2nw6sqyi14xgikn7mr2p4nj87lick5l4a2";
+  };
+
+  postPatch = ''
+      # check if our version of yara is the same version that upstream expects
+      echo "Checking version of yara"
+      expected_rev="$( sed -n -e 's|.*URL https://github.com/.*/archive/\(.*\)\.zip.*|\1|p' "deps/CMakeLists.txt" )"
+      if [ "$expected_rev" != '${yara.rev}' ]; then
+        echo "The yara dependency has the wrong version: ${yara.rev} while $expected_rev is expected."
+        exit 1
+      fi
+
+      # patch the CMakeLists.txt file to use our local copy of the dependency instead of fetching it at build time
+      sed -i -e "s|URL .*|URL ${yara}|" "deps/CMakeLists.txt"
+
+      # abuse the CONFIGURE_COMMAND to make the source writeable after copying it to the build locatoin (necessary for the build)
+      sed -i -e 's|CONFIGURE_COMMAND ""|CONFIGURE_COMMAND COMMAND ${coreutils}/bin/chmod -R u+w .|' "deps/CMakeLists.txt"
+    '';
+
+  buildPhase = "# do nothing";
+  configurePhase = "# do nothing";
+  installPhase = ''
+    mkdir -p "$out"
+    cp -r * "$out"
+  '';
+}