[PATCH 1/2] gnu: Add unicorn.

OpenSubmitted by Jakub Kądziołka.
Details
2 participants
  • Jakub Kądziołka
  • Leo Famulari
Owner
unassigned
Severity
normal
J
J
Jakub Kądziołka wrote on 28 Mar 2020 01:50
(address . guix-patches@gnu.org)
20200328005052.22846-1-kuba@kadziolka.net
* gnu/packages/emulators.scm (unicorn-next): New variable.
---

If I package a -rc version, should it have a -next suffix in its name
even though the "stable" version isn't packaged?

Maybe I should also package the non-rc unicorn? The test suite for that
version fails to compile, so it's not entirely trivial.

I'd also like to bring these build phases to your attention - I feel
like they need a review the most.

gnu/packages/emulators.scm | 110 ++++++++++++++++++++++++++++++++++++-
1 file changed, 109 insertions(+), 1 deletion(-)

Toggle diff (134 lines)
diff --git a/gnu/packages/emulators.scm b/gnu/packages/emulators.scm
index 3591b1740c..5b5e1359e3 100644
--- a/gnu/packages/emulators.scm
+++ b/gnu/packages/emulators.scm
@@ -44,6 +44,7 @@
   #:use-module (gnu packages boost)
   #:use-module (gnu packages backup)
   #:use-module (gnu packages cdrom)
+  #:use-module (gnu packages check)
   #:use-module (gnu packages compression)
   #:use-module (gnu packages curl)
   #:use-module (gnu packages elf)
@@ -88,7 +89,8 @@
   #:use-module (gnu packages web)
   #:use-module (guix build-system cmake)
   #:use-module (guix build-system glib-or-gtk)
