diff --git a/pkgs/development/python-modules/ghidra-bridge/default.nix b/pkgs/development/python-modules/ghidra-bridge/default.nix new file mode 100644 index 000000000000..2c50519da9bd --- /dev/null +++ b/pkgs/development/python-modules/ghidra-bridge/default.nix @@ -0,0 +1,43 @@ +{ + lib, + buildPythonPackage, + fetchFromGitHub, + jfx-bridge, + setuptools, +}: + +buildPythonPackage rec { + pname = "ghidra-bridge"; + version = "1.0.0"; + pyproject = true; + + src = fetchFromGitHub { + owner = "justfoxing"; + repo = "ghidra_bridge"; + tag = version; + hash = "sha256-VcAl1tamsuHvZRtBP0+DCl2A9d7E6aoj2AbJhEcBNMM="; + }; + + patches = [ ./no-invoke-git.patch ]; + + postPatch = '' + substituteInPlace ./setup.py --subst-var-by version ${version} + ''; + + build-system = [ setuptools ]; + + dependencies = [ jfx-bridge ]; + + # Tests require a running server instance + doCheck = false; + + pythonImportsCheck = [ "ghidra_bridge" ]; + + meta = { + description = "Python bridge to Ghidra's Python scripting"; + homepage = "https://github.com/justfoxing/ghidra_bridge"; + changelog = "https://github.com/justfoxing/ghidra_bridge/releases/tag/${src.tag}"; + license = lib.licenses.mit; + maintainers = with lib.maintainers; [ scoder12 ]; + }; +} diff --git a/pkgs/development/python-modules/ghidra-bridge/no-invoke-git.patch b/pkgs/development/python-modules/ghidra-bridge/no-invoke-git.patch new file mode 100644 index 000000000000..f82ebccde6ea --- /dev/null +++ b/pkgs/development/python-modules/ghidra-bridge/no-invoke-git.patch @@ -0,0 +1,13 @@ +diff --git a/setup.py b/setup.py +index 9a2abe0..75ce109 100644 +--- a/setup.py ++++ b/setup.py +@@ -6,7 +6,7 @@ with open("README.md", "r") as fh: + + # determine the version, then write it out into the bridge.py file + version = ( +- subprocess.check_output("git describe --tags", shell=True).decode("utf-8").strip() ++ "@version@" + ) + # check if this is a non-tag release and remark it as a dev release + if "-" in version: diff --git a/pkgs/development/python-modules/jfx-bridge/default.nix b/pkgs/development/python-modules/jfx-bridge/default.nix new file mode 100644 index 000000000000..2c261be4b96a --- /dev/null +++ b/pkgs/development/python-modules/jfx-bridge/default.nix @@ -0,0 +1,52 @@ +{ + lib, + buildPythonPackage, + fetchFromGitHub, + pytestCheckHook, + python, + setuptools, +}: + +buildPythonPackage rec { + pname = "jfx-bridge"; + version = "1.0.0"; + pyproject = true; + + src = fetchFromGitHub { + owner = "justfoxing"; + repo = "jfx_bridge"; + tag = version; + hash = "sha256-fpUrKNGqTpthhTfohCbwO1GBDAP/YnLWeapVhZftldg="; + }; + + patches = [ ./no-invoke-git.patch ]; + + postPatch = '' + substituteInPlace ./setup.py --subst-var-by version ${version} + ''; + + build-system = [ setuptools ]; + + nativeCheckInputs = [ pytestCheckHook ]; + + preCheck = '' + ${python.interpreter} test_bridge_server.py & + ''; + + disabledTests = [ + # known to cause timeout with newer python (acknowledged in test comment) + "test_nonreturn_marker_local" + # the mechanisms that hook into the python import machinery seem broken on newer python + "TestBridgeHookImport" + ]; + + pythonImportsCheck = [ "jfx_bridge" ]; + + meta = { + description = "Base Python RPC bridge used for ghidra_bridge"; + homepage = "https://github.com/justfoxing/jfx_bridge"; + changelog = "https://github.com/justfoxing/jfx_bridge/releases/tag/${src.tag}"; + license = lib.licenses.mit; + maintainers = with lib.maintainers; [ scoder12 ]; + }; +} diff --git a/pkgs/development/python-modules/jfx-bridge/no-invoke-git.patch b/pkgs/development/python-modules/jfx-bridge/no-invoke-git.patch new file mode 100644 index 000000000000..2c1f53ca2d6c --- /dev/null +++ b/pkgs/development/python-modules/jfx-bridge/no-invoke-git.patch @@ -0,0 +1,13 @@ +diff --git a/setup.py b/setup.py +index 079cb01..c5e71b8 100644 +--- a/setup.py ++++ b/setup.py +@@ -6,7 +6,7 @@ with open("README.md", "r") as fh: + long_description = fh.read() + + # determine the version, then write it out into the bridge.py file +-version = subprocess.check_output("git describe --tags", shell=True).decode("utf-8").strip() ++version = "@version@" + # check if this is a non-tag release and remark it as a dev release + if "-" in version: + ver, commits, hash = version.split("-") diff --git a/pkgs/development/python-modules/libbs/default.nix b/pkgs/development/python-modules/libbs/default.nix new file mode 100644 index 000000000000..3fb3de5bd5f8 --- /dev/null +++ b/pkgs/development/python-modules/libbs/default.nix @@ -0,0 +1,69 @@ +{ + lib, + buildPythonPackage, + fetchFromGitHub, + filelock, + ghidra-bridge, + jfx-bridge, + networkx, + platformdirs, + prompt-toolkit, + psutil, + pycparser, + pyhidra, + pytestCheckHook, + setuptools, + toml, + tqdm, + writableTmpDirAsHomeHook, +}: + +buildPythonPackage rec { + pname = "libbs"; + version = "2.11.1"; + pyproject = true; + + src = fetchFromGitHub { + owner = "binsync"; + repo = "libbs"; + tag = "v${version}"; + hash = "sha256-hYRRmnxA6K7O6suaP1eGRnY89gok3JNNsL70XRGWYBU="; + }; + + build-system = [ setuptools ]; + + dependencies = [ + filelock + ghidra-bridge + jfx-bridge + networkx + platformdirs + prompt-toolkit + psutil + pycparser + pyhidra + toml + tqdm + ]; + + nativeCheckInputs = [ + pytestCheckHook + writableTmpDirAsHomeHook + ]; + + pythonImportsCheck = [ "libbs" ]; + + disabledTests = [ + "test_change_watcher_plugin_cli" + "test_ghidra_artifact_watchers" + "TestHeadlessInterfaces" + ]; + + meta = { + description = "Library for writing plugins in any decompiler: includes API lifting, common data formatting, and GUI abstraction"; + homepage = "https://github.com/binsync/libbs"; + changelog = "https://github.com/binsync/libbs/releases/tag/${src.tag}"; + license = lib.licenses.bsd2; + maintainers = with lib.maintainers; [ scoder12 ]; + }; +} diff --git a/pkgs/development/python-modules/pyhidra/default.nix b/pkgs/development/python-modules/pyhidra/default.nix new file mode 100644 index 000000000000..0afc76e3e63c --- /dev/null +++ b/pkgs/development/python-modules/pyhidra/default.nix @@ -0,0 +1,57 @@ +{ + lib, + buildPythonPackage, + fetchFromGitHub, + jpype1, + pytest-datadir, + pytestCheckHook, + setuptools, +}: + +buildPythonPackage rec { + pname = "pyhidra"; + version = "1.3.0"; + pyproject = true; + + src = fetchFromGitHub { + owner = "dod-cyber-crime-center"; + repo = "pyhidra"; + tag = version; + hash = "sha256-8xouU+S7Apy1ySIlvOLPerTApqKy/MNdl9vuBdt+9Vk="; + }; + + build-system = [ setuptools ]; + + dependencies = [ jpype1 ]; + + nativeCheckInputs = [ + pytest-datadir + pytestCheckHook + ]; + + pythonImportsCheck = [ "pyhidra" ]; + + disabledTests = [ + # Tests require a running Ghidra instance + "test_invalid_jpype_keyword_arg" + "test_invalid_vm_arg_succeed" + "test_run_script" + "test_open_program" + "test_no_compiler" + "test_no_language_with_compiler" + "test_loader" + "test_invalid_loader_type" + "test_no_project" + "test_no_program" + "test_import_script" + "test_import_ghidra_base_java_packages" + ]; + + meta = { + description = "Provides direct access to the Ghidra API within a native CPython interpreter using jpype"; + homepage = "https://github.com/dod-cyber-crime-center/pyhidra"; + changelog = "https://github.com/dod-cyber-crime-center/pyhidra/blob/${src.tag}/CHANGELOG.md"; + license = lib.licenses.mit; + maintainers = with lib.maintainers; [ scoder12 ]; + }; +} diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix index b0234ed02dd5..36c797c832f6 100644 --- a/pkgs/top-level/python-packages.nix +++ b/pkgs/top-level/python-packages.nix @@ -5373,6 +5373,8 @@ self: super: with self; { ghdiff = callPackage ../development/python-modules/ghdiff { }; + ghidra-bridge = callPackage ../development/python-modules/ghidra-bridge { }; + ghome-foyer-api = callPackage ../development/python-modules/ghome-foyer-api { }; ghp-import = callPackage ../development/python-modules/ghp-import { }; @@ -6802,6 +6804,8 @@ self: super: with self; { jh2 = callPackage ../development/python-modules/jh2 { }; + jfx-bridge = callPackage ../development/python-modules/jfx-bridge { }; + jianpu-ly = callPackage ../development/python-modules/jianpu-ly { }; jieba = callPackage ../development/python-modules/jieba { }; @@ -7446,6 +7450,8 @@ self: super: with self; { libagent = callPackage ../development/python-modules/libagent { }; + libbs = callPackage ../development/python-modules/libbs { }; + pa-ringbuffer = callPackage ../development/python-modules/pa-ringbuffer { }; lib4sbom = callPackage ../development/python-modules/lib4sbom { }; @@ -10924,6 +10930,8 @@ self: super: with self; { pyhepmc = callPackage ../development/python-modules/pyhepmc { }; + pyhidra = callPackage ../development/python-modules/pyhidra { }; + pyhive-integration = callPackage ../development/python-modules/pyhive-integration { }; pyhumps = callPackage ../development/python-modules/pyhumps { };