Unverified Commit 1f42f627 authored by Jade Lovelace's avatar Jade Lovelace Committed by GitHub
Browse files

Merge pull request #310343 from vringar/ghidra-extensions

Ghidra extensions
parents 6d447251 a44a2981
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -21616,6 +21616,12 @@
    name = "Kostas Karachalios";
    githubId = 81346;
  };
  vringar = {
    email = "git@zabka.it";
    github = "vringar";
    name = "Stefan Zabka";
    githubId = 13276717;
  };
  vrthra = {
    email = "rahul@gopinath.org";
    github = "vrthra";
+15 −0
Original line number Diff line number Diff line
diff --git a/Ghidra/Framework/Utility/src/main/java/utility/application/ApplicationUtilities.java b/Ghidra/Framework/Utility/src/main/java/utility/application/ApplicationUtilities.java
index ea12a661f0..da7779b07f 100644
--- a/Ghidra/Framework/Utility/src/main/java/utility/application/ApplicationUtilities.java
+++ b/Ghidra/Framework/Utility/src/main/java/utility/application/ApplicationUtilities.java
@@ -36,6 +36,10 @@ public class ApplicationUtilities {
 	 */
 	public static Collection<ResourceFile> findDefaultApplicationRootDirs() {
 		Collection<ResourceFile> applicationRootDirs = new ArrayList<>();
+		String nixGhidraHome = System.getenv("NIX_GHIDRAHOME");
+		if (nixGhidraHome != null) {
+			applicationRootDirs.add(new ResourceFile(nixGhidraHome));
+		};
 		ResourceFile applicationRootDir = findPrimaryApplicationRootDir();
 		if (applicationRootDir != null) {
 			applicationRootDirs.add(applicationRootDir);
+26 −0
Original line number Diff line number Diff line
diff --git a/Ghidra/RuntimeScripts/Common/support/buildExtension.gradle b/Ghidra/RuntimeScripts/Common/support/buildExtension.gradle
index bc194f219..94b00fabd 100644
--- a/Ghidra/RuntimeScripts/Common/support/buildExtension.gradle
+++ b/Ghidra/RuntimeScripts/Common/support/buildExtension.gradle
@@ -82,7 +82,7 @@ dependencies {
 	helpPath fileTree(dir: ghidraDir + '/Features/Base', include: "**/Base.jar")
 }
 	
-def ZIP_NAME_PREFIX = "${DISTRO_PREFIX}_${RELEASE_NAME}_${getCurrentDate()}"
+def ZIP_NAME_PREFIX = "${DISTRO_PREFIX}_${RELEASE_NAME}"
 def DISTRIBUTION_DIR = file("dist")
 	
 def pathInZip = "${project.name}"
diff --git a/gradle/root/distribution.gradle b/gradle/root/distribution.gradle
index f44c8267b..f6231c417 100644
--- a/gradle/root/distribution.gradle
+++ b/gradle/root/distribution.gradle
@@ -32,7 +32,7 @@ apply from: "$rootProject.projectDir/gradle/support/sbom.gradle"
 def currentPlatform = getCurrentPlatformName()
 def PROJECT_DIR = file (rootProject.projectDir.absolutePath)
 ext.DISTRIBUTION_DIR = file("$buildDir/dist")
-ext.ZIP_NAME_PREFIX = "${rootProject.DISTRO_PREFIX}_${rootProject.BUILD_DATE_SHORT}"
+ext.ZIP_NAME_PREFIX = "${rootProject.DISTRO_PREFIX}"
 ext.ZIP_DIR_PREFIX = "${rootProject.DISTRO_PREFIX}"
 ext.ALL_REPOS = [rootProject.file('.').getName()]
 
+78 −0
Original line number Diff line number Diff line
{ lib
, stdenv
, unzip
, jdk
, gradle
, ghidra
}:

let
  metaCommon = oldMeta:
    oldMeta // (with lib; {
      maintainers = (oldMeta.maintainers or []) ++ (with maintainers; [ vringar ]);
      platforms = oldMeta.platforms or ghidra.meta.platforms;
    });

  buildGhidraExtension = {
    pname, nativeBuildInputs ? [], meta ? { }, ...
  }@args:
    stdenv.mkDerivation (args // {
      nativeBuildInputs = nativeBuildInputs ++ [
        unzip
        jdk
        gradle
      ];

      buildPhase = args.buildPhase or ''
        runHook preBuild

        # Set project name, otherwise defaults to directory name
        echo -e '\nrootProject.name = "${pname}"' >> settings.gradle

        export GRADLE_USER_HOME=$(mktemp -d)
        gradle \
          --offline \
          --no-daemon \
          -PGHIDRA_INSTALL_DIR=${ghidra}/lib/ghidra

        runHook postBuild
      '';

      installPhase = args.installPhase or ''
        runHook preInstall

        mkdir -p $out/lib/ghidra/Ghidra/Extensions
        unzip -d $out/lib/ghidra/Ghidra/Extensions dist/*.zip

        runHook postInstall
      '';

      meta = metaCommon meta;
    });

  buildGhidraScripts = { pname, meta ? { }, ... }@args:
    stdenv.mkDerivation (args // {
      installPhase = ''
        runHook preInstall

        GHIDRA_HOME=$out/lib/ghidra/Ghidra/Extensions/${pname}
        mkdir -p $GHIDRA_HOME
        cp -r . $GHIDRA_HOME/ghidra_scripts

        touch $GHIDRA_HOME/Module.manifest
        cat <<'EOF' > extension.properties
        name=${pname}
        description=${meta.description or ""}
        author=
        createdOn=
        version=${lib.getVersion ghidra}

        EOF

        runHook postInstall
      '';

      meta = metaCommon meta;
    });
in
  { inherit buildGhidraExtension buildGhidraScripts; }
+61 −11
Original line number Diff line number Diff line
{ stdenv
, fetchFromGitHub
, lib
, callPackage
, gradle_7
, perl
, makeWrapper
@@ -10,6 +11,7 @@
, icoutils
, xcbuild
, protobuf
, ghidra-extensions
}:

let
@@ -17,15 +19,40 @@ let
  pname = "ghidra";
  version = "11.0.3";

  releaseName = "NIX";
  distroPrefix = "ghidra_${version}_${releaseName}";
  src = fetchFromGitHub {
    owner = "NationalSecurityAgency";
    repo = "Ghidra";
    rev = "Ghidra_${version}_build";
    hash = "sha256-Id595aKYHP1R3Zw9sV1oL32nAUAr7D/K4wn6Zs7q3Jo=";
    hash = "sha256-IiLxaJvfJcK275FDZEsUCGp7haJjp8O2fUIoM4F9H30=";
    # populate values that require us to use git. By doing this in postFetch we
    # can delete .git afterwards and maintain better reproducibility of the src.
    leaveDotGit = true;
    postFetch = ''
      cd "$out"
      git rev-parse HEAD > $out/COMMIT
      # 1970-Jan-01
      date -u -d "@$(git log -1 --pretty=%ct)" "+%Y-%b-%d" > $out/SOURCE_DATE_EPOCH
      # 19700101
      date -u -d "@$(git log -1 --pretty=%ct)" "+%Y%m%d" > $out/SOURCE_DATE_EPOCH_SHORT
      find "$out" -name .git -print0 | xargs -0 rm -rf
    '';
  };

  gradle = gradle_7;

  patches = [
    # Use our own protoc binary instead of the prebuilt one
    ./0001-Use-protobuf-gradle-plugin.patch

    # Override installation directory to allow loading extensions
    ./0002-Load-nix-extensions.patch

    # Remove build dates from output filenames for easier reference
    ./0003-Remove-build-datestamp.patch
  ];

  desktopItem = makeDesktopItem {
    name = "ghidra";
    exec = "ghidra";
@@ -35,7 +62,25 @@ let
    categories = [ "Development" ];
  };

  # postPatch scripts.
  postPatch = ''
    # Set name of release (eg. PUBLIC, DEV, etc.)
    sed -i -e 's/application\.release\.name=.*/application.release.name=${releaseName}/' Ghidra/application.properties

    # Set build date and git revision
    echo "application.build.date=$(cat SOURCE_DATE_EPOCH)" >> Ghidra/application.properties
    echo "application.build.date.short=$(cat SOURCE_DATE_EPOCH_SHORT)" >> Ghidra/application.properties
    echo "application.revision.ghidra=$(cat COMMIT)" >> Ghidra/application.properties

    # Tells ghidra to use our own protoc binary instead of the prebuilt one.
    cat >>Ghidra/Debug/Debugger-gadp/build.gradle <<HERE
    protobuf {
      protoc {
        path = '${protobuf}/bin/protoc'
      }
    }
    HERE
  '';

  # Adds a gradle step that downloads all the dependencies to the gradle cache.
  addResolveStep = ''
    cat >>build.gradle <<HERE
@@ -64,9 +109,8 @@ HERE
  # Taken from mindustry derivation.
  deps = stdenv.mkDerivation {
    pname = "${pname}-deps";
    inherit version src;
    inherit version src patches;

    patches = [ ./0001-Use-protobuf-gradle-plugin.patch ];
    postPatch = addResolveStep;

    nativeBuildInputs = [ gradle perl ] ++ lib.optional stdenv.isDarwin xcbuild;
@@ -98,8 +142,8 @@ HERE
    outputHash = "sha256-nKfJiGoZlDEpbCmYVKNZXz2PYIosCd4nPFdy3MfprHc=";
  };

in stdenv.mkDerivation {
  inherit pname version src;
in stdenv.mkDerivation (finalAttrs: {
  inherit pname version src patches postPatch;

  nativeBuildInputs = [
    gradle unzip makeWrapper icoutils protobuf
@@ -107,9 +151,7 @@ in stdenv.mkDerivation {

  dontStrip = true;

  patches = [
    ./0001-Use-protobuf-gradle-plugin.patch
  ];
  __darwinAllowLocalNetworking = true;

  buildPhase = ''
    runHook preBuild
@@ -152,9 +194,17 @@ in stdenv.mkDerivation {
    mkdir -p "$out/bin"
    ln -s "${pkg_path}/ghidraRun" "$out/bin/ghidra"
    wrapProgram "${pkg_path}/support/launch.sh" \
      --set-default NIX_GHIDRAHOME "${pkg_path}/Ghidra" \
      --prefix PATH : ${lib.makeBinPath [ openjdk17 ]}
  '';

  passthru = {
    inherit releaseName distroPrefix;
    inherit (ghidra-extensions.override { ghidra = finalAttrs.finalPackage; }) buildGhidraExtension buildGhidraScripts;

    withExtensions = callPackage ./with-extensions.nix { ghidra = finalAttrs.finalPackage; };
  };

  meta = with lib; {
    description = "A software reverse engineering (SRE) suite of tools developed by NSA's Research Directorate in support of the Cybersecurity mission";
    mainProgram = "ghidra";
@@ -165,8 +215,8 @@ in stdenv.mkDerivation {
      binaryBytecode  # deps
    ];
    license = licenses.asl20;
    maintainers = with maintainers; [ roblabla ];
    maintainers = with maintainers; [ roblabla vringar ];
    broken = stdenv.isDarwin && stdenv.isx86_64;
  };

}
})
Loading