oscura 0.10.0__py3-none-any.whl → 0.11.0__py3-none-any.whl
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.
- oscura/__init__.py +1 -1
- oscura/__main__.py +4 -0
- oscura/analyzers/ml/signal_classifier.py +6 -0
- oscura/analyzers/waveform/spectral.py +18 -11
- oscura/automotive/__init__.py +1 -1
- oscura/automotive/dtc/data.json +17 -102
- oscura/automotive/flexray/fibex.py +9 -1
- oscura/core/schemas/device_mapping.json +2 -8
- oscura/core/schemas/packet_format.json +4 -24
- oscura/core/schemas/protocol_definition.json +2 -12
- oscura/loaders/validation.py +17 -10
- oscura/sessions/legacy.py +49 -1
- oscura/workflows/batch/aggregate.py +5 -1
- oscura-0.11.0.dist-info/METADATA +460 -0
- {oscura-0.10.0.dist-info → oscura-0.11.0.dist-info}/RECORD +18 -18
- oscura-0.10.0.dist-info/METADATA +0 -641
- {oscura-0.10.0.dist-info → oscura-0.11.0.dist-info}/WHEEL +0 -0
- {oscura-0.10.0.dist-info → oscura-0.11.0.dist-info}/entry_points.txt +0 -0
- {oscura-0.10.0.dist-info → oscura-0.11.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,460 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: oscura
|
|
3
|
+
Version: 0.11.0
|
|
4
|
+
Summary: Python framework for hardware reverse engineering: signal analysis, protocol decoding, and automated dissector generation. Unified workflows from oscilloscope captures to Wireshark dissectors with IEEE-compliant measurements.
|
|
5
|
+
Project-URL: Homepage, https://github.com/oscura-re/oscura
|
|
6
|
+
Project-URL: Documentation, https://github.com/oscura-re/oscura/tree/main/docs
|
|
7
|
+
Project-URL: Repository, https://github.com/oscura-re/oscura
|
|
8
|
+
Project-URL: Changelog, https://github.com/oscura-re/oscura/blob/main/CHANGELOG.md
|
|
9
|
+
Project-URL: Issue Tracker, https://github.com/oscura-re/oscura/issues
|
|
10
|
+
Project-URL: Discussions, https://github.com/oscura-re/oscura/discussions
|
|
11
|
+
License-Expression: MIT
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Keywords: automotive-protocols,can-bus,crc-recovery,device-replication,embedded-systems,exploitation,hardware-reverse-engineering,hardware-security,i2c,ieee-compliance,logic-analyzer,obd-ii,oscilloscope,protocol-analysis,protocol-decoder,protocol-inference,reverse-engineering,right-to-repair,security-research,signal-analysis,spectral-analysis,spi,state-machine-learning,uart,unknown-protocol,vulnerability-analysis,waveform-analysis
|
|
14
|
+
Classifier: Development Status :: 3 - Alpha
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: Intended Audience :: Information Technology
|
|
17
|
+
Classifier: Intended Audience :: Science/Research
|
|
18
|
+
Classifier: Intended Audience :: Telecommunications Industry
|
|
19
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
20
|
+
Classifier: Operating System :: OS Independent
|
|
21
|
+
Classifier: Programming Language :: Python :: 3
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
24
|
+
Classifier: Topic :: Scientific/Engineering
|
|
25
|
+
Classifier: Topic :: Scientific/Engineering :: Information Analysis
|
|
26
|
+
Classifier: Topic :: Security
|
|
27
|
+
Classifier: Topic :: System :: Hardware
|
|
28
|
+
Classifier: Topic :: System :: Hardware :: Hardware Drivers
|
|
29
|
+
Classifier: Typing :: Typed
|
|
30
|
+
Requires-Python: >=3.12
|
|
31
|
+
Requires-Dist: cantools<40.0.0,>=39.4.0
|
|
32
|
+
Requires-Dist: click<9.0.0,>=8.1.0
|
|
33
|
+
Requires-Dist: dpkt<2.0.0,>=1.9.0
|
|
34
|
+
Requires-Dist: jinja2<4.0.0,>=3.1
|
|
35
|
+
Requires-Dist: matplotlib<4.0.0,>=3.7.0
|
|
36
|
+
Requires-Dist: numpy<3.0.0,>=1.24.0
|
|
37
|
+
Requires-Dist: openpyxl<4.0.0,>=3.0.0
|
|
38
|
+
Requires-Dist: pandas<3.0.0,>=2.0.0
|
|
39
|
+
Requires-Dist: psutil<7.0.0,>=5.9.0
|
|
40
|
+
Requires-Dist: python-can<5.0.0,>=4.4.0
|
|
41
|
+
Requires-Dist: python-pptx<1.0.0,>=0.6.21
|
|
42
|
+
Requires-Dist: pyyaml<7.0.0,>=6.0
|
|
43
|
+
Requires-Dist: reportlab<6.0.0,>=4.4.7
|
|
44
|
+
Requires-Dist: scapy<3.0.0,>=2.5.0
|
|
45
|
+
Requires-Dist: scipy<2.0.0,>=1.10.0
|
|
46
|
+
Requires-Dist: tm-data-types<1.0.0,>=0.3.0
|
|
47
|
+
Requires-Dist: tqdm<5.0.0,>=4.65.0
|
|
48
|
+
Requires-Dist: weasyprint<64.0.0,>=63.0
|
|
49
|
+
Provides-Extra: all
|
|
50
|
+
Requires-Dist: asammdf<9.0.0,>=8.0.0; extra == 'all'
|
|
51
|
+
Requires-Dist: check-jsonschema<1.0.0,>=0.29.0; extra == 'all'
|
|
52
|
+
Requires-Dist: coverage[toml]<8.0.0,>=7.0; extra == 'all'
|
|
53
|
+
Requires-Dist: cryptography<47.0.0,>=44.0.1; extra == 'all'
|
|
54
|
+
Requires-Dist: h5py<4.0.0,>=3.0.0; extra == 'all'
|
|
55
|
+
Requires-Dist: hypothesis>=6.148.8; extra == 'all'
|
|
56
|
+
Requires-Dist: interrogate>=1.7.0; extra == 'all'
|
|
57
|
+
Requires-Dist: ipython<9.0.0,>=8.0.0; extra == 'all'
|
|
58
|
+
Requires-Dist: jupyter<2.0.0,>=1.0.0; extra == 'all'
|
|
59
|
+
Requires-Dist: mypy>=1.13.0; extra == 'all'
|
|
60
|
+
Requires-Dist: nbconvert!=7.16.6,<8.0.0,>=7.0.0; extra == 'all'
|
|
61
|
+
Requires-Dist: networkx<4.0.0,>=3.0; extra == 'all'
|
|
62
|
+
Requires-Dist: nptdms<2.0.0,>=1.7.0; extra == 'all'
|
|
63
|
+
Requires-Dist: pre-commit>=4.5.1; extra == 'all'
|
|
64
|
+
Requires-Dist: pyserial<4.0.0,>=3.5; extra == 'all'
|
|
65
|
+
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'all'
|
|
66
|
+
Requires-Dist: pytest-benchmark>=5.2.3; extra == 'all'
|
|
67
|
+
Requires-Dist: pytest-cov>=7.0.0; extra == 'all'
|
|
68
|
+
Requires-Dist: pytest-randomly<4.0.0,>=3.0; extra == 'all'
|
|
69
|
+
Requires-Dist: pytest-rerunfailures>=16.1; extra == 'all'
|
|
70
|
+
Requires-Dist: pytest-split>=0.2.0; extra == 'all'
|
|
71
|
+
Requires-Dist: pytest-timeout>=2.4.0; extra == 'all'
|
|
72
|
+
Requires-Dist: pytest-xdist>=3.8.0; extra == 'all'
|
|
73
|
+
Requires-Dist: pytest<10.0.0,>=8.0; extra == 'all'
|
|
74
|
+
Requires-Dist: pyvisa-py<1.0.0,>=0.7.0; extra == 'all'
|
|
75
|
+
Requires-Dist: pyvisa<2.0.0,>=1.13.0; extra == 'all'
|
|
76
|
+
Requires-Dist: pywavelets<2.0.0,>=1.0.0; extra == 'all'
|
|
77
|
+
Requires-Dist: rapidfuzz<4.0.0,>=3.0.0; extra == 'all'
|
|
78
|
+
Requires-Dist: rigolwfm<2.0.0,>=1.0.0; extra == 'all'
|
|
79
|
+
Requires-Dist: ruff>=0.14.0; extra == 'all'
|
|
80
|
+
Requires-Dist: scikit-learn<2.0.0,>=1.3.0; extra == 'all'
|
|
81
|
+
Requires-Dist: types-pyyaml<7.0.0,>=6.0; extra == 'all'
|
|
82
|
+
Requires-Dist: yamllint<2.0.0,>=1.35; extra == 'all'
|
|
83
|
+
Provides-Extra: analysis
|
|
84
|
+
Requires-Dist: networkx<4.0.0,>=3.0; extra == 'analysis'
|
|
85
|
+
Requires-Dist: pywavelets<2.0.0,>=1.0.0; extra == 'analysis'
|
|
86
|
+
Requires-Dist: scikit-learn<2.0.0,>=1.3.0; extra == 'analysis'
|
|
87
|
+
Provides-Extra: automotive
|
|
88
|
+
Requires-Dist: asammdf<9.0.0,>=8.0.0; extra == 'automotive'
|
|
89
|
+
Provides-Extra: dev
|
|
90
|
+
Requires-Dist: check-jsonschema<1.0.0,>=0.29.0; extra == 'dev'
|
|
91
|
+
Requires-Dist: coverage[toml]<8.0.0,>=7.0; extra == 'dev'
|
|
92
|
+
Requires-Dist: hypothesis>=6.148.8; extra == 'dev'
|
|
93
|
+
Requires-Dist: interrogate>=1.7.0; extra == 'dev'
|
|
94
|
+
Requires-Dist: mypy>=1.13.0; extra == 'dev'
|
|
95
|
+
Requires-Dist: pre-commit>=4.5.1; extra == 'dev'
|
|
96
|
+
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
|
|
97
|
+
Requires-Dist: pytest-benchmark>=5.2.3; extra == 'dev'
|
|
98
|
+
Requires-Dist: pytest-cov>=7.0.0; extra == 'dev'
|
|
99
|
+
Requires-Dist: pytest-randomly<4.0.0,>=3.0; extra == 'dev'
|
|
100
|
+
Requires-Dist: pytest-rerunfailures>=16.1; extra == 'dev'
|
|
101
|
+
Requires-Dist: pytest-split>=0.2.0; extra == 'dev'
|
|
102
|
+
Requires-Dist: pytest-timeout>=2.4.0; extra == 'dev'
|
|
103
|
+
Requires-Dist: pytest-xdist>=3.8.0; extra == 'dev'
|
|
104
|
+
Requires-Dist: pytest<10.0.0,>=8.0; extra == 'dev'
|
|
105
|
+
Requires-Dist: ruff>=0.14.0; extra == 'dev'
|
|
106
|
+
Requires-Dist: types-pyyaml<7.0.0,>=6.0; extra == 'dev'
|
|
107
|
+
Requires-Dist: yamllint<2.0.0,>=1.35; extra == 'dev'
|
|
108
|
+
Provides-Extra: fuzzy
|
|
109
|
+
Requires-Dist: rapidfuzz<4.0.0,>=3.0.0; extra == 'fuzzy'
|
|
110
|
+
Provides-Extra: hardware
|
|
111
|
+
Requires-Dist: pyserial<4.0.0,>=3.5; extra == 'hardware'
|
|
112
|
+
Requires-Dist: pyvisa-py<1.0.0,>=0.7.0; extra == 'hardware'
|
|
113
|
+
Requires-Dist: pyvisa<2.0.0,>=1.13.0; extra == 'hardware'
|
|
114
|
+
Provides-Extra: hdf5
|
|
115
|
+
Requires-Dist: h5py<4.0.0,>=3.0.0; extra == 'hdf5'
|
|
116
|
+
Provides-Extra: iot
|
|
117
|
+
Requires-Dist: cryptography<47.0.0,>=44.0.1; extra == 'iot'
|
|
118
|
+
Provides-Extra: jupyter
|
|
119
|
+
Requires-Dist: ipython<9.0.0,>=8.0.0; extra == 'jupyter'
|
|
120
|
+
Requires-Dist: jupyter<2.0.0,>=1.0.0; extra == 'jupyter'
|
|
121
|
+
Requires-Dist: nbconvert!=7.16.6,<8.0.0,>=7.0.0; extra == 'jupyter'
|
|
122
|
+
Provides-Extra: oscilloscopes
|
|
123
|
+
Requires-Dist: nptdms<2.0.0,>=1.7.0; extra == 'oscilloscopes'
|
|
124
|
+
Requires-Dist: rigolwfm<2.0.0,>=1.0.0; extra == 'oscilloscopes'
|
|
125
|
+
Provides-Extra: standard
|
|
126
|
+
Description-Content-Type: text/markdown
|
|
127
|
+
|
|
128
|
+
# Oscura
|
|
129
|
+
|
|
130
|
+
**Python framework for hardware reverse engineering: signal analysis, protocol decoding, and automated dissector generation.**
|
|
131
|
+
|
|
132
|
+
Unified workflows from oscilloscope captures to Wireshark dissectors. IEEE-compliant measurements, native protocol decoders, differential analysis, and CRC recovery—all in Python without tool juggling.
|
|
133
|
+
|
|
134
|
+
[](https://github.com/oscura-re/oscura/actions/workflows/ci.yml)
|
|
135
|
+
[](https://github.com/oscura-re/oscura/actions/workflows/code-quality.yml)
|
|
136
|
+
[](https://codecov.io/gh/oscura-re/oscura)
|
|
137
|
+
[](https://pypi.org/project/oscura/)
|
|
138
|
+
[](https://www.python.org/downloads/)
|
|
139
|
+
[](https://opensource.org/licenses/MIT)
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## What Oscura Provides
|
|
144
|
+
|
|
145
|
+
Unified Python framework for hardware reverse engineering workflows:
|
|
146
|
+
|
|
147
|
+
- **File Format Loading** - Oscilloscopes (Tektronix, Rigol), logic analyzers (Sigrok, VCD), network captures (PCAP), automotive (BLF), scientific instruments (HDF5, TDMS, Touchstone)
|
|
148
|
+
- **Protocol Decoding** - Serial (UART, SPI, I2C), automotive (CAN, LIN, FlexRay), debug (JTAG, SWD), industrial (Modbus, BACnet, EtherCAT, OPC UA, PROFINET), audio (I2S), wireless (BLE)
|
|
149
|
+
- **Signal Analysis** - Waveform measurements (IEEE 181), spectral analysis (IEEE 1241), jitter analysis (IEEE 2414), power analysis (IEEE 1459), eye diagrams, signal integrity
|
|
150
|
+
- **Protocol Inference** - CRC recovery, state machine extraction, field detection, format identification, magic byte discovery
|
|
151
|
+
- **Export Automation** - Wireshark dissectors, Scapy layers, DBC files, Kaitai Struct, 010 Editor templates, HTML/JSON reports
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## Installation
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
pip install oscura
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
For development setup or detailed installation options, see [Installation Guide](docs/getting-started/installation.md).
|
|
162
|
+
|
|
163
|
+
**Requirements**: Python 3.12+ | Dependencies: numpy, scipy, matplotlib, scikit-learn, cantools (all peer-reviewed, industry-standard libraries)
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## Usage Approaches
|
|
168
|
+
|
|
169
|
+
Oscura provides 5 usage patterns. **[→ Choose your approach](docs/getting-started/quick-start.md)**
|
|
170
|
+
|
|
171
|
+
Quick summary:
|
|
172
|
+
|
|
173
|
+
- **Comprehensive Script** - Immediate analysis ([showcase](demos/showcase/analyze_data_capture.py))
|
|
174
|
+
- **Convenience API** - Python applications ([examples](examples/))
|
|
175
|
+
- **Expert API** - Full control ([API docs](docs/api/))
|
|
176
|
+
- **YAML Pipeline** - Config-driven ([guide](docs/user-guide/integrations/yaml-pipelines.md))
|
|
177
|
+
- **CLI** - Command-line ([reference](docs/reference/cli.md))
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
## Example: Unknown Protocol Reverse Engineering
|
|
182
|
+
|
|
183
|
+
```python
|
|
184
|
+
from oscura.sessions import BlackBoxSession
|
|
185
|
+
|
|
186
|
+
# Differential analysis to identify protocol structure
|
|
187
|
+
session = BlackBoxSession(name="Unknown Device")
|
|
188
|
+
session.add_recording("idle", "idle.bin")
|
|
189
|
+
session.add_recording("active", "active.bin")
|
|
190
|
+
diff = session.compare("idle", "active")
|
|
191
|
+
|
|
192
|
+
# Generate Wireshark dissector from inferred structure
|
|
193
|
+
session.export_results("dissector", "protocol.lua")
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## Capabilities Reference
|
|
199
|
+
|
|
200
|
+
### File Format Support
|
|
201
|
+
|
|
202
|
+
Unified loader with automatic format detection via `oscura.load(path)`:
|
|
203
|
+
|
|
204
|
+
- **Oscilloscopes**: Tektronix WFM/TSS, Rigol WFM
|
|
205
|
+
- **Logic Analyzers**: VCD, Sigrok .sr
|
|
206
|
+
- **Network**: PCAP/PCAPNG
|
|
207
|
+
- **Scientific**: HDF5, TDMS, Touchstone S-parameters
|
|
208
|
+
- **Generic**: WAV, CSV, NumPy, binary dumps
|
|
209
|
+
- **Side-Channel**: ChipWhisperer traces
|
|
210
|
+
|
|
211
|
+
### Waveform Measurements (IEEE 181-2011)
|
|
212
|
+
|
|
213
|
+
Timing, amplitude, and quality measurements with sub-sample interpolation:
|
|
214
|
+
|
|
215
|
+
- **Timing**: rise/fall time, period, frequency, pulse width, duty cycle, phase, delay, slew rate
|
|
216
|
+
- **Amplitude**: peak-to-peak, RMS, mean, overshoot, undershoot, top, base
|
|
217
|
+
- **Advanced**: area, burst width, extinction ratio, quality factor
|
|
218
|
+
|
|
219
|
+
### Spectral Analysis (IEEE 1241-2010)
|
|
220
|
+
|
|
221
|
+
FFT, PSD, quality metrics:
|
|
222
|
+
|
|
223
|
+
- **Frequency Domain**: FFT, PSD (Welch method), spectrogram, coherence
|
|
224
|
+
- **Quality Metrics**: THD, SNR, SINAD, SFDR, ENOB
|
|
225
|
+
- **Advanced**: Cepstrum, bispectrum, cross-spectrum, transfer function
|
|
226
|
+
|
|
227
|
+
### Digital Signal Analysis
|
|
228
|
+
|
|
229
|
+
- **Conversion**: Threshold detection with hysteresis, edge detection, clock extraction
|
|
230
|
+
- **Timing**: Clock/baud rate detection, pulse width measurement, frame sync
|
|
231
|
+
- **Logic Levels**: TTL, CMOS, LVCMOS, LVDS, ECL detection
|
|
232
|
+
- **Quality**: Glitch detection, timing violations, signal quality metrics
|
|
233
|
+
|
|
234
|
+
### Eye Diagram Analysis
|
|
235
|
+
|
|
236
|
+
Eye diagram generation and measurements: height, width, area, crossing percentage, Q-factor, BER estimation, mask testing.
|
|
237
|
+
|
|
238
|
+
### Jitter Analysis (IEEE 2414-2020)
|
|
239
|
+
|
|
240
|
+
RJ/DJ decomposition using dual-Dirac model:
|
|
241
|
+
|
|
242
|
+
- **Components**: Random jitter (RJ), deterministic jitter (DJ), periodic jitter (PJ), data-dependent jitter (DDJ)
|
|
243
|
+
- **Measurements**: TIE, period jitter, cycle-to-cycle jitter
|
|
244
|
+
- **Visualization**: Bathtub curves for BER extrapolation
|
|
245
|
+
|
|
246
|
+
### Power Analysis (IEEE 1459-2010)
|
|
247
|
+
|
|
248
|
+
- **Basic**: Instantaneous, average, peak, RMS power, energy
|
|
249
|
+
- **AC Power**: Active, reactive, apparent power, power factor
|
|
250
|
+
- **Harmonics**: THD, harmonic content, crest factor
|
|
251
|
+
- **Quality**: Ripple, sag/swell detection, flicker, unbalance
|
|
252
|
+
|
|
253
|
+
### Statistical Analysis
|
|
254
|
+
|
|
255
|
+
- **Descriptive**: Mean, median, std dev, quartiles, percentiles
|
|
256
|
+
- **Distribution**: Histograms, skewness, kurtosis, normality tests
|
|
257
|
+
- **Outliers**: Z-score, IQR, MAD, isolation forest, DBSCAN
|
|
258
|
+
- **Correlation**: Auto/cross-correlation, Pearson, Spearman
|
|
259
|
+
- **Time Series**: Periodicity detection, trend analysis, change points
|
|
260
|
+
|
|
261
|
+
### Pattern Recognition
|
|
262
|
+
|
|
263
|
+
- **Period Detection**: FFT-based, autocorrelation, multi-method
|
|
264
|
+
- **Sequences**: Repeating patterns, n-grams, Lempel-Ziv complexity
|
|
265
|
+
- **Entropy**: Shannon entropy, byte frequency, encrypted/compressed region detection
|
|
266
|
+
- **Structure**: Magic bytes, headers, delimiters, sync patterns, alignment
|
|
267
|
+
|
|
268
|
+
### Protocol Decoders
|
|
269
|
+
|
|
270
|
+
Native state machine implementations:
|
|
271
|
+
|
|
272
|
+
- **Serial**: UART, SPI, I2C, 1-Wire
|
|
273
|
+
- **Automotive**: CAN, CAN-FD, LIN, FlexRay
|
|
274
|
+
- **Debug**: JTAG (IEEE 1149.1), SWD (ARM CoreSight)
|
|
275
|
+
- **Industrial**: Modbus, BACnet, EtherCAT, OPC UA, PROFINET, HDLC
|
|
276
|
+
- **Audio**: I2S
|
|
277
|
+
- **Wireless**: BLE advertising packets
|
|
278
|
+
- **Parallel**: Centronics, GPIB (IEEE 488.2)
|
|
279
|
+
|
|
280
|
+
### Protocol Inference
|
|
281
|
+
|
|
282
|
+
- **CRC Recovery**: Brute-force parameter search, algorithm detection
|
|
283
|
+
- **Field Detection**: Statistical boundary inference, type classification
|
|
284
|
+
- **Format Analysis**: Magic bytes, framing, escaping detection
|
|
285
|
+
- **Protocol Detection**: Multi-heuristic with confidence scoring
|
|
286
|
+
- **State Machines**: RPNI algorithm for state extraction
|
|
287
|
+
- **Dissector Generation**: Wireshark (Lua), Scapy (Python), Kaitai Struct, 010 Editor
|
|
288
|
+
|
|
289
|
+
### Automotive Analysis
|
|
290
|
+
|
|
291
|
+
- **CAN**: Frame decoding, ID identification, statistical analysis, differential analysis
|
|
292
|
+
- **DBC Generation**: Signal inference, automatic naming, scaling detection
|
|
293
|
+
- **Diagnostics**: OBD-II, UDS, J1939, DTC lookup
|
|
294
|
+
- **Security**: Replay detection, fuzzing, anomaly detection
|
|
295
|
+
|
|
296
|
+
### Signal Integrity
|
|
297
|
+
|
|
298
|
+
TDR analysis, S-parameters (Touchstone), insertion/return loss, VSWR, impedance calculation, crosstalk detection.
|
|
299
|
+
|
|
300
|
+
### Machine Learning
|
|
301
|
+
|
|
302
|
+
- **Classification**: Signal type, protocol identification, modulation detection (Random Forest/SVM)
|
|
303
|
+
- **Feature Extraction**: Timing, spectral, statistical features
|
|
304
|
+
- **Clustering**: K-means, DBSCAN, hierarchical
|
|
305
|
+
- **Anomaly Detection**: Isolation Forest, One-Class SVM
|
|
306
|
+
|
|
307
|
+
### Visualization
|
|
308
|
+
|
|
309
|
+
Waveforms, FFT/PSD spectra, spectrograms, histograms, logic analyzer views, eye diagrams, bathtub curves, constellation diagrams, Smith charts, Bode/Nyquist plots, protocol timelines.
|
|
310
|
+
|
|
311
|
+
### Export Formats
|
|
312
|
+
|
|
313
|
+
JSON, CSV, HTML reports, Wireshark dissectors (Lua), Scapy dissectors (Python), Kaitai Struct (YAML), DBC (CAN database), 010 Editor templates, WAV, VCD, NumPy, HDF5, MATLAB.
|
|
314
|
+
|
|
315
|
+
---
|
|
316
|
+
|
|
317
|
+
## When to Use Oscura
|
|
318
|
+
|
|
319
|
+
**Best suited for:**
|
|
320
|
+
|
|
321
|
+
- End-to-end Python workflows (capture → analysis → documentation)
|
|
322
|
+
- Unknown protocol reverse engineering with differential analysis
|
|
323
|
+
- DBC generation from CAN captures (open-source CANalyzer alternative)
|
|
324
|
+
- Automatic Wireshark dissector generation from inferred protocols
|
|
325
|
+
- Unified API across 14 oscilloscope/logic analyzer formats
|
|
326
|
+
- Reproducible research with hypothesis tracking
|
|
327
|
+
- Scripted multi-tool RE pipelines
|
|
328
|
+
|
|
329
|
+
**Oscura's strength:** Workflow automation combining multiple RE steps with hypothesis-driven analysis.
|
|
330
|
+
|
|
331
|
+
---
|
|
332
|
+
|
|
333
|
+
## Standards Compliance
|
|
334
|
+
|
|
335
|
+
Oscura implements measurements per IEEE specifications.
|
|
336
|
+
|
|
337
|
+
| Standard | Coverage | Implementation |
|
|
338
|
+
|----------|----------|----------------|
|
|
339
|
+
| IEEE 181-2011 | Pulse timing, rise/fall, overshoot, duty cycle | Native algorithms |
|
|
340
|
+
| IEEE 1241-2010 | SNR, SINAD, THD, SFDR, ENOB | Native + scipy.signal |
|
|
341
|
+
| IEEE 1459-2010 | Active/reactive power, harmonics, power factor | Native + scipy.signal |
|
|
342
|
+
| IEEE 2414-2020 | TIE, RJ/DJ decomposition, bathtub curves | Native + scipy.stats |
|
|
343
|
+
|
|
344
|
+
**Validation**: 475 test files with 80%+ code coverage, property-based testing via Hypothesis.
|
|
345
|
+
|
|
346
|
+
---
|
|
347
|
+
|
|
348
|
+
## Quality Metrics
|
|
349
|
+
|
|
350
|
+
**Testing**: 475 test files, 80%+ coverage with branch coverage, property-based testing (Hypothesis), nightly stress tests
|
|
351
|
+
|
|
352
|
+
**CI/CD**: Pre-commit hooks (format, lint, type check), merge queue validation, security scanning (Bandit, Safety)
|
|
353
|
+
|
|
354
|
+
**Type Safety**: MyPy strict mode, comprehensive type hints
|
|
355
|
+
|
|
356
|
+
**Documentation**: Google-style docstrings, 95% documentation coverage
|
|
357
|
+
|
|
358
|
+
View metrics: [CI Dashboard](https://github.com/oscura-re/oscura/actions) | [Coverage](https://codecov.io/gh/oscura-re/oscura)
|
|
359
|
+
|
|
360
|
+
---
|
|
361
|
+
|
|
362
|
+
## Demonstrations
|
|
363
|
+
|
|
364
|
+
**Comprehensive working demonstrations** covering all framework capabilities. See [demos/README.md](demos/README.md) for complete catalog.
|
|
365
|
+
|
|
366
|
+
**Categories**: Waveform Analysis, File I/O, Custom DAQ, Serial Protocols, Protocol Decoding, UDP Analysis, Protocol Inference, Automotive, Timing, Mixed Signal, Spectral, Jitter, Power, Signal Integrity, EMC, Signal RE, Advanced Inference, Complete Workflows
|
|
367
|
+
|
|
368
|
+
**Learning Paths**:
|
|
369
|
+
|
|
370
|
+
- Beginner (2-4 hours): File loading, basic measurements, export
|
|
371
|
+
- Intermediate (6-10 hours): Protocol decoding (UART, SPI, I2C, PCAP)
|
|
372
|
+
- Advanced (12-20 hours): CRC recovery, state machines, Wireshark dissectors
|
|
373
|
+
- Expert (20-40 hours): Complete RE workflows with ML inference
|
|
374
|
+
|
|
375
|
+
```bash
|
|
376
|
+
./scripts/setup.sh
|
|
377
|
+
python demos/00_getting_started/00_hello_world.py
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
---
|
|
381
|
+
|
|
382
|
+
## Documentation
|
|
383
|
+
|
|
384
|
+
**User Guides**:
|
|
385
|
+
|
|
386
|
+
- [Quick Start](docs/getting-started/quick-start.md) - Installation and first steps
|
|
387
|
+
- [Black-Box Analysis](docs/user-guide/workflows/blackbox-analysis.md) - Unknown protocol RE
|
|
388
|
+
- [Side-Channel Analysis](docs/user-guide/workflows/side-channel-analysis.md) - ChipWhisperer integration
|
|
389
|
+
- [Hardware Acquisition](docs/user-guide/workflows/hardware-acquisition.md) - Instrument control
|
|
390
|
+
- [Complete Workflows](docs/user-guide/workflows.md) - End-to-end pipelines
|
|
391
|
+
|
|
392
|
+
**API Reference**: [docs/api/](docs/api/) - Complete function reference
|
|
393
|
+
|
|
394
|
+
**Development**: [Architecture](docs/developer-guide/architecture.md) | [Testing](docs/testing/) | [CHANGELOG](CHANGELOG.md)
|
|
395
|
+
|
|
396
|
+
---
|
|
397
|
+
|
|
398
|
+
## Contributing
|
|
399
|
+
|
|
400
|
+
```bash
|
|
401
|
+
git clone https://github.com/oscura-re/oscura.git
|
|
402
|
+
cd oscura
|
|
403
|
+
./scripts/setup.sh # Setup with hooks
|
|
404
|
+
./scripts/check.sh # Quality checks
|
|
405
|
+
./scripts/test.sh # Test suite
|
|
406
|
+
python3 .claude/hooks/validate_all.py # Must pass 5/5
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
**Needed Contributions**:
|
|
410
|
+
|
|
411
|
+
- Workflow automation (new pipelines, export formats, integrations)
|
|
412
|
+
- File format loaders (oscilloscope/LA formats not yet supported)
|
|
413
|
+
- Inference algorithms (better state machine learning, field detection)
|
|
414
|
+
- Protocol decoders (proprietary protocols you've reversed)
|
|
415
|
+
- Hardware integration (DAQ systems, instrument drivers)
|
|
416
|
+
- Real-world validation (test on your captures, report issues)
|
|
417
|
+
|
|
418
|
+
[Contributing Guide](CONTRIBUTING.md) | [Architecture](docs/developer-guide/architecture.md)
|
|
419
|
+
|
|
420
|
+
---
|
|
421
|
+
|
|
422
|
+
## Project Status
|
|
423
|
+
|
|
424
|
+
**Version**: [0.10.0](https://github.com/oscura-re/oscura/releases/latest) (2026-02-03)
|
|
425
|
+
|
|
426
|
+
**Active Development**: Hypothesis-driven RE workflows, automotive protocol analysis (CAN-FD, J1939, OBD-II, UDS), unknown protocol inference (state machines, field detection, CRC recovery), multi-format loading, export automation
|
|
427
|
+
|
|
428
|
+
**Stability**: Production-ready for security research, right-to-repair, academic use. API evolution documented in [CHANGELOG](CHANGELOG.md).
|
|
429
|
+
|
|
430
|
+
[Release History](https://github.com/oscura-re/oscura/releases) | [Roadmap](https://github.com/oscura-re/oscura/discussions)
|
|
431
|
+
|
|
432
|
+
---
|
|
433
|
+
|
|
434
|
+
## Legal
|
|
435
|
+
|
|
436
|
+
**License**: [MIT License](LICENSE) - Permissive use, modification, distribution
|
|
437
|
+
|
|
438
|
+
**Disclaimer**: Intended for legitimate security research, right-to-repair, academic study, and authorized testing. Users responsible for compliance with applicable laws. Unauthorized access is illegal and unethical.
|
|
439
|
+
|
|
440
|
+
**Dependencies**: Python, NumPy, SciPy, Matplotlib, scikit-learn, cantools, Hypothesis. See [pyproject.toml](pyproject.toml).
|
|
441
|
+
|
|
442
|
+
---
|
|
443
|
+
|
|
444
|
+
## Citation
|
|
445
|
+
|
|
446
|
+
```bibtex
|
|
447
|
+
@software{oscura2026,
|
|
448
|
+
title = {Oscura: Hardware Reverse Engineering Framework},
|
|
449
|
+
author = {Oscura Contributors},
|
|
450
|
+
year = {2026},
|
|
451
|
+
url = {https://github.com/oscura-re/oscura},
|
|
452
|
+
version = {0.10.0}
|
|
453
|
+
}
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
Machine-readable: [CITATION.cff](CITATION.cff)
|
|
457
|
+
|
|
458
|
+
---
|
|
459
|
+
|
|
460
|
+
**Oscura** - Hardware reverse engineering framework providing unified workflows from signal capture to protocol specification. Built for security research, right-to-repair, academic study, and defense applications.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
oscura/__init__.py,sha256=
|
|
2
|
-
oscura/__main__.py,sha256=
|
|
1
|
+
oscura/__init__.py,sha256=DwhB48tFYd9xipcGCvkakl1Kskrj817d2wOnTYtIqXI,19119
|
|
2
|
+
oscura/__main__.py,sha256=6qveGY8VHAHbxcrvxg8V4qxDCH0w0p1AMejDVHzVc88,11998
|
|
3
3
|
oscura/convenience.py,sha256=YQgUr8zf386pQaOjXfNYhVL2NVUydRDVLoJizQW5_SU,29293
|
|
4
4
|
oscura/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
5
|
oscura/analyzers/__init__.py,sha256=gUqULZptAUglrkRaVzf69uvaTD88p67VJVP5LxLJozs,1124
|
|
@@ -32,7 +32,7 @@ oscura/analyzers/jitter/spectrum.py,sha256=pzsH0ekM97rligOUOHlsp-8Hn1VZnQpd-a8Ee
|
|
|
32
32
|
oscura/analyzers/jitter/timing.py,sha256=_-YhTAwKHDnzwL-MFXiqNZrH5y2TxDyIsbayMkuC64o,12627
|
|
33
33
|
oscura/analyzers/ml/__init__.py,sha256=77br1uGiIDnQJQngwfKPDep3OVGhoA_Pj3vIp_dnoUA,1356
|
|
34
34
|
oscura/analyzers/ml/features.py,sha256=xroEW2wqVWsZb2j2dnEQXlyubyHCKxY73WgjNOFrsms,21767
|
|
35
|
-
oscura/analyzers/ml/signal_classifier.py,sha256=
|
|
35
|
+
oscura/analyzers/ml/signal_classifier.py,sha256=MfJafwgOq2Rb_l9kVCYyWXfcDuBJx93VuieXMHZaBBw,22702
|
|
36
36
|
oscura/analyzers/packet/__init__.py,sha256=HNhAvW_T-P6OXlgCid01Jq8qfhgFtvABw-Tn7XLFoNU,3937
|
|
37
37
|
oscura/analyzers/packet/daq.py,sha256=-EXXEp5cUHhuBDN3W8-w0hvUKBULfHMW5Lf3FDFgIno,36290
|
|
38
38
|
oscura/analyzers/packet/metrics.py,sha256=MyCeg4YX0Z6illSs_o7LleFksjVD3OLb7eh5wAzhVjs,11456
|
|
@@ -136,7 +136,7 @@ oscura/analyzers/statistics/trend.py,sha256=Tu0gUZqy4PJ7Ne7YzRuJGU80DUl71Onc3QXs
|
|
|
136
136
|
oscura/analyzers/waveform/__init__.py,sha256=SqLMhTFy4-Krx0b3hTZbhd1NKPeNe767Q6yaTz1wo1c,614
|
|
137
137
|
oscura/analyzers/waveform/measurements.py,sha256=mqtMDqsfy_NAbrR9k0hPUsjsbABpkr3tw8sk0jaEFgM,35969
|
|
138
138
|
oscura/analyzers/waveform/measurements_with_uncertainty.py,sha256=lrHMLCzMyAn0MQeinXWFytFRULYa71upnz9ppI3e1C4,15108
|
|
139
|
-
oscura/analyzers/waveform/spectral.py,sha256=
|
|
139
|
+
oscura/analyzers/waveform/spectral.py,sha256=Vm-0BBHxFVWwCS7esVJx4UcWiQrbI-EIhh2EmcSnDg4,72788
|
|
140
140
|
oscura/analyzers/waveform/wavelets.py,sha256=rKoqiKmuLQ9iKMFshJam7wdn6fL6sFcJY_-J0fYl5F4,10116
|
|
141
141
|
oscura/api/__init__.py,sha256=7URqzrBUiIq54TSUUi291VhBiZ-ZL5cS4m5eM0WppGk,1808
|
|
142
142
|
oscura/api/dsl.py,sha256=_azJ2AnbN5EDhgH6RiZmHEDJxu5lzMbZpDhhsmaX7Zs,14880
|
|
@@ -163,7 +163,7 @@ oscura/api/server/templates/reports.html,sha256=LPdGkX-gXlg10FqNckB4WnY5eix0Tibh
|
|
|
163
163
|
oscura/api/server/templates/session_detail.html,sha256=_NpjSi63fPulhWAJc2qhvN6cll3J3_TQ1mOp_ejf7Ns,2850
|
|
164
164
|
oscura/api/server/templates/sessions.html,sha256=aAARmctGTaU7f-mtCpy-p13GRdTvR4jqTZ5MPIgbhG4,2346
|
|
165
165
|
oscura/api/server/templates/waveforms.html,sha256=vxG9sPxcspsyV0ylpXf_8FzpTYDazPQcempY9iGljQ0,1977
|
|
166
|
-
oscura/automotive/__init__.py,sha256=
|
|
166
|
+
oscura/automotive/__init__.py,sha256=VCrOyBrV1S6fhgyEZY7GqZRbv6Yf8J2h_FV5gPEHdsI,2768
|
|
167
167
|
oscura/automotive/visualization.py,sha256=LD6Gia3kDqoB_jQkOeVmyRVLv1BPuTUVj6lJMVtbQWg,10664
|
|
168
168
|
oscura/automotive/can/__init__.py,sha256=ZYxC8tMMi9Drm9adkH5yklypBTfIbf3D7BYA2SUp9fE,1491
|
|
169
169
|
oscura/automotive/can/analysis.py,sha256=0z6MycxuJGusqDQhYEpHnGRmDw3OMf5yDbS8zI6GJO0,11251
|
|
@@ -181,12 +181,12 @@ oscura/automotive/dbc/__init__.py,sha256=HZlM2WAaaglpX4C9tJVkF7uZiaHW4iUPQAbhfJY
|
|
|
181
181
|
oscura/automotive/dbc/generator.py,sha256=ayhwTwMjZlzh70fihVSTRFmDWEuGDZgwUYArWFG6TcM,29823
|
|
182
182
|
oscura/automotive/dbc/parser.py,sha256=C5SL1bfJFZp0CYsw-ff8ysJ_57Us9dBoHZ1t6LVLGbo,4421
|
|
183
183
|
oscura/automotive/dtc/__init__.py,sha256=09CgvnClJTQIvzgDOQ22CbcjGAg_zOhPlbm1-k-gl30,895
|
|
184
|
-
oscura/automotive/dtc/data.json,sha256=
|
|
184
|
+
oscura/automotive/dtc/data.json,sha256=5pddTolfBJjwimwp5epiMjUqSngZ1dur9LQlcHfdjrA,79331
|
|
185
185
|
oscura/automotive/dtc/database.py,sha256=Ee1Jd4CbP5T4LON0Y2PdOkgdISHa8jf8c6znb0S_L00,9582
|
|
186
186
|
oscura/automotive/flexray/__init__.py,sha256=2RuW8TR4M3tSDEfcj-pJQpGGSxGaw5GdyGSvjMnU8Lk,938
|
|
187
187
|
oscura/automotive/flexray/analyzer.py,sha256=UG3e9tJSHGV7aR3WKwfVCrNDSVlT7ZgFm7vgCcw0qOo,16727
|
|
188
188
|
oscura/automotive/flexray/crc.py,sha256=_tESIhGZFL-yL67loyS2oE2DGwRlWC0VRrT5ZU871C4,5230
|
|
189
|
-
oscura/automotive/flexray/fibex.py,sha256=
|
|
189
|
+
oscura/automotive/flexray/fibex.py,sha256=qZ5ZVwQIXvz-5JpJTH2nBJdQdND_ebIZiZR5ig4rsac,15430
|
|
190
190
|
oscura/automotive/j1939/__init__.py,sha256=FhUfn6zkGXZtWRMAuVJh1EU9JnKRivzPm7Kh9edJBII,1348
|
|
191
191
|
oscura/automotive/j1939/analyzer.py,sha256=WnJnGL4oSggwp39YO_wX6qoDTelVFg1g9iWWDzt4HU0,19519
|
|
192
192
|
oscura/automotive/j1939/decoder.py,sha256=qSfok5RTuwc4vR5sjnEdTOi06TwaNfIhBtZq6Vpzhik,25115
|
|
@@ -290,9 +290,9 @@ oscura/core/plugins/registry.py,sha256=XNtq0rBuppC1Z5V5RH74afW-LBnWSLc33lCE6BDZK
|
|
|
290
290
|
oscura/core/plugins/versioning.py,sha256=d18sXMbgeWy_dVNaM7JWvCVIF6VgpnjIbjP8gdFfgSs,10785
|
|
291
291
|
oscura/core/schemas/__init__.py,sha256=W33kQp0A8v9qZevqjm3T-1Fjrnou5cz0WCAbLRkwbgY,4327
|
|
292
292
|
oscura/core/schemas/bus_configuration.json,sha256=gpcDsg04760KCaLeIDuWvP6RzRUcPZuQplJbe7xpc8E,9562
|
|
293
|
-
oscura/core/schemas/device_mapping.json,sha256=
|
|
294
|
-
oscura/core/schemas/packet_format.json,sha256=
|
|
295
|
-
oscura/core/schemas/protocol_definition.json,sha256=
|
|
293
|
+
oscura/core/schemas/device_mapping.json,sha256=I87-MWnXldVWIXRC1H-WgzNLszymRdnaxwE3B1z8qys,5415
|
|
294
|
+
oscura/core/schemas/packet_format.json,sha256=NVa4RtwSye9QgD1pBi67nuCDRsVljudCpBBGjmZsMqk,12567
|
|
295
|
+
oscura/core/schemas/protocol_definition.json,sha256=lThVXTWzh7GxN-XNb3h8Bh20l1NZUigivWBb04xvogs,11116
|
|
296
296
|
oscura/correlation/__init__.py,sha256=4H5lCJqBBG3_10oIPsdIOyCij8FlKtMxLp3SAYvSsRg,1537
|
|
297
297
|
oscura/correlation/multi_protocol.py,sha256=Lce9AF2iqenpGRMYpSJ_LbXBA7nVK5mLbDEwHhbVldg,28260
|
|
298
298
|
oscura/discovery/__init__.py,sha256=ytYa_s4PfKxRRopOdUGsmzUIDPevH25ze_VytBEX2Cw,1232
|
|
@@ -405,7 +405,7 @@ oscura/loaders/tdms.py,sha256=CH4g9ZEgLjJ556Mt2SYlo9LJ11hbxbgqd-VRYB1aSXQ,11141
|
|
|
405
405
|
oscura/loaders/tektronix.py,sha256=fk1QopvToHXFsrFOD3pSb88PIAj0E1kK2QgxOpxelCw,26350
|
|
406
406
|
oscura/loaders/touchstone.py,sha256=Cj4KlQQMcSEZuf5M0hg3lFvXvnuPZkcLa8-X-qKEObA,8898
|
|
407
407
|
oscura/loaders/tss.py,sha256=Gd27lHk2GWn8Mm-aZqNDEPrf_uNN2NXnrfiq-rdpoaY,13433
|
|
408
|
-
oscura/loaders/validation.py,sha256=
|
|
408
|
+
oscura/loaders/validation.py,sha256=c-976d9u1Nf-PweiQ44oT_Z7EKdfcOUnD8OTBn2wVtY,18342
|
|
409
409
|
oscura/loaders/vcd.py,sha256=eiW9rV7wal1drm1n0BtPuriae_L1NQimgOh3BmWDTUc,17911
|
|
410
410
|
oscura/loaders/wav.py,sha256=rPuf7e9e9v3wL2l4_Qim9yo2INcFVpkKm5rcT4QcQzM,9202
|
|
411
411
|
oscura/pipeline/__init__.py,sha256=S0R19AhuJOBvtCnGUiW_qnMyAwDUo6bd32kWGekp2xw,1871
|
|
@@ -470,7 +470,7 @@ oscura/sessions/__init__.py,sha256=gJMEZezGxt0KniCQNFinp65B9HwDDfmXkYiq3n4wWYk,2
|
|
|
470
470
|
oscura/sessions/base.py,sha256=JjMO-QybHS55OqFZ4jZC1DTVehTKrxOgMPlSA5bwlkk,10847
|
|
471
471
|
oscura/sessions/blackbox.py,sha256=nk1ZKapxwDSIHmweD9x7kSbiMOOLVdMqVN-lavRhYYI,26039
|
|
472
472
|
oscura/sessions/generic.py,sha256=roecnb2ftlzyOyKioaB4N0klUJKfRsbPN1WyWO-YEws,6660
|
|
473
|
-
oscura/sessions/legacy.py,sha256
|
|
473
|
+
oscura/sessions/legacy.py,sha256=RYerJGiO-Wov62phQhhtMHXJcV9bGeWxHI_PQGXKT6E,25631
|
|
474
474
|
oscura/side_channel/__init__.py,sha256=3-vgWWiaabnfZL6tXvzRtvXoUw4Gmquue0oFZ10amrU,1141
|
|
475
475
|
oscura/utils/__init__.py,sha256=VGd2Hzqy1j47UtheI73Hc8GOPwIAi2SWX34CbOxhk1A,2771
|
|
476
476
|
oscura/utils/autodetect.py,sha256=cP-_be6XK9neO28J2le1iZ8YLvPmfpc8L-p6KAlA6h8,9324
|
|
@@ -564,14 +564,14 @@ oscura/workflows/signal_integrity.py,sha256=TQ5CWnS2iyzS5TU32TfLzNilQT2fhY8EPy3E
|
|
|
564
564
|
oscura/workflows/waveform.py,sha256=DJS6aA4bymIKmCOdZB6FUTf3dPWKmFgVjsTlcIRBJsY,31596
|
|
565
565
|
oscura/workflows/batch/__init__.py,sha256=ngm5GSV8cC-T0nfigyQVkRkqJM5dpaxMTH6s3NZN67c,1260
|
|
566
566
|
oscura/workflows/batch/advanced.py,sha256=dGLQN4DUNLoAS2JBFebleW9Qe3s6s492JhuNucWiJyk,23628
|
|
567
|
-
oscura/workflows/batch/aggregate.py,sha256=
|
|
567
|
+
oscura/workflows/batch/aggregate.py,sha256=gDnf0aMk8ZVfVRvAOA6qIMfZCPgfU5rPTX-c9aukc4k,15916
|
|
568
568
|
oscura/workflows/batch/analyze.py,sha256=pMXUChVGpSj7L0dNgPTN6R2-XdxHQteQLNJkEEJnXv4,7536
|
|
569
569
|
oscura/workflows/batch/logging.py,sha256=6YkTrOA2OSiRjYHmtRn-lL2wyNpya0sggVkgxszo4qw,15485
|
|
570
570
|
oscura/workflows/batch/metrics.py,sha256=InbxaZmFQrANpp_RCcx5F3va55UaiQjhFJ-_SEKAS20,17322
|
|
571
571
|
oscura/workflows/legacy/__init__.py,sha256=PqHw8AIWfP4-1lJEjCDC4c_O8GXYOcWodK9ciOnGJaU,409
|
|
572
572
|
oscura/workflows/legacy/dag.py,sha256=tEhiWmOSdcEYKmrwYUETC0P5yN-_Cy9fEysPwTDVZ3A,12337
|
|
573
|
-
oscura-0.
|
|
574
|
-
oscura-0.
|
|
575
|
-
oscura-0.
|
|
576
|
-
oscura-0.
|
|
577
|
-
oscura-0.
|
|
573
|
+
oscura-0.11.0.dist-info/METADATA,sha256=YWJqgPrd73hr127e_dy1ip7sYIR0A7nF7Ab6PRcojqE,20170
|
|
574
|
+
oscura-0.11.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
575
|
+
oscura-0.11.0.dist-info/entry_points.txt,sha256=QLBxd-iTjBQ5HidaVSkLBwvUsqxSG1ZTJ6i-0juu960,48
|
|
576
|
+
oscura-0.11.0.dist-info/licenses/LICENSE,sha256=p1_oEK-oqWDXMFSv5mKbyYkgW-CPbCnFUvdICu490aY,1077
|
|
577
|
+
oscura-0.11.0.dist-info/RECORD,,
|