assemblyline-toolbox 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- assemblyline_toolbox-0.1.0/.github/workflows/CI.yml +186 -0
- assemblyline_toolbox-0.1.0/.gitignore +72 -0
- assemblyline_toolbox-0.1.0/Cargo.lock +202 -0
- assemblyline_toolbox-0.1.0/Cargo.toml +13 -0
- assemblyline_toolbox-0.1.0/PKG-INFO +7 -0
- assemblyline_toolbox-0.1.0/pyproject.toml +13 -0
- assemblyline_toolbox-0.1.0/readme.md +12 -0
- assemblyline_toolbox-0.1.0/src/frequency.rs +61 -0
- assemblyline_toolbox-0.1.0/src/lib.rs +15 -0
- assemblyline_toolbox-0.1.0/src/ssdeep.rs +36 -0
- assemblyline_toolbox-0.1.0/tests/test_frequency.py +22 -0
- assemblyline_toolbox-0.1.0/tests/test_ssdeep.py +24 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
# This file is autogenerated by maturin v1.12.6
|
|
2
|
+
# To update, run
|
|
3
|
+
#
|
|
4
|
+
# maturin generate-ci github
|
|
5
|
+
#
|
|
6
|
+
name: CI
|
|
7
|
+
|
|
8
|
+
on:
|
|
9
|
+
push:
|
|
10
|
+
branches:
|
|
11
|
+
- main
|
|
12
|
+
- master
|
|
13
|
+
tags:
|
|
14
|
+
- '*'
|
|
15
|
+
pull_request:
|
|
16
|
+
workflow_dispatch:
|
|
17
|
+
|
|
18
|
+
permissions:
|
|
19
|
+
contents: read
|
|
20
|
+
|
|
21
|
+
jobs:
|
|
22
|
+
linux:
|
|
23
|
+
runs-on: ${{ matrix.platform.runner }}
|
|
24
|
+
strategy:
|
|
25
|
+
matrix:
|
|
26
|
+
platform:
|
|
27
|
+
- runner: ubuntu-22.04
|
|
28
|
+
target: x86_64
|
|
29
|
+
- runner: ubuntu-22.04
|
|
30
|
+
target: x86
|
|
31
|
+
- runner: ubuntu-22.04
|
|
32
|
+
target: aarch64
|
|
33
|
+
- runner: ubuntu-22.04
|
|
34
|
+
target: armv7
|
|
35
|
+
- runner: ubuntu-22.04
|
|
36
|
+
target: s390x
|
|
37
|
+
- runner: ubuntu-22.04
|
|
38
|
+
target: ppc64le
|
|
39
|
+
steps:
|
|
40
|
+
- uses: actions/checkout@v6
|
|
41
|
+
- uses: actions/setup-python@v6
|
|
42
|
+
with:
|
|
43
|
+
python-version: 3.x
|
|
44
|
+
- name: Build wheels
|
|
45
|
+
uses: PyO3/maturin-action@v1
|
|
46
|
+
with:
|
|
47
|
+
target: ${{ matrix.platform.target }}
|
|
48
|
+
args: --release --out dist --find-interpreter
|
|
49
|
+
sccache: ${{ !startsWith(github.ref, 'refs/tags/') }}
|
|
50
|
+
manylinux: auto
|
|
51
|
+
- name: Upload wheels
|
|
52
|
+
uses: actions/upload-artifact@v6
|
|
53
|
+
with:
|
|
54
|
+
name: wheels-linux-${{ matrix.platform.target }}
|
|
55
|
+
path: dist
|
|
56
|
+
|
|
57
|
+
musllinux:
|
|
58
|
+
runs-on: ${{ matrix.platform.runner }}
|
|
59
|
+
strategy:
|
|
60
|
+
matrix:
|
|
61
|
+
platform:
|
|
62
|
+
- runner: ubuntu-22.04
|
|
63
|
+
target: x86_64
|
|
64
|
+
- runner: ubuntu-22.04
|
|
65
|
+
target: x86
|
|
66
|
+
- runner: ubuntu-22.04
|
|
67
|
+
target: aarch64
|
|
68
|
+
- runner: ubuntu-22.04
|
|
69
|
+
target: armv7
|
|
70
|
+
steps:
|
|
71
|
+
- uses: actions/checkout@v6
|
|
72
|
+
- uses: actions/setup-python@v6
|
|
73
|
+
with:
|
|
74
|
+
python-version: 3.x
|
|
75
|
+
- name: Build wheels
|
|
76
|
+
uses: PyO3/maturin-action@v1
|
|
77
|
+
with:
|
|
78
|
+
target: ${{ matrix.platform.target }}
|
|
79
|
+
args: --release --out dist --find-interpreter
|
|
80
|
+
sccache: ${{ !startsWith(github.ref, 'refs/tags/') }}
|
|
81
|
+
manylinux: musllinux_1_2
|
|
82
|
+
- name: Upload wheels
|
|
83
|
+
uses: actions/upload-artifact@v6
|
|
84
|
+
with:
|
|
85
|
+
name: wheels-musllinux-${{ matrix.platform.target }}
|
|
86
|
+
path: dist
|
|
87
|
+
|
|
88
|
+
windows:
|
|
89
|
+
runs-on: ${{ matrix.platform.runner }}
|
|
90
|
+
strategy:
|
|
91
|
+
matrix:
|
|
92
|
+
platform:
|
|
93
|
+
- runner: windows-latest
|
|
94
|
+
target: x64
|
|
95
|
+
python_arch: x64
|
|
96
|
+
- runner: windows-latest
|
|
97
|
+
target: x86
|
|
98
|
+
python_arch: x86
|
|
99
|
+
- runner: windows-11-arm
|
|
100
|
+
target: aarch64
|
|
101
|
+
python_arch: arm64
|
|
102
|
+
steps:
|
|
103
|
+
- uses: actions/checkout@v6
|
|
104
|
+
- uses: actions/setup-python@v6
|
|
105
|
+
with:
|
|
106
|
+
python-version: 3.13
|
|
107
|
+
architecture: ${{ matrix.platform.python_arch }}
|
|
108
|
+
- name: Build wheels
|
|
109
|
+
uses: PyO3/maturin-action@v1
|
|
110
|
+
with:
|
|
111
|
+
target: ${{ matrix.platform.target }}
|
|
112
|
+
args: --release --out dist --find-interpreter
|
|
113
|
+
sccache: ${{ !startsWith(github.ref, 'refs/tags/') }}
|
|
114
|
+
- name: Upload wheels
|
|
115
|
+
uses: actions/upload-artifact@v6
|
|
116
|
+
with:
|
|
117
|
+
name: wheels-windows-${{ matrix.platform.target }}
|
|
118
|
+
path: dist
|
|
119
|
+
|
|
120
|
+
macos:
|
|
121
|
+
runs-on: ${{ matrix.platform.runner }}
|
|
122
|
+
strategy:
|
|
123
|
+
matrix:
|
|
124
|
+
platform:
|
|
125
|
+
- runner: macos-15-intel
|
|
126
|
+
target: x86_64
|
|
127
|
+
- runner: macos-latest
|
|
128
|
+
target: aarch64
|
|
129
|
+
steps:
|
|
130
|
+
- uses: actions/checkout@v6
|
|
131
|
+
- uses: actions/setup-python@v6
|
|
132
|
+
with:
|
|
133
|
+
python-version: 3.x
|
|
134
|
+
- name: Build wheels
|
|
135
|
+
uses: PyO3/maturin-action@v1
|
|
136
|
+
with:
|
|
137
|
+
target: ${{ matrix.platform.target }}
|
|
138
|
+
args: --release --out dist --find-interpreter
|
|
139
|
+
sccache: ${{ !startsWith(github.ref, 'refs/tags/') }}
|
|
140
|
+
- name: Upload wheels
|
|
141
|
+
uses: actions/upload-artifact@v6
|
|
142
|
+
with:
|
|
143
|
+
name: wheels-macos-${{ matrix.platform.target }}
|
|
144
|
+
path: dist
|
|
145
|
+
|
|
146
|
+
sdist:
|
|
147
|
+
runs-on: ubuntu-latest
|
|
148
|
+
steps:
|
|
149
|
+
- uses: actions/checkout@v6
|
|
150
|
+
- name: Build sdist
|
|
151
|
+
uses: PyO3/maturin-action@v1
|
|
152
|
+
with:
|
|
153
|
+
command: sdist
|
|
154
|
+
args: --out dist
|
|
155
|
+
- name: Upload sdist
|
|
156
|
+
uses: actions/upload-artifact@v6
|
|
157
|
+
with:
|
|
158
|
+
name: wheels-sdist
|
|
159
|
+
path: dist
|
|
160
|
+
|
|
161
|
+
release:
|
|
162
|
+
name: Release
|
|
163
|
+
runs-on: ubuntu-latest
|
|
164
|
+
if: ${{ startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch' }}
|
|
165
|
+
needs: [linux, musllinux, windows, macos, sdist]
|
|
166
|
+
permissions:
|
|
167
|
+
# Use to sign the release artifacts
|
|
168
|
+
id-token: write
|
|
169
|
+
# Used to upload release artifacts
|
|
170
|
+
contents: write
|
|
171
|
+
# Used to generate artifact attestation
|
|
172
|
+
attestations: write
|
|
173
|
+
steps:
|
|
174
|
+
- uses: actions/download-artifact@v7
|
|
175
|
+
- name: Generate artifact attestation
|
|
176
|
+
uses: actions/attest-build-provenance@v3
|
|
177
|
+
with:
|
|
178
|
+
subject-path: 'wheels-*/*'
|
|
179
|
+
- name: Install uv
|
|
180
|
+
if: ${{ startsWith(github.ref, 'refs/tags/') }}
|
|
181
|
+
uses: astral-sh/setup-uv@v7
|
|
182
|
+
- name: Publish to PyPI
|
|
183
|
+
if: ${{ startsWith(github.ref, 'refs/tags/') }}
|
|
184
|
+
run: uv publish 'wheels-*/*'
|
|
185
|
+
env:
|
|
186
|
+
UV_PUBLISH_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/target
|
|
2
|
+
|
|
3
|
+
# Byte-compiled / optimized / DLL files
|
|
4
|
+
__pycache__/
|
|
5
|
+
.pytest_cache/
|
|
6
|
+
*.py[cod]
|
|
7
|
+
|
|
8
|
+
# C extensions
|
|
9
|
+
*.so
|
|
10
|
+
|
|
11
|
+
# Distribution / packaging
|
|
12
|
+
.Python
|
|
13
|
+
.venv/
|
|
14
|
+
env/
|
|
15
|
+
bin/
|
|
16
|
+
build/
|
|
17
|
+
develop-eggs/
|
|
18
|
+
dist/
|
|
19
|
+
eggs/
|
|
20
|
+
lib/
|
|
21
|
+
lib64/
|
|
22
|
+
parts/
|
|
23
|
+
sdist/
|
|
24
|
+
var/
|
|
25
|
+
include/
|
|
26
|
+
man/
|
|
27
|
+
venv/
|
|
28
|
+
*.egg-info/
|
|
29
|
+
.installed.cfg
|
|
30
|
+
*.egg
|
|
31
|
+
|
|
32
|
+
# Installer logs
|
|
33
|
+
pip-log.txt
|
|
34
|
+
pip-delete-this-directory.txt
|
|
35
|
+
pip-selfcheck.json
|
|
36
|
+
|
|
37
|
+
# Unit test / coverage reports
|
|
38
|
+
htmlcov/
|
|
39
|
+
.tox/
|
|
40
|
+
.coverage
|
|
41
|
+
.cache
|
|
42
|
+
nosetests.xml
|
|
43
|
+
coverage.xml
|
|
44
|
+
|
|
45
|
+
# Translations
|
|
46
|
+
*.mo
|
|
47
|
+
|
|
48
|
+
# Mr Developer
|
|
49
|
+
.mr.developer.cfg
|
|
50
|
+
.project
|
|
51
|
+
.pydevproject
|
|
52
|
+
|
|
53
|
+
# Rope
|
|
54
|
+
.ropeproject
|
|
55
|
+
|
|
56
|
+
# Django stuff:
|
|
57
|
+
*.log
|
|
58
|
+
*.pot
|
|
59
|
+
|
|
60
|
+
.DS_Store
|
|
61
|
+
|
|
62
|
+
# Sphinx documentation
|
|
63
|
+
docs/_build/
|
|
64
|
+
|
|
65
|
+
# PyCharm
|
|
66
|
+
.idea/
|
|
67
|
+
|
|
68
|
+
# VSCode
|
|
69
|
+
.vscode/
|
|
70
|
+
|
|
71
|
+
# Pyenv
|
|
72
|
+
.python-version
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
# This file is automatically @generated by Cargo.
|
|
2
|
+
# It is not intended for manual editing.
|
|
3
|
+
version = 4
|
|
4
|
+
|
|
5
|
+
[[package]]
|
|
6
|
+
name = "assemblyline-toolbox"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
dependencies = [
|
|
9
|
+
"ffuzzy",
|
|
10
|
+
"pyo3",
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
[[package]]
|
|
14
|
+
name = "autocfg"
|
|
15
|
+
version = "1.5.0"
|
|
16
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
17
|
+
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
|
|
18
|
+
|
|
19
|
+
[[package]]
|
|
20
|
+
name = "cfg-if"
|
|
21
|
+
version = "1.0.4"
|
|
22
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
23
|
+
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
|
24
|
+
|
|
25
|
+
[[package]]
|
|
26
|
+
name = "ffuzzy"
|
|
27
|
+
version = "0.3.16"
|
|
28
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
29
|
+
checksum = "ce4602f12666608260e6b31f021f3699cacbdeaf80519860d79512458d94485f"
|
|
30
|
+
dependencies = [
|
|
31
|
+
"cfg-if",
|
|
32
|
+
"static_assertions",
|
|
33
|
+
"version_check",
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
[[package]]
|
|
37
|
+
name = "heck"
|
|
38
|
+
version = "0.5.0"
|
|
39
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
40
|
+
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
|
41
|
+
|
|
42
|
+
[[package]]
|
|
43
|
+
name = "indoc"
|
|
44
|
+
version = "2.0.7"
|
|
45
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
46
|
+
checksum = "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706"
|
|
47
|
+
dependencies = [
|
|
48
|
+
"rustversion",
|
|
49
|
+
]
|
|
50
|
+
|
|
51
|
+
[[package]]
|
|
52
|
+
name = "libc"
|
|
53
|
+
version = "0.2.183"
|
|
54
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
55
|
+
checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d"
|
|
56
|
+
|
|
57
|
+
[[package]]
|
|
58
|
+
name = "memoffset"
|
|
59
|
+
version = "0.9.1"
|
|
60
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
61
|
+
checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
|
|
62
|
+
dependencies = [
|
|
63
|
+
"autocfg",
|
|
64
|
+
]
|
|
65
|
+
|
|
66
|
+
[[package]]
|
|
67
|
+
name = "once_cell"
|
|
68
|
+
version = "1.21.4"
|
|
69
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
70
|
+
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
|
|
71
|
+
|
|
72
|
+
[[package]]
|
|
73
|
+
name = "portable-atomic"
|
|
74
|
+
version = "1.13.1"
|
|
75
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
76
|
+
checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49"
|
|
77
|
+
|
|
78
|
+
[[package]]
|
|
79
|
+
name = "proc-macro2"
|
|
80
|
+
version = "1.0.106"
|
|
81
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
82
|
+
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
|
|
83
|
+
dependencies = [
|
|
84
|
+
"unicode-ident",
|
|
85
|
+
]
|
|
86
|
+
|
|
87
|
+
[[package]]
|
|
88
|
+
name = "pyo3"
|
|
89
|
+
version = "0.27.2"
|
|
90
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
91
|
+
checksum = "ab53c047fcd1a1d2a8820fe84f05d6be69e9526be40cb03b73f86b6b03e6d87d"
|
|
92
|
+
dependencies = [
|
|
93
|
+
"indoc",
|
|
94
|
+
"libc",
|
|
95
|
+
"memoffset",
|
|
96
|
+
"once_cell",
|
|
97
|
+
"portable-atomic",
|
|
98
|
+
"pyo3-build-config",
|
|
99
|
+
"pyo3-ffi",
|
|
100
|
+
"pyo3-macros",
|
|
101
|
+
"unindent",
|
|
102
|
+
]
|
|
103
|
+
|
|
104
|
+
[[package]]
|
|
105
|
+
name = "pyo3-build-config"
|
|
106
|
+
version = "0.27.2"
|
|
107
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
108
|
+
checksum = "b455933107de8642b4487ed26d912c2d899dec6114884214a0b3bb3be9261ea6"
|
|
109
|
+
dependencies = [
|
|
110
|
+
"target-lexicon",
|
|
111
|
+
]
|
|
112
|
+
|
|
113
|
+
[[package]]
|
|
114
|
+
name = "pyo3-ffi"
|
|
115
|
+
version = "0.27.2"
|
|
116
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
117
|
+
checksum = "1c85c9cbfaddf651b1221594209aed57e9e5cff63c4d11d1feead529b872a089"
|
|
118
|
+
dependencies = [
|
|
119
|
+
"libc",
|
|
120
|
+
"pyo3-build-config",
|
|
121
|
+
]
|
|
122
|
+
|
|
123
|
+
[[package]]
|
|
124
|
+
name = "pyo3-macros"
|
|
125
|
+
version = "0.27.2"
|
|
126
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
127
|
+
checksum = "0a5b10c9bf9888125d917fb4d2ca2d25c8df94c7ab5a52e13313a07e050a3b02"
|
|
128
|
+
dependencies = [
|
|
129
|
+
"proc-macro2",
|
|
130
|
+
"pyo3-macros-backend",
|
|
131
|
+
"quote",
|
|
132
|
+
"syn",
|
|
133
|
+
]
|
|
134
|
+
|
|
135
|
+
[[package]]
|
|
136
|
+
name = "pyo3-macros-backend"
|
|
137
|
+
version = "0.27.2"
|
|
138
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
139
|
+
checksum = "03b51720d314836e53327f5871d4c0cfb4fb37cc2c4a11cc71907a86342c40f9"
|
|
140
|
+
dependencies = [
|
|
141
|
+
"heck",
|
|
142
|
+
"proc-macro2",
|
|
143
|
+
"pyo3-build-config",
|
|
144
|
+
"quote",
|
|
145
|
+
"syn",
|
|
146
|
+
]
|
|
147
|
+
|
|
148
|
+
[[package]]
|
|
149
|
+
name = "quote"
|
|
150
|
+
version = "1.0.45"
|
|
151
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
152
|
+
checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
|
|
153
|
+
dependencies = [
|
|
154
|
+
"proc-macro2",
|
|
155
|
+
]
|
|
156
|
+
|
|
157
|
+
[[package]]
|
|
158
|
+
name = "rustversion"
|
|
159
|
+
version = "1.0.22"
|
|
160
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
161
|
+
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
|
|
162
|
+
|
|
163
|
+
[[package]]
|
|
164
|
+
name = "static_assertions"
|
|
165
|
+
version = "1.1.0"
|
|
166
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
167
|
+
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
|
168
|
+
|
|
169
|
+
[[package]]
|
|
170
|
+
name = "syn"
|
|
171
|
+
version = "2.0.117"
|
|
172
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
173
|
+
checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
|
|
174
|
+
dependencies = [
|
|
175
|
+
"proc-macro2",
|
|
176
|
+
"quote",
|
|
177
|
+
"unicode-ident",
|
|
178
|
+
]
|
|
179
|
+
|
|
180
|
+
[[package]]
|
|
181
|
+
name = "target-lexicon"
|
|
182
|
+
version = "0.13.5"
|
|
183
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
184
|
+
checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca"
|
|
185
|
+
|
|
186
|
+
[[package]]
|
|
187
|
+
name = "unicode-ident"
|
|
188
|
+
version = "1.0.24"
|
|
189
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
190
|
+
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
|
|
191
|
+
|
|
192
|
+
[[package]]
|
|
193
|
+
name = "unindent"
|
|
194
|
+
version = "0.2.4"
|
|
195
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
196
|
+
checksum = "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3"
|
|
197
|
+
|
|
198
|
+
[[package]]
|
|
199
|
+
name = "version_check"
|
|
200
|
+
version = "0.9.5"
|
|
201
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
202
|
+
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
[package]
|
|
2
|
+
name = "assemblyline-toolbox"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
edition = "2024"
|
|
5
|
+
|
|
6
|
+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
7
|
+
[lib]
|
|
8
|
+
name = "assemblyline_toolbox"
|
|
9
|
+
crate-type = ["cdylib"]
|
|
10
|
+
|
|
11
|
+
[dependencies]
|
|
12
|
+
pyo3 = "0.27.0"
|
|
13
|
+
ffuzzy = "0.3"
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: assemblyline-toolbox
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Classifier: Programming Language :: Rust
|
|
5
|
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
6
|
+
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
7
|
+
Requires-Python: >=3.8
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["maturin>=1.12,<2.0"]
|
|
3
|
+
build-backend = "maturin"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "assemblyline-toolbox"
|
|
7
|
+
requires-python = ">=3.8"
|
|
8
|
+
classifiers = [
|
|
9
|
+
"Programming Language :: Rust",
|
|
10
|
+
"Programming Language :: Python :: Implementation :: CPython",
|
|
11
|
+
"Programming Language :: Python :: Implementation :: PyPy",
|
|
12
|
+
]
|
|
13
|
+
dynamic = ["version"]
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
# Assemblyline toolbox
|
|
4
|
+
|
|
5
|
+
Bindings for rust components to be exposed to python.
|
|
6
|
+
|
|
7
|
+
## Repo status
|
|
8
|
+
|
|
9
|
+
This package is separated from the other assemblyline rust components as the `maturin` toolchain it is using comes bundled with action hooks for github which our main build pipeline doesn't use. While these bindings are under development, or until those actions are ported to our main pipeline, this repo can be used to build python packages that can be _version pinned_ in the assemblyline python packagaes.
|
|
10
|
+
|
|
11
|
+
_This does mean that the rust code available to python packages will be slightly out of step and require manual builds on this repo to update._
|
|
12
|
+
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
//! Utilities used for fast byte counting in python
|
|
2
|
+
//!
|
|
3
|
+
//! This is duplicated from the assemblyline-server crate due to its simplicity.
|
|
4
|
+
|
|
5
|
+
use pyo3::{pyclass, pymethods};
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
/// A counter that accumulates byte frequencies in order to calculate entropy
|
|
9
|
+
#[pyclass]
|
|
10
|
+
pub struct BufferedCalculator {
|
|
11
|
+
counts: Box<[u64; 256]>,
|
|
12
|
+
length: u64,
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
#[pymethods]
|
|
17
|
+
impl BufferedCalculator {
|
|
18
|
+
#[new]
|
|
19
|
+
pub fn py_new() -> Self {
|
|
20
|
+
Self {
|
|
21
|
+
counts: Box::new([0; 256]),
|
|
22
|
+
length: 0,
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
pub fn len(&self) -> u64 {
|
|
27
|
+
self.length
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
pub fn entropy(&self) -> f64 {
|
|
31
|
+
if self.length == 0 {
|
|
32
|
+
return 0.0;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
let length = self.length as f64;
|
|
36
|
+
|
|
37
|
+
let mut entropy = 0.0;
|
|
38
|
+
for v in self.counts.iter() {
|
|
39
|
+
let prob = *v as f64 / length;
|
|
40
|
+
if prob != 0.0 {
|
|
41
|
+
entropy += prob * prob.log2();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
entropy *= -1.0;
|
|
46
|
+
|
|
47
|
+
// Make sure we don't return -0.0. Just keep things pretty.
|
|
48
|
+
if entropy == -0.0 {
|
|
49
|
+
entropy = 0.0;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return entropy
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
pub fn update(&mut self, data: &[u8]) {
|
|
56
|
+
self.length += data.len() as u64;
|
|
57
|
+
for byte in data {
|
|
58
|
+
self.counts[*byte as usize] += 1;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#![allow(clippy::needless_return)]
|
|
2
|
+
|
|
3
|
+
mod frequency;
|
|
4
|
+
mod ssdeep;
|
|
5
|
+
use pyo3::prelude::*;
|
|
6
|
+
|
|
7
|
+
/// A collection of tools implemented in rust exported for python components of assemblyline
|
|
8
|
+
#[pymodule]
|
|
9
|
+
pub mod assemblyline_toolbox {
|
|
10
|
+
#[pymodule_export]
|
|
11
|
+
use crate::frequency::BufferedCalculator;
|
|
12
|
+
#[pymodule_export]
|
|
13
|
+
use crate::ssdeep::SsdeepHasher;
|
|
14
|
+
}
|
|
15
|
+
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#![allow(clippy::collapsible_if)]
|
|
2
|
+
use pyo3::exceptions::PyValueError;
|
|
3
|
+
use pyo3::{PyResult, pyclass, pymethods};
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
#[pyclass]
|
|
7
|
+
pub struct SsdeepHasher {
|
|
8
|
+
hasher: ssdeep::Generator
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
#[pymethods]
|
|
12
|
+
impl SsdeepHasher {
|
|
13
|
+
#[new]
|
|
14
|
+
#[pyo3(signature = (fixed_length=None))]
|
|
15
|
+
pub fn py_new(fixed_length: Option<u64>) -> PyResult<Self> {
|
|
16
|
+
let mut hasher = ssdeep::Generator::new();
|
|
17
|
+
if let Some(length) = fixed_length {
|
|
18
|
+
if let Err(err) = hasher.set_fixed_input_size(length) {
|
|
19
|
+
return Err(PyValueError::new_err(format!("Could not build ssdeep hasher with length {length}: {err}")))
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
Ok(Self{ hasher })
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
pub fn update(&mut self, data: &[u8]) {
|
|
26
|
+
self.hasher.update(data);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
pub fn digest(&self) -> PyResult<String> {
|
|
30
|
+
match self.hasher.finalize() {
|
|
31
|
+
Ok(digest) => Ok(digest.to_string()),
|
|
32
|
+
Err(err) => Err(PyValueError::new_err(format!("Could not finish ssdeep hash: {err}"))),
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
|
|
2
|
+
import random
|
|
3
|
+
|
|
4
|
+
from assemblyline_toolbox import BufferedCalculator
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def test_entropy():
|
|
8
|
+
|
|
9
|
+
calculator = BufferedCalculator()
|
|
10
|
+
assert calculator.entropy() == 0
|
|
11
|
+
|
|
12
|
+
calculator = BufferedCalculator()
|
|
13
|
+
calculator.update(b"1" * 10000)
|
|
14
|
+
assert calculator.entropy() == 0
|
|
15
|
+
assert calculator.len() == 10000
|
|
16
|
+
|
|
17
|
+
calculator = BufferedCalculator()
|
|
18
|
+
calculator.update(bytes([random.randint(1, 255) for _ in range(10000)]))
|
|
19
|
+
assert calculator.entropy() > 7.5
|
|
20
|
+
assert calculator.len() == 10000
|
|
21
|
+
|
|
22
|
+
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
from assemblyline_toolbox import SsdeepHasher
|
|
3
|
+
|
|
4
|
+
SAMPLE = b"A very interesting block of sample text that is totally innocent and can't be faulted in any way."
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def test_ssdeep():
|
|
8
|
+
|
|
9
|
+
calculator = SsdeepHasher()
|
|
10
|
+
print(calculator.digest())
|
|
11
|
+
|
|
12
|
+
calculator = SsdeepHasher()
|
|
13
|
+
calculator.update(SAMPLE[0:10])
|
|
14
|
+
calculator.update(SAMPLE[10:])
|
|
15
|
+
assert calculator.digest() == '3:M0HLGiKZOER2WFsPsI4FT205JiMLi:M0iSERW3ITiKi'
|
|
16
|
+
|
|
17
|
+
calculator = SsdeepHasher(len(SAMPLE))
|
|
18
|
+
calculator.update(SAMPLE)
|
|
19
|
+
assert calculator.digest() == '3:M0HLGiKZOER2WFsPsI4FT205JiMLi:M0iSERW3ITiKi'
|
|
20
|
+
|
|
21
|
+
with pytest.raises(ValueError, match='fixed size'):
|
|
22
|
+
calculator = SsdeepHasher(len(SAMPLE))
|
|
23
|
+
calculator.update(SAMPLE * 2)
|
|
24
|
+
calculator.digest()
|