commit: 0de81dd1aa58a80fd9a8b6d856b25651c7873061
parent e36122f81530a6e6f0e5aeb3f4136536e992c24e
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date: Thu, 27 Oct 2022 00:11:11 +0200
Add support for Python pickle files
Diffstat:
11 files changed, 48 insertions(+), 5 deletions(-)
diff --git a/.reuse/dep5 b/.reuse/dep5
@@ -3,6 +3,6 @@ Upstream-Name: deblob
Upstream-Contact: deblob Authors <https://hacktivis.me/projects/deblob>
Source: https://hacktivis.me/projects/deblob
-Files: test/fixtures/pyc/*.pyc test/fixtures/hello.luac* test/fixtures/hello.class test/fixtures/hello.nqp.moarvm test/fixtures/hello.pir.pbc test/fixtures/perl_storage.pst test/fixtures/hello.beam test/fixtures/empty.dtb test/fixtures/hello-chez.so
+Files: test/fixtures/pyc/*.pyc test/fixtures/pickle/*.pickle test/fixtures/hello.luac* test/fixtures/hello.class test/fixtures/hello.nqp.moarvm test/fixtures/hello.pir.pbc test/fixtures/perl_storage.pst test/fixtures/hello.beam test/fixtures/empty.dtb test/fixtures/hello-chez.so
Copyright: 2019-2022 deblob Authors <https://hacktivis.me/projects/deblob>
License: BSD-3-Clause
diff --git a/Makefile b/Makefile
@@ -22,16 +22,19 @@ clean:
rm -f $(EXE)
$(MAKE) -C test/fixtures clean
-.PHONY: test
-test: all
+.PHONY: test-fixtures
+test-fixtures: all
@if $(MAKE) --version | grep -q GNU; then echo 'GNU Make is not my favorite make implementation'; fi
$(MAKE) -C test/fixtures
+test: test-fixtures test-pyc test-pickle
rm -fr test/check_dir-fixtures
cp -r test/fixtures test/check_dir-fixtures
$(HARE) $(HAREFLAGS) test
rm -fr test/check_dir-fixtures
+.PHONY: test-pyc
+test-pyc: test-fixtures
rm -fr test/check_dir_pyc-fixtures
cp -r test/fixtures/pyc/ test/check_dir_pyc-fixtures
test -n "$$(ls test/check_dir_pyc-fixtures)"
@@ -39,6 +42,15 @@ test: all
test -z "$$(ls test/check_dir_pyc-fixtures)"
rm -fr test/check_dir_pyc-fixtures
+.PHONY: test-pickle
+test-pickle: test-fixtures
+ rm -fr test/check_dir_pickle-fixtures
+ cp -r test/fixtures/pickle/ test/check_dir_pickle-fixtures
+ test "$$(find test/check_dir_pickle-fixtures -type f | wc -l)" -eq "6"
+ ./deblob -d test/check_dir_pickle-fixtures
+ test "$$(find test/check_dir_pickle-fixtures -type f | wc -l)" -eq "2"
+ rm -fr test/check_dir_pickle-fixtures
+
.PHONY: lint
lint:
$(MANDOC) -Tlint -Wunsupp,error,warning $(EXE).1
diff --git a/deblob.1 b/deblob.1
@@ -50,6 +50,8 @@ Java Class files
Python 2.7 & 3.8/3.9/3.10 bytecode files, typically
.Sq *.pyc
.It
+Python pickle files, used to serialize Python objects
+.It
Portable Executable files, typically
.Sq *.exe
and
diff --git a/main.ha b/main.ha
@@ -32,6 +32,12 @@ const magic: [_][]u8 = [
[0x55, 0x0D, '\r', '\n'], // (3413i litte-endian) Python 3.8
[0x61, 0x0D, '\r', '\n'], // (3425i litte-endian) Python 3.9
[0x6F, 0x0D, '\r', '\n'], // (3439i litte-endian) Python 3.10
+ // Python pickle object data, similarly to Perl Storage it's dangerous enough to cause code execution
+ [0x80, 0x02], // Protocol 2 + start of frame
+ [0x80, 0x03], // Protocol 3 + start of frame
+ [0x80, 0x04, 0x95], // Protocol 4 + start of frame
+ [0x80, 0x05, 0x95], // Protocol 5 + start of frame
+
// MoarVM bytecode https://github.com/MoarVM/MoarVM/blob/master/docs/bytecode.markdown
['M', 'O', 'A', 'R', 'V', 'M', '\r', '\n'],
// Parrot Bytecode https://github.com/parrot/parrot/blob/master/docs/parrotbyte.pod
@@ -103,6 +109,8 @@ fn is_blob(filename: str) (bool | fs::error | io::error) = {
(true, "test/fixtures/monodx.dll"),
//(true, "test/fixtures/option.rom"),
(true, "test/fixtures/perl_storage.pst"),
+ (true, "test/fixtures/pickle/hello.4.pickle"),
+ (true, "test/fixtures/pickle/hello.5.pickle"),
(true, "test/fixtures/qemu_vga.ndrv"),
];
@@ -204,7 +212,7 @@ fn check_dir(dirname: str) (void | errors::invalid) = {
case let e: fs::error =>
fmt::fatalf("os::readdir({}): {}", dirname, fs::strerror(e));
};
- assert(len(files_before) == 39);
+ assert(len(files_before) == 40);
const ret = check_dir(dirname);
assert(ret is void);
@@ -215,7 +223,7 @@ fn check_dir(dirname: str) (void | errors::invalid) = {
case let e: fs::error =>
fmt::fatalf("os::readdir({}): {}", dirname, fs::strerror(e));
};
- assert(len(files_after) == 23);
+ assert(len(files_after) == 24);
};
export fn main() void = {
diff --git a/test/fixtures/pickle/hello.0.pickle b/test/fixtures/pickle/hello.0.pickle
@@ -0,0 +1,4 @@
+c__main__
+hello
+p0
+.
+\ No newline at end of file
diff --git a/test/fixtures/pickle/hello.1.pickle b/test/fixtures/pickle/hello.1.pickle
Binary files differ.
diff --git a/test/fixtures/pickle/hello.2.pickle b/test/fixtures/pickle/hello.2.pickle
Binary files differ.
diff --git a/test/fixtures/pickle/hello.3.pickle b/test/fixtures/pickle/hello.3.pickle
Binary files differ.
diff --git a/test/fixtures/pickle/hello.4.pickle b/test/fixtures/pickle/hello.4.pickle
Binary files differ.
diff --git a/test/fixtures/pickle/hello.5.pickle b/test/fixtures/pickle/hello.5.pickle
Binary files differ.
diff --git a/test/python_pickle.py b/test/python_pickle.py
@@ -0,0 +1,16 @@
+#!/usr/bin/python
+# SPDX-FileCopyrightText: 2019-2022 deblob Authors <https://hacktivis.me/projects/deblob>
+# SPDX-License-Identifier: BSD-3-Clause
+
+import pickle
+
+def hello():
+ print("Hello, World!")
+
+
+for protocol in range(0, pickle.HIGHEST_PROTOCOL+1):
+ dest_file = "./test/fixtures/pickle/hello.{}.pickle".format(protocol)
+ print(dest_file)
+ fh = open(dest_file, "xb")
+ pickle.dump(hello, fh, protocol)
+ fh.close()