-  #:use-module (guix build-system gnu))
+  #:use-module (guix build-system gnu)
+  #:use-module (guix build-system python))
 
 (define-public desmume
   (package
@@ -1628,3 +1630,109 @@ derived from Gens.  Project goals include clean source code, combined features
 from various forks of Gens, and improved platform portability.")
     (supported-systems '("i686-linux" "x86_64-linux"))
     (license license:gpl2+)))
+
+;; python-pwntools requires a -rc release of unicorn
+(define-public unicorn-next
+  (package
+    (name "unicorn-next")
+    (version "1.0.2-rc2")
+    ;; NOTE: unicorn ships a bundled QEMU, but with custom modifications.
+    (source
+     (origin
+       (method git-fetch)
+       (uri (git-reference
+             (url "https://github.com/unicorn-engine/unicorn")
+             (commit version)))
+       (file-name (git-file-name name version))
+       (sha256
+        (base32
+         "0v5sc8sniv2w0bki1f7n3pgsk17y7hggw55fvkjzk2sv8z8w4bsj"))))
+    (outputs '("out" "python"))
+    ;; The main library is not written in Python, but the build process has
+    ;; little in common with any defined build system, so we might as well
+    ;; build on top of python-build-system and make use of all
+    ;; the Python-specific phases that can be reused.
+    (build-system python-build-system)
+    (arguments
+     `(#:modules ((srfi srfi-26)
+                  (guix build python-build-system)
+                  (guix build utils))
+       #:phases
+       (modify-phases %standard-phases
+         (add-after 'unpack 'install-bindings-to-python-output
+           (lambda* (#:key outputs #:allow-other-keys)
+             ;; python-build-system will build the bindings and install them to
+             ;; the "out" output, so change the build-internal names of the
+             ;; outputs.
+             (set-car! (assoc "out" outputs) "lib")
+             (set-car! (assoc "python" outputs) "out")
+             #t))
+         (add-before 'build 'build-library
+           (lambda* (#:key inputs #:allow-other-keys)
+             (invoke "make"
+                     "-j" (number->string (parallel-job-count))
+                     (string-append
+                      "UNICORN_QEMU_FLAGS=--python="
+                      (assoc-ref inputs "python-for-qemu")
+                      "/bin/python2")
+                     "UNICORN_STATIC=no"
+                     "CC=gcc")))
+         (add-after 'build-library 'install-library
+           (lambda* (#:key outputs #:allow-other-keys)
+             (invoke "make" "install"
+                     "UNICORN_STATIC=no"
+                     (string-append
+                      "PREFIX="
+                      (assoc-ref outputs "lib")))))
+         (add-before 'build 'prepare-bindings
+           (lambda* (#:key outputs #:allow-other-keys)
+             (chdir "bindings/python")
+             ;; Set this environment variable so that the Python bindings
+             ;; don't build their own copy of the shared object, but use
+             ;; a dummy value such that the bindings test suite uses the
+             ;; same mechanism for loading the library as any other user.
+             (setenv "LIBUNICORN_PATH" "1")
+             (substitute* "unicorn/unicorn.py"
+               (("_path_list = \\[.*")
+                (string-append
+                 "_path_list = [\""
+                 (assoc-ref outputs "lib")
+                 ;; eat the rest of the list
+                 "/lib\"] + 0*[")))
+             #t))
+         (add-before 'check 'check-library
+           (lambda* (#:key outputs #:allow-other-keys)
+             ;; TODO: running the tests on non-x86 requires a cross-binutils
+             ;; with x86 as target.
+             ,@(if (member (%current-system) '("x86_64-linux" "i686-linux"))
+                   '((for-each
+                      (lambda (suite)
+                        (with-directory-excursion
+                            (string-append "../../tests/" suite)
+                          (invoke "make" "test" "CC=gcc")))
+                      '("unit" "regress")))
+                   '())
+             #t))
+         (add-after 'install 'install-samples
+           (lambda* (#:key outputs #:allow-other-keys)
+             (let* ((python-samples (find-files "." "sample_.*"))
+                    (c-samples (find-files "../../samples" ".*\\.c"))
+                    (python-docdir
+                      (string-append (assoc-ref outputs "out")
+                                     "/share/doc/unicorn/samples"))
+                    (c-docdir
+                      (string-append (assoc-ref outputs "lib")
+                                     "/share/doc/unicorn/samples")))
+               (for-each (cut install-file <> c-docdir) c-samples)
+               (for-each (cut install-file <> python-docdir) python-samples)
+               #t))))))
+    (native-inputs
+     `(("cmocka" ,cmocka)
+       ("python-for-qemu" ,python-2)
+       ("hexdump-for-tests" ,util-linux)))
+    (home-page "http://www.unicorn-engine.org")
+    (synopsis "Unicorn CPU emulator framework")
+    (description
+     "Unicorn is a lightweight, multi-platform, multi-architecture CPU emulator
+framework based on QEMU.")
+    (license license:gpl2+)))
-- 
2.26.0
J
J
Jakub Kądziołka wrote on 28 Mar 2020 01:53
[PATCH 2/2] gnu: Add python-pwntools.
(address . 40267@debbugs.gnu.org)
20200328005345.24506-1-kuba@kadziolka.net
* gnu/packages/cybersecurity.scm (python-pwntools): New variable.
---

This patch requires #40265.

gnu/packages/cybersecurity.scm | 51 +++++++++++++++++++++++++++++++++-
1 file changed, 50 insertions(+), 1 deletion(-)

Toggle diff (71 lines)
diff --git a/gnu/packages/cybersecurity.scm b/gnu/packages/cybersecurity.scm
index aedac03b8a..cb9c33bae1 100644
--- a/gnu/packages/cybersecurity.scm
+++ b/gnu/packages/cybersecurity.scm
@@ -18,10 +18,17 @@
 
 (define-module (gnu packages cybersecurity)
   #:use-module (guix download)
+  #:use-module (guix git-download)
   #:use-module (guix packages)
   #:use-module ((guix licenses) #:prefix license:)
   #:use-module (guix build-system python)
-  #:use-module (gnu packages engineering))
+  #:use-module (gnu packages bioinformatics)
+  #:use-module (gnu packages emulators)
+  #:use-module (gnu packages engineering)
+  #:use-module (gnu packages python-crypto)
+  #:use-module (gnu packages python-web)
+  #:use-module (gnu packages python-xyz)
+  #:use-module (gnu packages time))
 
 (define-public ropgadget
   (package
@@ -44,3 +51,45 @@
 gadgets in binaries.  Some facilities are included for automatically generating
 chains of gadgets to execute system calls.")
     (license license:bsd-3)))
+
+(define-public python-pwntools
+  (package
+    (name "python-pwntools")
+    (version "4.0.1")
+    (source
+      (origin
+        (method git-fetch)
+        (uri (git-reference
+               (url "https://github.com/Gallopsled/pwntools")
+               (commit version)))
+        (file-name (git-file-name name version))
+        (sha256
+         (base32
+          "14grsflkfpr7y3gg2lm86lfn6n40yip45n4gjz0hzi9sjalq1gr5"))))
+    (build-system python-build-system)
+    (arguments
+     `(#:tests? #f)) ; Tests require networking and custom sshd configuration
+    (propagated-inputs
+     `(("paramiko" ,python-paramiko)
+       ("mako" ,python-mako)
+       ("pyelftools" ,python-pyelftools)
+       ("capstone" ,python-capstone)
+       ("ropgadget" ,ropgadget)
+       ("pyserial" ,python-pyserial)
+       ("requests" ,python-requests)
+       ("pygments" ,python-pygments)
+       ("pysocks" ,python-pysocks)
+       ("dateutil" ,python-dateutil)
+       ("packaging" ,python-packaging)
+       ("psutil" ,python-psutil)
+       ("intervaltree" ,python-intervaltree)
+       ("sortedcontainers" ,python-sortedcontainers)
+       ("unicorn" ,unicorn-next "python")))
+    (native-inputs
+     `(("tox" ,python-tox)))
+    (home-page "https://github.com/Gallopsled/pwntools")
+    (synopsis "CTF framework and exploit development library")
+    (description "Pwntools is a CTF framework and exploit development library.
+Written in Python, it is designed for rapid prototyping and development, and
+intended to make exploit writing as simple as possible.")
+    (license (list license:expat license:bsd-2 license:gpl2+))))
-- 
2.26.0
L
L
Leo Famulari wrote on 29 Mar 2020 04:56
(name . Jakub Kądziołka)(address . kuba@kadziolka.net)(address . 40267@debbugs.gnu.org)
20200329025615.GA16918@jasmine.lan
On Sat, Mar 28, 2020 at 01:53:45AM +0100, Jakub Kądziołka wrote:
Toggle quote (3 lines)
> * gnu/packages/cybersecurity.scm (python-pwntools): New variable.
> + (propagated-inputs

It would be nice to sort these, especially if the package might grow new
dependencies later.

Toggle quote (2 lines)
> + (license (list license:expat license:bsd-2 license:gpl2+))))

I looked it up; the package is overall MIT/Expat licensed, but a few
components use other licenses. It helpful to list the files with the
other licenses, or to say where to look up the info with a comment like
"See LICENSE-pwntools.txt in the source distribution."
L
L
Leo Famulari wrote on 29 Mar 2020 05:48
Re: [bug#40267] [PATCH 1/2] gnu: Add unicorn.
(name . Jakub Kądziołka)(address . kuba@kadziolka.net)(address . 40267@debbugs.gnu.org)
20200329034811.GB16918@jasmine.lan
On Sat, Mar 28, 2020 at 01:50:52AM +0100, Jakub Kądziołka wrote:
Toggle quote (2 lines)
> * gnu/packages/emulators.scm (unicorn-next): New variable.

Sounds like a cool package!

Toggle quote (3 lines)
> If I package a -rc version, should it have a -next suffix in its name
> even though the "stable" version isn't packaged?

I think it's best to just call it unicorn. The version says -rc and we
mention it in the synopsis and description. And it's useful under the
hood for guix lint to match the upstream name.

Toggle quote (3 lines)
> Maybe I should also package the non-rc unicorn? The test suite for that
> version fails to compile, so it's not entirely trivial.

Is the previous release useful? We normally don't package betas or
release candidates... it depends. Do you have an idea of the release
timeline? Do you think upstream would mind if we packaged the RC?

Toggle quote (2 lines)
> + ;; NOTE: unicorn ships a bundled QEMU, but with custom modifications.

Can you add more detail to this comment? Is it just a patch on a QEMU
tarball or is this not really QEMU anymore?

Toggle quote (5 lines)
> + ;; The main library is not written in Python, but the build process has
> + ;; little in common with any defined build system, so we might as well
> + ;; build on top of python-build-system and make use of all
> + ;; the Python-specific phases that can be reused.

Okay

Toggle quote (9 lines)
> + (add-after 'unpack 'install-bindings-to-python-output
> + (lambda* (#:key outputs #:allow-other-keys)
> + ;; python-build-system will build the bindings and install them to
> + ;; the "out" output, so change the build-internal names of the
> + ;; outputs.
> + (set-car! (assoc "out" outputs) "lib")
> + (set-car! (assoc "python" outputs) "out")
> + #t))

I would wait for advice here. The manual requests we write everything in
a functional style. But I don't know of another way to make
python-build-system install things to alternate outputs without changing
the build system or replacing the install phase. It would be nice to
have a parameter for this somewhere...

Toggle quote (6 lines)
> + (add-before 'check 'check-library
> + (lambda* (#:key outputs #:allow-other-keys)
> + ;; TODO: running the tests on non-x86 requires a cross-binutils
> + ;; with x86 as target.
> + ,@(if (member (%current-system) '("x86_64-linux" "i686-linux"))

I think the 'when' procedure is more clear than 'if' in cases where the
else branch is empty.
J
J
Jakub Kądziołka wrote on 29 Mar 2020 14:43
(name . Leo Famulari)(address . leo@famulari.name)(address . 40267@debbugs.gnu.org)
20200329124351.dckxah33q6ajb6z2@gravity
On Sat, Mar 28, 2020 at 11:48:11PM -0400, Leo Famulari wrote:
Toggle quote (8 lines)
> On Sat, Mar 28, 2020 at 01:50:52AM +0100, Jakub Kądziołka wrote:
> > If I package a -rc version, should it have a -next suffix in its name
> > even though the "stable" version isn't packaged?
>
> I think it's best to just call it unicorn. The version says -rc and we
> mention it in the synopsis and description. And it's useful under the
> hood for guix lint to match the upstream name.

Fair enough.

Toggle quote (5 lines)
> > Maybe I should also package the non-rc unicorn? The test suite for that
> > version fails to compile, so it's not entirely trivial.
>
> Is the previous release useful?

As far as I am aware, the non-rc release is not useful beyond avoiding
any potential uneasyness about running -rc releases ;)

Toggle quote (4 lines)
> We normally don't package betas or
> release candidates... it depends. Do you have an idea of the release
> timeline?

Sadly, I have no idea.

Toggle quote (2 lines)
> Do you think upstream would mind if we packaged the RC?

I don't think so? As a datapoint, FreeBSD packages the -rc.

Toggle quote (5 lines)
> > + ;; NOTE: unicorn ships a bundled QEMU, but with custom modifications.
>
> Can you add more detail to this comment? Is it just a patch on a QEMU
> tarball or is this not really QEMU anymore?

The documentation suggests the changes go quite deep:

| Internally, Unicorn reuses the CPU emulation component of QEMU as its
| core (with quite a lot of changes to adapt to our design).

What do you think about a comment like this?

;; NOTE: unicorn ships a bundled QEMU, but heavily modified.

Toggle quote (15 lines)
> > + (add-after 'unpack 'install-bindings-to-python-output
> > + (lambda* (#:key outputs #:allow-other-keys)
> > + ;; python-build-system will build the bindings and install them to
> > + ;; the "out" output, so change the build-internal names of the
> > + ;; outputs.
> > + (set-car! (assoc "out" outputs) "lib")
> > + (set-car! (assoc "python" outputs) "out")
> > + #t))
>
> I would wait for advice here. The manual requests we write everything in
> a functional style. But I don't know of another way to make
> python-build-system install things to alternate outputs without changing
> the build system or replacing the install phase. It would be nice to
> have a parameter for this somewhere...

Yeah, it's not the nicest thing. I think I'll submit a patch to c-u that
would add such a parameter (does #:python-output sound good?), and then come
back here when it lands. Would this imperative hack be ok as a temporary solution?

Toggle quote (9 lines)
> > + (add-before 'check 'check-library
> > + (lambda* (#:key outputs #:allow-other-keys)
> > + ;; TODO: running the tests on non-x86 requires a cross-binutils
> > + ;; with x86 as target.
> > + ,@(if (member (%current-system) '("x86_64-linux" "i686-linux"))
>
> I think the 'when' procedure is more clear than 'if' in cases where the
> else branch is empty.

The issue is that the else branch contains '(), and is not itself empty.
Do you happen to know how to get the value of (%current-system)
build-side?

Thanks for your review!
-----BEGIN PGP SIGNATURE-----

iQIzBAABCAAdFiEE5Xa/ss9usT31cTO54xWnWEYTFWQFAl6AmAEACgkQ4xWnWEYT
FWSgFhAAyDaaXmj8Js9BvgjvinyLCQRrB0CVull04a2pIT7O527tsxxlUK3uRM0U
WIbLEovk/5dkWILIOkDPKc5/rSQM7tO+xjya6fJCT5Y6i6M0plurrtUKrBnAOdUq
EgvjWYfGeOOYnoM5+v86RMSdy/4fRe0pogSQ8hlhsQmfpA0d3m6FnWKExxp97ya+
/SdXp2SQcGV6zJAfa4s+PAqxrPJSEJqOdTS5yY9AGb17sSm/PmsGxaKhtnVtuRS9
Igr9VD4ljfuzRZx9qreg5nwxqZ0hwXqjRaiIPen/CHB+HSqs8p4eOvl9jHAC5XQt
oVr0NdB3Fh3Z7jLNhWpWfYENzp72baQftMopXPTM7mBMje75x+bBzr6UZXshnRzU
qFG3f+iW2PiAjPGKPrJnLNVJVP84IA09HTdRKxE/OhCwNQ8cMrK5+gCsPJZ4QSB+
+X0F6/QgCuJUcRE3nMz4vrArFw/t/KDGmBxGGEe6pN2yKZx3lC0Stk4W9L2blyrw
5IfEmkPq3pl1fDWLUKw+H2eriA9dHFaWKsl7nXGBtT7giylr0OVTNVzZp0M8AWcB
DusOLuCogkKAvs5inBaP0InDttBYN2vZNW27Dbhqz2O4AFMx6p3GD4NxXecilGVQ
5ucITT19Nf/+Y5yXd8PShcIDwEnrJ43YAsUK6RJlySjwYGDfw9Y=
=0iAC
-----END PGP SIGNATURE-----


J
J
Jakub Kądziołka wrote on 29 Mar 2020 17:32
Re: [bug#40267] [PATCH 2/2] gnu: Add python-pwntools.
(name . Leo Famulari)(address . leo@famulari.name)(address . 40267@debbugs.gnu.org)
20200329153246.prmtftsaburxt4tt@gravity
On Sat, Mar 28, 2020 at 10:56:15PM -0400, Leo Famulari wrote:
Toggle quote (7 lines)
> On Sat, Mar 28, 2020 at 01:53:45AM +0100, Jakub Kądziołka wrote:
> > * gnu/packages/cybersecurity.scm (python-pwntools): New variable.
> > + (propagated-inputs
>
> It would be nice to sort these, especially if the package might grow new
> dependencies later.

The current order is copied from setup.py in the package, as I felt it
was easier to compare it that way, but I can sort them if that's
preferred.

Toggle quote (7 lines)
> > + (license (list license:expat license:bsd-2 license:gpl2+))))
>
> I looked it up; the package is overall MIT/Expat licensed, but a few
> components use other licenses. It helpful to list the files with the
> other licenses, or to say where to look up the info with a comment like
> "See LICENSE-pwntools.txt in the source distribution."

Ok, I added your suggested comment locally.
-----BEGIN PGP SIGNATURE-----

iQIzBAABCAAdFiEE5Xa/ss9usT31cTO54xWnWEYTFWQFAl6Av5YACgkQ4xWnWEYT
FWT0FQ/+KCI7a/IX8tuJGmJh3Dy2j41V9w/WE0HyHltpYgGSBXGlfWmdeIE+j1sP
4B1DrS0DN1aZKkv8T+1dnupbuCBI65xD2xYwZejXD5QyV2ZRW4A+SpmcUtCeJykY
q88x7/4jeOhvWeiham44wZEO58ZzdCTz/V73eSA9eCMLwB8zfz8N9VaWG4lE+mEl
yQ7sWpYhMb/uHKwWKU3i4nXTK8KCLQe0OffG22UWHP5+5YGgRowdA6y1Zs4u3IhD
IjYqltZhexKZSAiIzUFx+/mAbxfiI5vFaQ58j+zZuJrZMwLgtNg5e5x42Ja4lQHD
4gug0uXMa90uAsYhwjS3ISC32QmwpP+eFnOfPVsNTyXODpY0jiRoQm80as+GmGy9
8tR7Fh8eOhEdlHmlC50x85yLyIUxnITxAMFq/sIFbM9tdinoCirPP9X/xMQEVXp9
dgfqAPDJ+ZYhdc4wNDplwhMFo9zvqQ8eXw/D1wq7XfWANDC7rtS8KjtKHX2Yj+i9
0wLXSiqGeH+FtxOMgaPBAeT0p3IpnDRnSTVw099bQyIwlzDQjAZounLnv7M6CFlV
c3TTTlJodHVkKN69JCcVChzhkyZDa6L8GG4IXIbE+JcbH2mb20IClkHHT3LA9qDW
Sb+N5GwvRCySMfFLLFXHJWXXCNKH8uVMEDJteatyQwXZeKwN5xs=
=87PL
-----END PGP SIGNATURE-----


J
J
Jakub Kądziołka wrote on 7 Jun 2020 22:19
[PATCH v2 1/2] gnu: Add unicorn.
(address . 40267@debbugs.gnu.org)(address . leo@famulari.name)
20200607201941.5044-1-kuba@kadziolka.net
* gnu/packages/emulators.scm (unicorn): New variable.
---

Changes from v1: packaged a new -rc, which makes tests pass on ARM. Add
an input for cross-binutils, and use it while running tests. Also, the
new -rc doesn't need Python for build orchestration, so the python-2
input got dropped. The python-build-system phases hack got prefixed with
a comment referencing the core-updates patch.

gnu/packages/emulators.scm | 117 ++++++++++++++++++++++++++++++++++++-
1 file changed, 116 insertions(+), 1 deletion(-)

Toggle diff (142 lines)
diff --git a/gnu/packages/emulators.scm b/gnu/packages/emulators.scm
index 9798ac370e..a82df6e9b6 100644
--- a/gnu/packages/emulators.scm
+++ b/gnu/packages/emulators.scm
@@ -44,7 +44,9 @@
   #:use-module (gnu packages boost)
   #:use-module (gnu packages backup)
   #:use-module (gnu packages cdrom)
+  #:use-module (gnu packages check)
   #:use-module (gnu packages compression)
+  #:use-module (gnu packages cross-base)
   #:use-module (gnu packages curl)
   #:use-module (gnu packages elf)
   #:use-module (gnu packages fonts)
@@ -88,7 +90,8 @@
   #:use-module (gnu packages web)
   #:use-module (guix build-system cmake)
   #:use-module (guix build-system glib-or-gtk)
-  #:use-module (guix build-system gnu))
+  #:use-module (guix build-system gnu)
+  #:use-module (guix build-system python))
 
 (define-public desmume
   (package
@@ -1622,3 +1625,115 @@ derived from Gens.  Project goals include clean source code, combined features
 from various forks of Gens, and improved platform portability.")
     (supported-systems '("i686-linux" "x86_64-linux"))
     (license license:gpl2+)))
+
+;; python-pwntools requires a -rc release of unicorn
+(define-public unicorn
+  (let ((unless-x86
+          (lambda (code)
+            (if (member (%current-system) '("x86_64-linux" "i686-linux"))
+              '()
+              code))))
+    (package
+      (name "unicorn")
+      (version "1.0.2-rc4")
+      ;; NOTE: unicorn ships a bundled QEMU, but with a lot of custom modifications.
+      (source
+       (origin
+         (method git-fetch)
+         (uri (git-reference
+               (url "https://github.com/unicorn-engine/unicorn")
+               (commit version)))
+         (file-name (git-file-name name version))
+         (sha256
+          (base32
+           "17nyccgk7hpc4hab24yn57f1xnmr7kq4px98zbp2bkwcrxny8gwy"))))
+      (outputs '("out" "python"))
+      ;; The main library is not written in Python, but the build process has
+      ;; little in common with any defined build system, so we might as well
+      ;; build on top of python-build-system and make use of all
+      ;; the Python-specific phases that can be reused.
+      (build-system python-build-system)
+      (arguments
+       `(#:modules ((srfi srfi-26)
+                    (guix build python-build-system)
+                    (guix build utils))
+         #:phases
+         (modify-phases %standard-phases
+           (add-after 'unpack 'install-bindings-to-python-output
+             (lambda* (#:key outputs #:allow-other-keys)
+               ;; python-build-system will build the bindings and install them to
+               ;; the "out" output, so change the build-internal names of the
+               ;; outputs.
+               ;;
+               ;; TODO: remove this once #40469 lands, through the core-updates
+               ;; holding zone, on master.
+               (set-car! (assoc "out" outputs) "lib")
+               (set-car! (assoc "python" outputs) "out")
+               #t))
+           (add-before 'build 'build-library
+             (lambda* (#:key inputs #:allow-other-keys)
+               (invoke "make"
+                       "-j" (number->string (parallel-job-count))
+                       "UNICORN_STATIC=no"
+                       "CC=gcc")))
+           (add-after 'build-library 'install-library
+             (lambda* (#:key outputs #:allow-other-keys)
+               (invoke "make" "install"
+                       "UNICORN_STATIC=no"
+                       (string-append
+                        "PREFIX="
+                        (assoc-ref outputs "lib")))))
+           (add-before 'build 'prepare-bindings
+             (lambda* (#:key outputs #:allow-other-keys)
+               (chdir "bindings/python")
+               ;; Set this environment variable so that the Python bindings
+               ;; don't build their own copy of the shared object, but use
+               ;; a dummy value such that the bindings test suite uses the
+               ;; same mechanism for loading the library as any other user.
+               (setenv "LIBUNICORN_PATH" "1")
+               (substitute* "unicorn/unicorn.py"
+                 (("_path_list = \\[.*")
+                  (string-append
+                   "_path_list = [\""
+                   (assoc-ref outputs "lib")
+                   ;; eat the rest of the list
+                   "/lib\"] + 0*[")))
+               #t))
+           (add-before 'check 'check-library
+             (lambda* (#:key outputs #:allow-other-keys)
+               (for-each
+                 (lambda (suite)
+                   (with-directory-excursion
+                     (string-append "../../tests/" suite)
+                     (invoke "make" "test" "CC=gcc"
+                             ,@(unless-x86
+                                '("AS=i686-unknown-linux-gnu-as"
+                                  "OBJCOPY=i686-unknown-linux-gnu-objcopy")))))
+                 '("unit" "regress"))
+               #t))
+           (add-after 'install 'install-samples
+             (lambda* (#:key outputs #:allow-other-keys)
+               (let* ((python-samples (find-files "." "sample_.*"))
+                      (c-samples (find-files "../../samples" ".*\\.c"))
+                      (python-docdir
+                        (string-append (assoc-ref outputs "out")
+                                       "/share/doc/unicorn/samples"))
+                      (c-docdir
+                        (string-append (assoc-ref outputs "lib")
+                                       "/share/doc/unicorn/samples")))
+                 (for-each (cut install-file <> c-docdir) c-samples)
+                 (for-each (cut install-file <> python-docdir) python-samples)
+                 #t))))))
+      (native-inputs
+       ;; NOTE: cross-binutils needs to be wrapped with unless-x86, as otherwise
+       ;; the linker provided by the package will be used, circumventing the ld-wrapper.
+       `(,@(unless-x86
+            `(("assembler-for-tests" ,(cross-binutils "i686-unknown-linux-gnu"))))
+         ("cmocka" ,cmocka)
+         ("hexdump-for-tests" ,util-linux)))
+      (home-page "http://www.unicorn-engine.org")
+      (synopsis "Unicorn CPU emulator framework")
+      (description
+       "Unicorn is a lightweight, multi-platform, multi-architecture CPU emulator
+framework based on QEMU.")
+      (license license:gpl2+))))
-- 
2.26.2
J
J
Jakub Kądziołka wrote on 7 Jun 2020 22:19
[WIP PATCH v2 2/2] gnu: Add python-pwntools.
(address . 40267@debbugs.gnu.org)(address . leo@famulari.name)
20200607201941.5044-2-kuba@kadziolka.net
* gnu/packages/cybersecurity.scm (python-pwntools): New variable.
---

Changes from v1: added a patch to fix the installed commands' behavior
when wrapped by Guix - exec doesn't fool Python's sys.argv[0]. Resolved
the optional dependency on binutils for various architectures. Some
unresolved questions here mentioned in the comments.

I tried moving python-intervaltree out of bioinformatics.scm, but I
couldn't find a good place for intervaltree (the C library) to go with
it. python-xyz.scm feels wrong, since it's not in Python, and leaving it
in bioinformatics.scm creates a cycle.

gnu/local.mk | 1 +
gnu/packages/cybersecurity.scm | 83 ++++++++++++++++++-
.../python-pwntools-guix-wrappers.patch | 14 ++++
3 files changed, 97 insertions(+), 1 deletion(-)
create mode 100644 gnu/packages/patches/python-pwntools-guix-wrappers.patch

Toggle diff (135 lines)
diff --git a/gnu/local.mk b/gnu/local.mk
index ae8a2275f7..4384ad952d 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -1431,6 +1431,7 @@ dist_patch_DATA =						\
   %D%/packages/patches/python-packaging-test-arch.patch		\
   %D%/packages/patches/python2-parameterized-docstring-test.patch	\
   %D%/packages/patches/python-paste-remove-timing-test.patch	\
+  %D%/packages/patches/python-pwntools-guix-wrappers.patch	\
   %D%/packages/patches/python-pycrypto-CVE-2013-7459.patch	\
   %D%/packages/patches/python-pycrypto-time-clock.patch		\
   %D%/packages/patches/python2-pygobject-2-gi-info-type-error-domain.patch \
diff --git a/gnu/packages/cybersecurity.scm b/gnu/packages/cybersecurity.scm
index 8ded081c50..d45618e617 100644
--- a/gnu/packages/cybersecurity.scm
+++ b/gnu/packages/cybersecurity.scm
@@ -18,10 +18,20 @@
 
 (define-module (gnu packages cybersecurity)
   #:use-module (guix download)
+  #:use-module (guix git-download)
   #:use-module (guix packages)
   #:use-module ((guix licenses) #:prefix license:)
   #:use-module (guix build-system python)
-  #:use-module (gnu packages engineering))
+  #:use-module (gnu packages)
+  #:use-module (gnu packages avr)
+  #:use-module (gnu packages bioinformatics)
+  #:use-module (gnu packages cross-base)
+  #:use-module (gnu packages emulators)
+  #:use-module (gnu packages engineering)
+  #:use-module (gnu packages python-crypto)
+  #:use-module (gnu packages python-web)
+  #:use-module (gnu packages python-xyz)
+  #:use-module (gnu packages time))
 
 (define-public ropgadget
   (package
@@ -43,3 +53,74 @@
 gadgets in binaries.  Some facilities are included for automatically generating
 chains of gadgets to execute system calls.")
     (license license:bsd-3)))
+
+(define-public python-pwntools
+  (package
+    (name "python-pwntools")
+    (version "4.1.1")
+    (source
+      (origin
+        (method git-fetch)
+        (uri (git-reference
+               (url "https://github.com/Gallopsled/pwntools")
+               (commit version)))
+        (file-name (git-file-name name version))
+        (sha256
+         (base32
+          "101whqdfj415h0f4b9hz2jrwny44b0jdd9jmbh6rzz5w1yp41d5v"))
+        (patches (search-patches "python-pwntools-guix-wrappers.patch"))))
+    (build-system python-build-system)
+    (arguments
+     `(#:tests? #f)) ; Tests require networking and custom sshd configuration
+    (propagated-inputs
+     `(("paramiko" ,python-paramiko)
+       ("mako" ,python-mako)
+       ("pyelftools" ,python-pyelftools)
+       ("capstone" ,python-capstone)
+       ("ropgadget" ,ropgadget)
+       ("pyserial" ,python-pyserial)
+       ("requests" ,python-requests)
+       ("pygments" ,python-pygments)
+       ("pysocks" ,python-pysocks)
+       ("dateutil" ,python-dateutil)
+       ("packaging" ,python-packaging)
+       ("psutil" ,python-psutil)
+       ("intervaltree" ,python-intervaltree)
+       ("sortedcontainers" ,python-sortedcontainers)
+       ("unicorn" ,unicorn "python")
+
+       ;; See https://docs.pwntools.com/en/stable/install/binutils.html
+       ;; All architectures recognized by pwntools are included.
+       ("binutils:aarch64" ,(cross-binutils "aarch64-linux-gnu"))
+       ("binutils:alpha" ,(cross-binutils "alpha-linux-gnu"))
+       ("binutils:arm" ,(cross-binutils "arm-linux-gnueabihf"))
+       ;; TODO: AVR binutils aren't detected,
+       ;; see https://github.com/Gallopsled/pwntools/pull/1536
+       ("binutils:avr" ,avr-binutils)
+       ("binutils:cris" ,(cross-binutils "cris-linux-gnu"))
+       ("binutils:i686" ,(cross-binutils "i686-linux-gnu"))
+       ("binutils:ia64" ,(cross-binutils "ia64-linux-gnu"))
+       ("binutils:m68k" ,(cross-binutils "m68k-linux-gnu"))
+       ("binutils:mips" ,(cross-binutils "mipsel-linux-gnu"))
+       ("binutils:mips64" ,(cross-binutils "mips64el-linux-gnu"))
+       ;; TODO: MSP430 doesn't work for the same reason as AVR.
+       ("binutils:msp430" ,(cross-binutils "msp430"))
+       ("binutils:powerpc" ,(cross-binutils "powerpc-linux-gnu"))
+       ("binutils:powerpc64" ,(cross-binutils "powerpc64-linux-gnu"))
+       ;; TODO: Attempting to assemble code for arch='s390' complains
+       ;; about bfdname
+       ("binutils:s390" ,(cross-binutils "s390-linux-gnu"))
+       ("binutils:sparc" ,(cross-binutils "sparc-linux-gnu"))
+       ("binutils:sparc64" ,(cross-binutils "sparc64-linux-gnu"))
+       ;; TODO: Should VAX use a -linux-gnu target, or just "vax"?
+       ("binutils:vax" ,(cross-binutils "vax-linux-gnu"))
+       ("binutils:x86_64" ,(cross-binutils "x86_64-linux-gnu"))))
+    (native-inputs
+     `(("tox" ,python-tox)))
+    (home-page "https://github.com/Gallopsled/pwntools")
+    (synopsis "CTF framework and exploit development library")
+    (description "Pwntools is a CTF framework and exploit development library.
+Written in Python, it is designed for rapid prototyping and development, and
+intended to make exploit writing as simple as possible.")
+    ;; See LICENSE-pwntools.txt in the source distribution.
+    (license (list license:expat license:bsd-2 license:gpl2+))))
diff --git a/gnu/packages/patches/python-pwntools-guix-wrappers.patch b/gnu/packages/patches/python-pwntools-guix-wrappers.patch
new file mode 100644
index 0000000000..b79a22320d
--- /dev/null
+++ b/gnu/packages/patches/python-pwntools-guix-wrappers.patch
@@ -0,0 +1,14 @@
+Parse argv properly when the programs are wrapped by Guix.
+========================================================================
+diff --git a/pwnlib/commandline/common.py b/pwnlib/commandline/common.py
+index 75edfdcb..5249b6e6 100644
+--- a/pwnlib/commandline/common.py
++++ b/pwnlib/commandline/common.py
+@@ -28,5 +28,7 @@ parser_commands = parser.add_subparsers(dest='command')
+ def main(file=sys.argv[0]):
+     import pwnlib.commandline.main
+     name = os.path.splitext(os.path.basename(file))[0]
++    if name.startswith('.') and name.endswith('-real'):
++        name = name[1:-5]
+     sys.argv.insert(1, name)
+     pwnlib.commandline.main.main()
-- 
2.26.2
?