Skip to content

Commit

Permalink
Improve nix flake
Browse files Browse the repository at this point in the history
- Builds with current nixpkgs
- Separate pypanda package built with nixpkgs Python functions
- Configurable plugin list
  • Loading branch information
lluchs committed Dec 10, 2024
1 parent cc88392 commit 43be8ff
Show file tree
Hide file tree
Showing 2 changed files with 164 additions and 58 deletions.
62 changes: 53 additions & 9 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

160 changes: 111 additions & 49 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -2,63 +2,85 @@
description = "PANDA: Platform for Architecture-Neutral Dynamic Analysis";

inputs = {
# nixpkgs with a Wireshark version that works with the network plugin.
nixpkgs-wireshark = {
url = "github:NixOS/nixpkgs?rev=e93823409f9e6b8e878edf060b430a14353a28f9";
};
libosi-src = {
url = "github:panda-re/libosi";
flake = false;
};
# Override this input to change which plugins are built.
panda-config = {
url = "file:/dev/null";
flake = false;
};
nix-filter.url = "github:numtide/nix-filter";
};

outputs = { self, nixpkgs, libosi-src }: {
outputs = { self, nixpkgs, nixpkgs-wireshark, libosi-src, panda-config, nix-filter }:
let
system = "x86_64-linux";

pkgs = import nixpkgs { inherit system; };
lib = pkgs.lib;
pyPkgs = pkgs.python3Packages;

packages.x86_64-linux.default = let
filter = nix-filter.lib;

pkgs = import nixpkgs {
system = "x86_64-linux";
config.permittedInsecurePackages = [ "libdwarf-20210528" ];
};
panda-config-content = builtins.readFile panda-config;
panda-config-enabled = if panda-config-content == "" then (builtins.readFile ./panda/plugins/config.panda) else panda-config-content;

pyPkgs = pkgs.python3Packages;
# Is any plugin in `plugins` enabled in config.panda?
plugin-enabled = plugins:
(builtins.match "(^|.*\n)(${builtins.concatStringsSep "|" plugins})(\n.*|$)" panda-config-enabled) != null;

# We need to use an older version of wireshark, since 2.5.1 breaks the network plugin
wireshark = (import (pkgs.fetchFromGitHub {
owner = "NixOS";
repo = "nixpkgs";
rev = "a7e0fb6ffcae252bdd0c85928f179c74c3492a89";
hash = "sha256-RdXz/U0JJvsABkGWhF4Cukl4KuZvOJvkci7EuizKid0=";
}) { localSystem.system = "x86_64-linux"; }).wireshark-cli.overrideAttrs
wireshark = (import nixpkgs-wireshark { inherit system; }).wireshark-cli.overrideAttrs
(prev: {
outputs = [ "out" "dev" ];
postInstall = ''
${prev.postInstall}
# Install headers
mkdir $dev/include/wireshark/{epan/{wmem,ftypes,dfilter},wsutil,wiretap} -pv
cp config.h $dev/include/wireshark
cp ../ws_*.h $dev/include/wireshark
cp ../epan/*.h $dev/include/wireshark/epan/
cp ../epan/wmem/*.h $dev/include/wireshark/epan/wmem/
cp ../epan/ftypes/*.h $dev/include/wireshark/epan/ftypes/
cp ../epan/dfilter/*.h $dev/include/wireshark/epan/dfilter/
cp ../wsutil/*.h $dev/include/wireshark/wsutil/
cp ../wiretap/*.h $dev/include/wireshark/wiretap
'';
});

libdwarf = pkgs.stdenv.mkDerivation rec {
pname = "libdwarf";
version = "20210528";

src = pkgs.fetchurl {
url = "https://www.prevanders.net/libdwarf-${version}.tar.gz";
hash = "sha512-4PnIhVQFPubBsTM5YIkRieeCDEpN3DArfmN1Skzc/CrLG0tgg6ci0SBKdemU//NAHswlG4w7JAkPjLQEbZD4cA==";
};

configureFlags = [ "--enable-shared" "--disable-nonshared" ];
buildInputs = with pkgs; [ zlib libelf ];
outputs = [ "bin" "lib" "dev" "out" ];
enableParallelBuilding = true;
};

libosi = pkgs.stdenv.mkDerivation {
name = "libosi";
src = libosi-src;
buildInputs = with pkgs; [ cmake pkg-config glib ];
};

default = pkgs.stdenv.mkDerivation {
panda = pkgs.stdenv.mkDerivation {
name = "panda";
src = ./.;
src = filter {
root = ./.;
# exclude flake files to prevent unnecessary rebuilds
exclude = [
./flake.nix
./flake.lock
];
};
cargoRoot = "panda/plugins";
cargoDeps = pkgs.rustPlatform.importCargoLock {
lockFile = ./panda/plugins/Cargo.lock;
};
buildInputs = (with pkgs; [
pkg-config
python3
zlib
glib
Expand All @@ -69,14 +91,16 @@
protobufc
protobuf
cargo
curl
libdwarf_20210528
zip
libelf
jsoncpp
]) ++ [ wireshark libosi ]
])
++ (lib.optionals (plugin-enabled [ "network" ]) [ wireshark ])
++ (lib.optionals (plugin-enabled [ "wintrospection" ]) [ libosi ])
++ (lib.optionals (plugin-enabled [ "pri_dwarf" ]) [ libdwarf ])
++ (lib.optionals (plugin-enabled [ "pri_dwarf" "dwarf2" ]) [ pkgs.libelf ])
++ (lib.optionals (plugin-enabled [ "dwarf2" "syscalls_logger" ]) [ pkgs.jsoncpp ])
++ (lib.optionals (plugin-enabled [ "osi_linux" ]) [ pkgs.curl ])
++ (with pyPkgs; [ pycparser libfdt setuptools ]);
nativeBuildInputs = [ pkgs.rustPlatform.cargoSetupHook ];
nativeBuildInputs = [ pkgs.pkg-config pkgs.rustPlatform.cargoSetupHook ];
propagatedBuildInputs = with pyPkgs; [ cffi colorama ];
enableParallelBuilding = true;
patches = [
Expand Down Expand Up @@ -113,16 +137,10 @@
--replace '/usr/include/wireshark' '${wireshark.dev}/include/wireshark'
substituteInPlace panda/plugins/pri_dwarf/*.{h,cpp} \
--replace '<libdwarf/' '<'
substituteInPlace panda/python/core/pandare/utils.py \
--replace \
'pjoin(python_package, arch_dir), pjoin(local_build, arch_dir)' \
'realpath(pjoin(dirname(__file__), "../../../../bin"))'
substituteInPlace panda/python/core/pandare/panda.py \
--replace 'self.plugin_path = plugin_path' "self.plugin_path = plugin_path or pjoin('$out', 'lib/panda', arch)" \
--replace 'if libpanda_path:' 'if True:' \
--replace '= libpanda_path' "= libpanda_path or pjoin('$out', 'bin', f'libpanda-{arch}.so')" \
--replace 'realpath(pjoin(self.get_build_dir(), "pc-bios"))' "pjoin('$out', 'share/panda')"
'';
''
+ lib.optionalString (panda-config-content != "") ''
cp "${panda-config}" panda/plugins/config.panda
'';
preConfigure = "mkdir build && cd build";
configureScript = "../configure";
configureFlags = [
Expand All @@ -142,15 +160,59 @@
# TODO: "--enable-llvm"
];
postInstall = ''
rm -r $out/lib/panda/*/{cosi,cosi_strace,gdb,snake_hook,rust_skeleton}
(
cd ../panda/python/core
python3 setup.py install --prefix "$out"
)
rm -rf $out/lib/panda/*/{cosi,cosi_strace,gdb,snake_hook,rust_skeleton}
# Generated files for PyPANDA (built separately)
(cd ../panda/python/core && python ./create_panda_datatypes.py)
mkdir "$out/lib/panda/python"
cp -r ../panda/python/core/pandare/{autogen,include,plog_pb2.py} "$out/lib/panda/python"
rm -r "$out/lib/python3"
'';
};

in default;
pypanda = let
panda = self.packages.x86_64-linux.default;
in pyPkgs.buildPythonPackage {
pname = "pandare";
version = "1.8";
format = "setuptools";
src = ./panda/python/core;

};
propagatedBuildInputs = with pyPkgs; [
cffi
protobuf
colorama
];

nativeBuildInputs = [
pyPkgs.setuptools_scm
];

buildInputs = [ panda ];

postPatch = ''
substituteInPlace setup.py \
--replace 'install_requires=parse_requirements("requirements.txt"),' ""
substituteInPlace pandare/utils.py \
--replace '/usr/local/bin/' '${panda}'
substituteInPlace pandare/panda.py \
--replace 'self.plugin_path = plugin_path' "self.plugin_path = plugin_path or pjoin('${panda}', 'lib/panda', arch)" \
--replace 'if libpanda_path:' 'if True:' \
--replace '= libpanda_path' "= libpanda_path or pjoin('${panda}', 'bin', f'libpanda-{arch}.so')" \
--replace 'realpath(pjoin(self.get_build_dir(), "pc-bios"))' "pjoin('${panda}', 'share/panda')"
# Use auto-generated files from separate derivation above.
rm create_panda_datatypes.py
rm -r pandare/{include,autogen}
cp -rt pandare "${panda}"/lib/panda/python/{include,autogen,plog_pb2.py}
'';
};

in {
packages.x86_64-linux = {
default = panda;
pypanda = pypanda;
wireshark = wireshark;
libdwarf = libdwarf;
};
};
}

0 comments on commit 43be8ff

Please sign in to comment.