oscura 0.5.0__py3-none-any.whl → 0.6.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 +169 -167
- oscura/analyzers/__init__.py +3 -0
- oscura/analyzers/classification.py +659 -0
- oscura/analyzers/digital/__init__.py +0 -48
- oscura/analyzers/digital/edges.py +325 -65
- oscura/analyzers/digital/extraction.py +0 -195
- oscura/analyzers/digital/quality.py +293 -166
- oscura/analyzers/digital/timing.py +260 -115
- oscura/analyzers/digital/timing_numba.py +334 -0
- oscura/analyzers/entropy.py +605 -0
- oscura/analyzers/eye/diagram.py +176 -109
- oscura/analyzers/eye/metrics.py +5 -5
- oscura/analyzers/jitter/__init__.py +6 -4
- oscura/analyzers/jitter/ber.py +52 -52
- oscura/analyzers/jitter/classification.py +156 -0
- oscura/analyzers/jitter/decomposition.py +163 -113
- oscura/analyzers/jitter/spectrum.py +80 -64
- oscura/analyzers/ml/__init__.py +39 -0
- oscura/analyzers/ml/features.py +600 -0
- oscura/analyzers/ml/signal_classifier.py +604 -0
- oscura/analyzers/packet/daq.py +246 -158
- oscura/analyzers/packet/parser.py +12 -1
- oscura/analyzers/packet/payload.py +50 -2110
- oscura/analyzers/packet/payload_analysis.py +361 -181
- oscura/analyzers/packet/payload_patterns.py +133 -70
- oscura/analyzers/packet/stream.py +84 -23
- oscura/analyzers/patterns/__init__.py +26 -5
- oscura/analyzers/patterns/anomaly_detection.py +908 -0
- oscura/analyzers/patterns/clustering.py +169 -108
- oscura/analyzers/patterns/clustering_optimized.py +227 -0
- oscura/analyzers/patterns/discovery.py +1 -1
- oscura/analyzers/patterns/matching.py +581 -197
- oscura/analyzers/patterns/pattern_mining.py +778 -0
- oscura/analyzers/patterns/periodic.py +121 -38
- oscura/analyzers/patterns/sequences.py +175 -78
- oscura/analyzers/power/conduction.py +1 -1
- oscura/analyzers/power/soa.py +6 -6
- oscura/analyzers/power/switching.py +250 -110
- oscura/analyzers/protocol/__init__.py +17 -1
- oscura/analyzers/protocols/__init__.py +1 -22
- oscura/analyzers/protocols/base.py +6 -6
- oscura/analyzers/protocols/ble/__init__.py +38 -0
- oscura/analyzers/protocols/ble/analyzer.py +809 -0
- oscura/analyzers/protocols/ble/uuids.py +288 -0
- oscura/analyzers/protocols/can.py +257 -127
- oscura/analyzers/protocols/can_fd.py +107 -80
- oscura/analyzers/protocols/flexray.py +139 -80
- oscura/analyzers/protocols/hdlc.py +93 -58
- oscura/analyzers/protocols/i2c.py +247 -106
- oscura/analyzers/protocols/i2s.py +138 -86
- oscura/analyzers/protocols/industrial/__init__.py +40 -0
- oscura/analyzers/protocols/industrial/bacnet/__init__.py +33 -0
- oscura/analyzers/protocols/industrial/bacnet/analyzer.py +708 -0
- oscura/analyzers/protocols/industrial/bacnet/encoding.py +412 -0
- oscura/analyzers/protocols/industrial/bacnet/services.py +622 -0
- oscura/analyzers/protocols/industrial/ethercat/__init__.py +30 -0
- oscura/analyzers/protocols/industrial/ethercat/analyzer.py +474 -0
- oscura/analyzers/protocols/industrial/ethercat/mailbox.py +339 -0
- oscura/analyzers/protocols/industrial/ethercat/topology.py +166 -0
- oscura/analyzers/protocols/industrial/modbus/__init__.py +31 -0
- oscura/analyzers/protocols/industrial/modbus/analyzer.py +525 -0
- oscura/analyzers/protocols/industrial/modbus/crc.py +79 -0
- oscura/analyzers/protocols/industrial/modbus/functions.py +436 -0
- oscura/analyzers/protocols/industrial/opcua/__init__.py +21 -0
- oscura/analyzers/protocols/industrial/opcua/analyzer.py +552 -0
- oscura/analyzers/protocols/industrial/opcua/datatypes.py +446 -0
- oscura/analyzers/protocols/industrial/opcua/services.py +264 -0
- oscura/analyzers/protocols/industrial/profinet/__init__.py +23 -0
- oscura/analyzers/protocols/industrial/profinet/analyzer.py +441 -0
- oscura/analyzers/protocols/industrial/profinet/dcp.py +263 -0
- oscura/analyzers/protocols/industrial/profinet/ptcp.py +200 -0
- oscura/analyzers/protocols/jtag.py +180 -98
- oscura/analyzers/protocols/lin.py +219 -114
- oscura/analyzers/protocols/manchester.py +4 -4
- oscura/analyzers/protocols/onewire.py +253 -149
- oscura/analyzers/protocols/parallel_bus/__init__.py +20 -0
- oscura/analyzers/protocols/parallel_bus/centronics.py +92 -0
- oscura/analyzers/protocols/parallel_bus/gpib.py +137 -0
- oscura/analyzers/protocols/spi.py +192 -95
- oscura/analyzers/protocols/swd.py +321 -167
- oscura/analyzers/protocols/uart.py +267 -125
- oscura/analyzers/protocols/usb.py +235 -131
- oscura/analyzers/side_channel/power.py +17 -12
- oscura/analyzers/signal/__init__.py +15 -0
- oscura/analyzers/signal/timing_analysis.py +1086 -0
- oscura/analyzers/signal_integrity/__init__.py +4 -1
- oscura/analyzers/signal_integrity/sparams.py +2 -19
- oscura/analyzers/spectral/chunked.py +129 -60
- oscura/analyzers/spectral/chunked_fft.py +300 -94
- oscura/analyzers/spectral/chunked_wavelet.py +100 -80
- oscura/analyzers/statistical/checksum.py +376 -217
- oscura/analyzers/statistical/classification.py +229 -107
- oscura/analyzers/statistical/entropy.py +78 -53
- oscura/analyzers/statistics/correlation.py +407 -211
- oscura/analyzers/statistics/outliers.py +2 -2
- oscura/analyzers/statistics/streaming.py +30 -5
- oscura/analyzers/validation.py +216 -101
- oscura/analyzers/waveform/measurements.py +9 -0
- oscura/analyzers/waveform/measurements_with_uncertainty.py +31 -15
- oscura/analyzers/waveform/spectral.py +500 -228
- oscura/api/__init__.py +31 -5
- oscura/api/dsl/__init__.py +582 -0
- oscura/{dsl → api/dsl}/commands.py +43 -76
- oscura/{dsl → api/dsl}/interpreter.py +26 -51
- oscura/{dsl → api/dsl}/parser.py +107 -77
- oscura/{dsl → api/dsl}/repl.py +2 -2
- oscura/api/dsl.py +1 -1
- oscura/{integrations → api/integrations}/__init__.py +1 -1
- oscura/{integrations → api/integrations}/llm.py +201 -102
- oscura/api/operators.py +3 -3
- oscura/api/optimization.py +144 -30
- oscura/api/rest_server.py +921 -0
- oscura/api/server/__init__.py +17 -0
- oscura/api/server/dashboard.py +850 -0
- oscura/api/server/static/README.md +34 -0
- oscura/api/server/templates/base.html +181 -0
- oscura/api/server/templates/export.html +120 -0
- oscura/api/server/templates/home.html +284 -0
- oscura/api/server/templates/protocols.html +58 -0
- oscura/api/server/templates/reports.html +43 -0
- oscura/api/server/templates/session_detail.html +89 -0
- oscura/api/server/templates/sessions.html +83 -0
- oscura/api/server/templates/waveforms.html +73 -0
- oscura/automotive/__init__.py +8 -1
- oscura/automotive/can/__init__.py +10 -0
- oscura/automotive/can/checksum.py +3 -1
- oscura/automotive/can/dbc_generator.py +590 -0
- oscura/automotive/can/message_wrapper.py +121 -74
- oscura/automotive/can/patterns.py +98 -21
- oscura/automotive/can/session.py +292 -56
- oscura/automotive/can/state_machine.py +6 -3
- oscura/automotive/can/stimulus_response.py +97 -75
- oscura/automotive/dbc/__init__.py +10 -2
- oscura/automotive/dbc/generator.py +84 -56
- oscura/automotive/dbc/parser.py +6 -6
- oscura/automotive/dtc/data.json +2763 -0
- oscura/automotive/dtc/database.py +2 -2
- oscura/automotive/flexray/__init__.py +31 -0
- oscura/automotive/flexray/analyzer.py +504 -0
- oscura/automotive/flexray/crc.py +185 -0
- oscura/automotive/flexray/fibex.py +449 -0
- oscura/automotive/j1939/__init__.py +45 -8
- oscura/automotive/j1939/analyzer.py +605 -0
- oscura/automotive/j1939/spns.py +326 -0
- oscura/automotive/j1939/transport.py +306 -0
- oscura/automotive/lin/__init__.py +47 -0
- oscura/automotive/lin/analyzer.py +612 -0
- oscura/automotive/loaders/blf.py +13 -2
- oscura/automotive/loaders/csv_can.py +143 -72
- oscura/automotive/loaders/dispatcher.py +50 -2
- oscura/automotive/loaders/mdf.py +86 -45
- oscura/automotive/loaders/pcap.py +111 -61
- oscura/automotive/uds/__init__.py +4 -0
- oscura/automotive/uds/analyzer.py +725 -0
- oscura/automotive/uds/decoder.py +140 -58
- oscura/automotive/uds/models.py +7 -1
- oscura/automotive/visualization.py +1 -1
- oscura/cli/analyze.py +348 -0
- oscura/cli/batch.py +142 -122
- oscura/cli/benchmark.py +275 -0
- oscura/cli/characterize.py +137 -82
- oscura/cli/compare.py +224 -131
- oscura/cli/completion.py +250 -0
- oscura/cli/config_cmd.py +361 -0
- oscura/cli/decode.py +164 -87
- oscura/cli/export.py +286 -0
- oscura/cli/main.py +115 -31
- oscura/{onboarding → cli/onboarding}/__init__.py +3 -3
- oscura/{onboarding → cli/onboarding}/help.py +80 -58
- oscura/{onboarding → cli/onboarding}/tutorials.py +97 -72
- oscura/{onboarding → cli/onboarding}/wizard.py +55 -36
- oscura/cli/progress.py +147 -0
- oscura/cli/shell.py +157 -135
- oscura/cli/validate_cmd.py +204 -0
- oscura/cli/visualize.py +158 -0
- oscura/convenience.py +125 -79
- oscura/core/__init__.py +4 -2
- oscura/core/backend_selector.py +3 -3
- oscura/core/cache.py +126 -15
- oscura/core/cancellation.py +1 -1
- oscura/{config → core/config}/__init__.py +20 -11
- oscura/{config → core/config}/defaults.py +1 -1
- oscura/{config → core/config}/loader.py +7 -5
- oscura/{config → core/config}/memory.py +5 -5
- oscura/{config → core/config}/migration.py +1 -1
- oscura/{config → core/config}/pipeline.py +99 -23
- oscura/{config → core/config}/preferences.py +1 -1
- oscura/{config → core/config}/protocol.py +3 -3
- oscura/{config → core/config}/schema.py +426 -272
- oscura/{config → core/config}/settings.py +1 -1
- oscura/{config → core/config}/thresholds.py +195 -153
- oscura/core/correlation.py +5 -6
- oscura/core/cross_domain.py +0 -2
- oscura/core/debug.py +9 -5
- oscura/{extensibility → core/extensibility}/docs.py +158 -70
- oscura/{extensibility → core/extensibility}/extensions.py +160 -76
- oscura/{extensibility → core/extensibility}/logging.py +1 -1
- oscura/{extensibility → core/extensibility}/measurements.py +1 -1
- oscura/{extensibility → core/extensibility}/plugins.py +1 -1
- oscura/{extensibility → core/extensibility}/templates.py +73 -3
- oscura/{extensibility → core/extensibility}/validation.py +1 -1
- oscura/core/gpu_backend.py +11 -7
- oscura/core/log_query.py +101 -11
- oscura/core/logging.py +126 -54
- oscura/core/logging_advanced.py +5 -5
- oscura/core/memory_limits.py +108 -70
- oscura/core/memory_monitor.py +2 -2
- oscura/core/memory_progress.py +7 -7
- oscura/core/memory_warnings.py +1 -1
- oscura/core/numba_backend.py +13 -13
- oscura/{plugins → core/plugins}/__init__.py +9 -9
- oscura/{plugins → core/plugins}/base.py +7 -7
- oscura/{plugins → core/plugins}/cli.py +3 -3
- oscura/{plugins → core/plugins}/discovery.py +186 -106
- oscura/{plugins → core/plugins}/lifecycle.py +1 -1
- oscura/{plugins → core/plugins}/manager.py +7 -7
- oscura/{plugins → core/plugins}/registry.py +3 -3
- oscura/{plugins → core/plugins}/versioning.py +1 -1
- oscura/core/progress.py +16 -1
- oscura/core/provenance.py +8 -2
- oscura/{schemas → core/schemas}/__init__.py +2 -2
- oscura/core/schemas/bus_configuration.json +322 -0
- oscura/core/schemas/device_mapping.json +182 -0
- oscura/core/schemas/packet_format.json +418 -0
- oscura/core/schemas/protocol_definition.json +363 -0
- oscura/core/types.py +4 -0
- oscura/core/uncertainty.py +3 -3
- oscura/correlation/__init__.py +52 -0
- oscura/correlation/multi_protocol.py +811 -0
- oscura/discovery/auto_decoder.py +117 -35
- oscura/discovery/comparison.py +191 -86
- oscura/discovery/quality_validator.py +155 -68
- oscura/discovery/signal_detector.py +196 -79
- oscura/export/__init__.py +18 -20
- oscura/export/kaitai_struct.py +513 -0
- oscura/export/scapy_layer.py +801 -0
- oscura/export/wireshark/README.md +15 -15
- oscura/export/wireshark/generator.py +1 -1
- oscura/export/wireshark/templates/dissector.lua.j2 +2 -2
- oscura/export/wireshark_dissector.py +746 -0
- oscura/guidance/wizard.py +207 -111
- oscura/hardware/__init__.py +19 -0
- oscura/{acquisition → hardware/acquisition}/__init__.py +4 -4
- oscura/{acquisition → hardware/acquisition}/file.py +2 -2
- oscura/{acquisition → hardware/acquisition}/hardware.py +7 -7
- oscura/{acquisition → hardware/acquisition}/saleae.py +15 -12
- oscura/{acquisition → hardware/acquisition}/socketcan.py +1 -1
- oscura/{acquisition → hardware/acquisition}/streaming.py +2 -2
- oscura/{acquisition → hardware/acquisition}/synthetic.py +3 -3
- oscura/{acquisition → hardware/acquisition}/visa.py +33 -11
- oscura/hardware/firmware/__init__.py +29 -0
- oscura/hardware/firmware/pattern_recognition.py +874 -0
- oscura/hardware/hal_detector.py +736 -0
- oscura/hardware/security/__init__.py +37 -0
- oscura/hardware/security/side_channel_detector.py +1126 -0
- oscura/inference/__init__.py +4 -0
- oscura/inference/active_learning/README.md +7 -7
- oscura/inference/active_learning/observation_table.py +4 -1
- oscura/inference/alignment.py +216 -123
- oscura/inference/bayesian.py +113 -33
- oscura/inference/crc_reverse.py +101 -55
- oscura/inference/logic.py +6 -2
- oscura/inference/message_format.py +342 -183
- oscura/inference/protocol.py +95 -44
- oscura/inference/protocol_dsl.py +180 -82
- oscura/inference/signal_intelligence.py +1439 -706
- oscura/inference/spectral.py +99 -57
- oscura/inference/state_machine.py +810 -158
- oscura/inference/stream.py +270 -110
- oscura/iot/__init__.py +34 -0
- oscura/iot/coap/__init__.py +32 -0
- oscura/iot/coap/analyzer.py +668 -0
- oscura/iot/coap/options.py +212 -0
- oscura/iot/lorawan/__init__.py +21 -0
- oscura/iot/lorawan/crypto.py +206 -0
- oscura/iot/lorawan/decoder.py +801 -0
- oscura/iot/lorawan/mac_commands.py +341 -0
- oscura/iot/mqtt/__init__.py +27 -0
- oscura/iot/mqtt/analyzer.py +999 -0
- oscura/iot/mqtt/properties.py +315 -0
- oscura/iot/zigbee/__init__.py +31 -0
- oscura/iot/zigbee/analyzer.py +615 -0
- oscura/iot/zigbee/security.py +153 -0
- oscura/iot/zigbee/zcl.py +349 -0
- oscura/jupyter/display.py +125 -45
- oscura/{exploratory → jupyter/exploratory}/__init__.py +8 -8
- oscura/{exploratory → jupyter/exploratory}/error_recovery.py +298 -141
- oscura/jupyter/exploratory/fuzzy.py +746 -0
- oscura/{exploratory → jupyter/exploratory}/fuzzy_advanced.py +258 -100
- oscura/{exploratory → jupyter/exploratory}/legacy.py +464 -242
- oscura/{exploratory → jupyter/exploratory}/parse.py +167 -145
- oscura/{exploratory → jupyter/exploratory}/recovery.py +119 -87
- oscura/jupyter/exploratory/sync.py +612 -0
- oscura/{exploratory → jupyter/exploratory}/unknown.py +299 -176
- oscura/jupyter/magic.py +4 -4
- oscura/{ui → jupyter/ui}/__init__.py +2 -2
- oscura/{ui → jupyter/ui}/formatters.py +3 -3
- oscura/{ui → jupyter/ui}/progressive_display.py +153 -82
- oscura/loaders/__init__.py +171 -63
- oscura/loaders/binary.py +88 -1
- oscura/loaders/chipwhisperer.py +153 -137
- oscura/loaders/configurable.py +208 -86
- oscura/loaders/csv_loader.py +458 -215
- oscura/loaders/hdf5_loader.py +278 -119
- oscura/loaders/lazy.py +87 -54
- oscura/loaders/mmap_loader.py +1 -1
- oscura/loaders/numpy_loader.py +253 -116
- oscura/loaders/pcap.py +226 -151
- oscura/loaders/rigol.py +110 -49
- oscura/loaders/sigrok.py +201 -78
- oscura/loaders/tdms.py +81 -58
- oscura/loaders/tektronix.py +291 -174
- oscura/loaders/touchstone.py +182 -87
- oscura/loaders/vcd.py +215 -117
- oscura/loaders/wav.py +155 -68
- oscura/reporting/__init__.py +9 -7
- oscura/reporting/analyze.py +352 -146
- oscura/reporting/argument_preparer.py +69 -14
- oscura/reporting/auto_report.py +97 -61
- oscura/reporting/batch.py +131 -58
- oscura/reporting/chart_selection.py +57 -45
- oscura/reporting/comparison.py +63 -17
- oscura/reporting/content/executive.py +76 -24
- oscura/reporting/core_formats/multi_format.py +11 -8
- oscura/reporting/engine.py +312 -158
- oscura/reporting/enhanced_reports.py +949 -0
- oscura/reporting/export.py +86 -43
- oscura/reporting/formatting/numbers.py +69 -42
- oscura/reporting/html.py +139 -58
- oscura/reporting/index.py +137 -65
- oscura/reporting/output.py +158 -67
- oscura/reporting/pdf.py +67 -102
- oscura/reporting/plots.py +191 -112
- oscura/reporting/sections.py +88 -47
- oscura/reporting/standards.py +104 -61
- oscura/reporting/summary_generator.py +75 -55
- oscura/reporting/tables.py +138 -54
- oscura/reporting/templates/enhanced/protocol_re.html +525 -0
- oscura/reporting/templates/index.md +13 -13
- oscura/sessions/__init__.py +14 -23
- oscura/sessions/base.py +3 -3
- oscura/sessions/blackbox.py +106 -10
- oscura/sessions/generic.py +2 -2
- oscura/sessions/legacy.py +783 -0
- oscura/side_channel/__init__.py +63 -0
- oscura/side_channel/dpa.py +1025 -0
- oscura/utils/__init__.py +15 -1
- oscura/utils/autodetect.py +1 -5
- oscura/utils/bitwise.py +118 -0
- oscura/{builders → utils/builders}/__init__.py +1 -1
- oscura/{comparison → utils/comparison}/__init__.py +6 -6
- oscura/{comparison → utils/comparison}/compare.py +202 -101
- oscura/{comparison → utils/comparison}/golden.py +83 -63
- oscura/{comparison → utils/comparison}/limits.py +313 -89
- oscura/{comparison → utils/comparison}/mask.py +151 -45
- oscura/{comparison → utils/comparison}/trace_diff.py +1 -1
- oscura/{comparison → utils/comparison}/visualization.py +147 -89
- oscura/{component → utils/component}/__init__.py +3 -3
- oscura/{component → utils/component}/impedance.py +122 -58
- oscura/{component → utils/component}/reactive.py +165 -168
- oscura/{component → utils/component}/transmission_line.py +3 -3
- oscura/{filtering → utils/filtering}/__init__.py +6 -6
- oscura/{filtering → utils/filtering}/base.py +1 -1
- oscura/{filtering → utils/filtering}/convenience.py +2 -2
- oscura/{filtering → utils/filtering}/design.py +169 -93
- oscura/{filtering → utils/filtering}/filters.py +2 -2
- oscura/{filtering → utils/filtering}/introspection.py +2 -2
- oscura/utils/geometry.py +31 -0
- oscura/utils/imports.py +184 -0
- oscura/utils/lazy.py +1 -1
- oscura/{math → utils/math}/__init__.py +2 -2
- oscura/{math → utils/math}/arithmetic.py +114 -48
- oscura/{math → utils/math}/interpolation.py +139 -106
- oscura/utils/memory.py +129 -66
- oscura/utils/memory_advanced.py +92 -9
- oscura/utils/memory_extensions.py +10 -8
- oscura/{optimization → utils/optimization}/__init__.py +1 -1
- oscura/{optimization → utils/optimization}/search.py +2 -2
- oscura/utils/performance/__init__.py +58 -0
- oscura/utils/performance/caching.py +889 -0
- oscura/utils/performance/lsh_clustering.py +333 -0
- oscura/utils/performance/memory_optimizer.py +699 -0
- oscura/utils/performance/optimizations.py +675 -0
- oscura/utils/performance/parallel.py +654 -0
- oscura/utils/performance/profiling.py +661 -0
- oscura/{pipeline → utils/pipeline}/base.py +1 -1
- oscura/{pipeline → utils/pipeline}/composition.py +11 -3
- oscura/{pipeline → utils/pipeline}/parallel.py +3 -2
- oscura/{pipeline → utils/pipeline}/pipeline.py +1 -1
- oscura/{pipeline → utils/pipeline}/reverse_engineering.py +412 -221
- oscura/{search → utils/search}/__init__.py +3 -3
- oscura/{search → utils/search}/anomaly.py +188 -58
- oscura/utils/search/context.py +294 -0
- oscura/{search → utils/search}/pattern.py +138 -10
- oscura/utils/serial.py +51 -0
- oscura/utils/storage/__init__.py +61 -0
- oscura/utils/storage/database.py +1166 -0
- oscura/{streaming → utils/streaming}/chunked.py +302 -143
- oscura/{streaming → utils/streaming}/progressive.py +1 -1
- oscura/{streaming → utils/streaming}/realtime.py +3 -2
- oscura/{triggering → utils/triggering}/__init__.py +6 -6
- oscura/{triggering → utils/triggering}/base.py +6 -6
- oscura/{triggering → utils/triggering}/edge.py +2 -2
- oscura/{triggering → utils/triggering}/pattern.py +2 -2
- oscura/{triggering → utils/triggering}/pulse.py +115 -74
- oscura/{triggering → utils/triggering}/window.py +2 -2
- oscura/utils/validation.py +32 -0
- oscura/validation/__init__.py +121 -0
- oscura/{compliance → validation/compliance}/__init__.py +5 -5
- oscura/{compliance → validation/compliance}/advanced.py +5 -5
- oscura/{compliance → validation/compliance}/masks.py +1 -1
- oscura/{compliance → validation/compliance}/reporting.py +127 -53
- oscura/{compliance → validation/compliance}/testing.py +114 -52
- oscura/validation/compliance_tests.py +915 -0
- oscura/validation/fuzzer.py +990 -0
- oscura/validation/grammar_tests.py +596 -0
- oscura/validation/grammar_validator.py +904 -0
- oscura/validation/hil_testing.py +977 -0
- oscura/{quality → validation/quality}/__init__.py +4 -4
- oscura/{quality → validation/quality}/ensemble.py +251 -171
- oscura/{quality → validation/quality}/explainer.py +3 -3
- oscura/{quality → validation/quality}/scoring.py +1 -1
- oscura/{quality → validation/quality}/warnings.py +4 -4
- oscura/validation/regression_suite.py +808 -0
- oscura/validation/replay.py +788 -0
- oscura/{testing → validation/testing}/__init__.py +2 -2
- oscura/{testing → validation/testing}/synthetic.py +5 -5
- oscura/visualization/__init__.py +9 -0
- oscura/visualization/accessibility.py +1 -1
- oscura/visualization/annotations.py +64 -67
- oscura/visualization/colors.py +7 -7
- oscura/visualization/digital.py +180 -81
- oscura/visualization/eye.py +236 -85
- oscura/visualization/interactive.py +320 -143
- oscura/visualization/jitter.py +587 -247
- oscura/visualization/layout.py +169 -134
- oscura/visualization/optimization.py +103 -52
- oscura/visualization/palettes.py +1 -1
- oscura/visualization/power.py +427 -211
- oscura/visualization/power_extended.py +626 -297
- oscura/visualization/presets.py +2 -0
- oscura/visualization/protocols.py +495 -181
- oscura/visualization/render.py +79 -63
- oscura/visualization/reverse_engineering.py +171 -124
- oscura/visualization/signal_integrity.py +460 -279
- oscura/visualization/specialized.py +190 -100
- oscura/visualization/spectral.py +670 -255
- oscura/visualization/thumbnails.py +166 -137
- oscura/visualization/waveform.py +150 -63
- oscura/workflows/__init__.py +3 -0
- oscura/{batch → workflows/batch}/__init__.py +5 -5
- oscura/{batch → workflows/batch}/advanced.py +150 -75
- oscura/workflows/batch/aggregate.py +531 -0
- oscura/workflows/batch/analyze.py +236 -0
- oscura/{batch → workflows/batch}/logging.py +2 -2
- oscura/{batch → workflows/batch}/metrics.py +1 -1
- oscura/workflows/complete_re.py +1144 -0
- oscura/workflows/compliance.py +44 -54
- oscura/workflows/digital.py +197 -51
- oscura/workflows/legacy/__init__.py +12 -0
- oscura/{workflow → workflows/legacy}/dag.py +4 -1
- oscura/workflows/multi_trace.py +9 -9
- oscura/workflows/power.py +42 -62
- oscura/workflows/protocol.py +82 -49
- oscura/workflows/reverse_engineering.py +351 -150
- oscura/workflows/signal_integrity.py +157 -82
- oscura-0.6.0.dist-info/METADATA +643 -0
- oscura-0.6.0.dist-info/RECORD +590 -0
- oscura/analyzers/digital/ic_database.py +0 -498
- oscura/analyzers/digital/timing_paths.py +0 -339
- oscura/analyzers/digital/vintage.py +0 -377
- oscura/analyzers/digital/vintage_result.py +0 -148
- oscura/analyzers/protocols/parallel_bus.py +0 -449
- oscura/batch/aggregate.py +0 -300
- oscura/batch/analyze.py +0 -139
- oscura/dsl/__init__.py +0 -73
- oscura/exceptions.py +0 -59
- oscura/exploratory/fuzzy.py +0 -513
- oscura/exploratory/sync.py +0 -384
- oscura/export/wavedrom.py +0 -430
- oscura/exporters/__init__.py +0 -94
- oscura/exporters/csv.py +0 -303
- oscura/exporters/exporters.py +0 -44
- oscura/exporters/hdf5.py +0 -217
- oscura/exporters/html_export.py +0 -701
- oscura/exporters/json_export.py +0 -338
- oscura/exporters/markdown_export.py +0 -367
- oscura/exporters/matlab_export.py +0 -354
- oscura/exporters/npz_export.py +0 -219
- oscura/exporters/spice_export.py +0 -210
- oscura/exporters/vintage_logic_csv.py +0 -247
- oscura/reporting/vintage_logic_report.py +0 -523
- oscura/search/context.py +0 -149
- oscura/session/__init__.py +0 -34
- oscura/session/annotations.py +0 -289
- oscura/session/history.py +0 -313
- oscura/session/session.py +0 -520
- oscura/visualization/digital_advanced.py +0 -718
- oscura/visualization/figure_manager.py +0 -156
- oscura/workflow/__init__.py +0 -13
- oscura-0.5.0.dist-info/METADATA +0 -407
- oscura-0.5.0.dist-info/RECORD +0 -486
- /oscura/core/{config.py → config/legacy.py} +0 -0
- /oscura/{extensibility → core/extensibility}/__init__.py +0 -0
- /oscura/{extensibility → core/extensibility}/registry.py +0 -0
- /oscura/{plugins → core/plugins}/isolation.py +0 -0
- /oscura/{builders → utils/builders}/signal_builder.py +0 -0
- /oscura/{optimization → utils/optimization}/parallel.py +0 -0
- /oscura/{pipeline → utils/pipeline}/__init__.py +0 -0
- /oscura/{streaming → utils/streaming}/__init__.py +0 -0
- {oscura-0.5.0.dist-info → oscura-0.6.0.dist-info}/WHEEL +0 -0
- {oscura-0.5.0.dist-info → oscura-0.6.0.dist-info}/entry_points.txt +0 -0
- {oscura-0.5.0.dist-info → oscura-0.6.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
"""Figure management for saving and organizing matplotlib figures.
|
|
2
|
-
|
|
3
|
-
This module provides utilities for saving matplotlib figures in multiple formats
|
|
4
|
-
and managing collections of figures for report generation.
|
|
5
|
-
|
|
6
|
-
Example:
|
|
7
|
-
>>> from oscura.visualization.figure_manager import FigureManager
|
|
8
|
-
>>> manager = FigureManager(output_dir="./plots")
|
|
9
|
-
>>> paths = manager.save_figure(fig, "timing_diagram", formats=["png", "svg"])
|
|
10
|
-
>>> base64_img = manager.embed_as_base64(fig, format="png")
|
|
11
|
-
"""
|
|
12
|
-
|
|
13
|
-
from __future__ import annotations
|
|
14
|
-
|
|
15
|
-
import base64
|
|
16
|
-
from io import BytesIO
|
|
17
|
-
from pathlib import Path
|
|
18
|
-
from typing import TYPE_CHECKING, Any
|
|
19
|
-
|
|
20
|
-
if TYPE_CHECKING:
|
|
21
|
-
from matplotlib.figure import Figure
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
class FigureManager:
|
|
25
|
-
"""Manager for saving and organizing matplotlib figures.
|
|
26
|
-
|
|
27
|
-
Attributes:
|
|
28
|
-
output_dir: Directory for saving figures.
|
|
29
|
-
saved_figures: Dictionary mapping figure names to saved paths.
|
|
30
|
-
"""
|
|
31
|
-
|
|
32
|
-
def __init__(self, output_dir: str | Path):
|
|
33
|
-
"""Initialize figure manager.
|
|
34
|
-
|
|
35
|
-
Args:
|
|
36
|
-
output_dir: Directory for saving figures.
|
|
37
|
-
"""
|
|
38
|
-
self.output_dir = Path(output_dir)
|
|
39
|
-
self.output_dir.mkdir(parents=True, exist_ok=True)
|
|
40
|
-
self.saved_figures: dict[str, dict[str, Path]] = {}
|
|
41
|
-
|
|
42
|
-
def save_figure(
|
|
43
|
-
self,
|
|
44
|
-
fig: Figure,
|
|
45
|
-
name: str,
|
|
46
|
-
*,
|
|
47
|
-
formats: list[str] | None = None,
|
|
48
|
-
dpi: int = 300,
|
|
49
|
-
**savefig_kwargs: Any,
|
|
50
|
-
) -> dict[str, Path]:
|
|
51
|
-
"""Save figure in multiple formats.
|
|
52
|
-
|
|
53
|
-
Args:
|
|
54
|
-
fig: Matplotlib figure to save.
|
|
55
|
-
name: Base name for the saved files (without extension).
|
|
56
|
-
formats: List of formats to save ("png", "svg", "pdf"). Defaults to ["png"].
|
|
57
|
-
dpi: Resolution for raster formats (default: 300).
|
|
58
|
-
**savefig_kwargs: Additional kwargs passed to fig.savefig().
|
|
59
|
-
|
|
60
|
-
Returns:
|
|
61
|
-
Dictionary mapping format to saved file path.
|
|
62
|
-
|
|
63
|
-
Example:
|
|
64
|
-
>>> paths = manager.save_figure(fig, "timing_diagram", formats=["png", "svg"])
|
|
65
|
-
>>> print(paths["png"]) # PosixPath('./plots/timing_diagram.png')
|
|
66
|
-
"""
|
|
67
|
-
if formats is None:
|
|
68
|
-
formats = ["png"]
|
|
69
|
-
|
|
70
|
-
saved_paths: dict[str, Path] = {}
|
|
71
|
-
|
|
72
|
-
for fmt in formats:
|
|
73
|
-
# Construct file path
|
|
74
|
-
file_path = self.output_dir / f"{name}.{fmt}"
|
|
75
|
-
|
|
76
|
-
# Save figure
|
|
77
|
-
fig.savefig(
|
|
78
|
-
file_path,
|
|
79
|
-
dpi=dpi,
|
|
80
|
-
bbox_inches="tight",
|
|
81
|
-
format=fmt,
|
|
82
|
-
**savefig_kwargs,
|
|
83
|
-
)
|
|
84
|
-
|
|
85
|
-
saved_paths[fmt] = file_path
|
|
86
|
-
|
|
87
|
-
# Store in saved_figures registry
|
|
88
|
-
self.saved_figures[name] = saved_paths
|
|
89
|
-
|
|
90
|
-
return saved_paths
|
|
91
|
-
|
|
92
|
-
def embed_as_base64(
|
|
93
|
-
self,
|
|
94
|
-
fig: Figure,
|
|
95
|
-
format: str = "png",
|
|
96
|
-
dpi: int = 150,
|
|
97
|
-
**savefig_kwargs: Any,
|
|
98
|
-
) -> str:
|
|
99
|
-
"""Convert figure to base64-encoded string for HTML embedding.
|
|
100
|
-
|
|
101
|
-
Args:
|
|
102
|
-
fig: Matplotlib figure to convert.
|
|
103
|
-
format: Image format ("png", "jpg", "svg"). Default: "png".
|
|
104
|
-
dpi: Resolution for raster formats (default: 150).
|
|
105
|
-
**savefig_kwargs: Additional kwargs passed to fig.savefig().
|
|
106
|
-
|
|
107
|
-
Returns:
|
|
108
|
-
Base64-encoded image string (without data URI prefix).
|
|
109
|
-
|
|
110
|
-
Example:
|
|
111
|
-
>>> base64_img = manager.embed_as_base64(fig)
|
|
112
|
-
>>> html = f'<img src="data:image/png;base64,{base64_img}" />'
|
|
113
|
-
"""
|
|
114
|
-
# Save figure to bytes buffer
|
|
115
|
-
buf = BytesIO()
|
|
116
|
-
fig.savefig(
|
|
117
|
-
buf,
|
|
118
|
-
format=format,
|
|
119
|
-
dpi=dpi,
|
|
120
|
-
bbox_inches="tight",
|
|
121
|
-
**savefig_kwargs,
|
|
122
|
-
)
|
|
123
|
-
buf.seek(0)
|
|
124
|
-
|
|
125
|
-
# Encode to base64
|
|
126
|
-
img_base64 = base64.b64encode(buf.read()).decode("utf-8")
|
|
127
|
-
buf.close()
|
|
128
|
-
|
|
129
|
-
return img_base64
|
|
130
|
-
|
|
131
|
-
def get_saved_path(self, name: str, format: str) -> Path | None:
|
|
132
|
-
"""Get path to a saved figure.
|
|
133
|
-
|
|
134
|
-
Args:
|
|
135
|
-
name: Figure name.
|
|
136
|
-
format: Image format.
|
|
137
|
-
|
|
138
|
-
Returns:
|
|
139
|
-
Path to saved figure, or None if not found.
|
|
140
|
-
"""
|
|
141
|
-
if name in self.saved_figures:
|
|
142
|
-
return self.saved_figures[name].get(format)
|
|
143
|
-
return None
|
|
144
|
-
|
|
145
|
-
def list_saved_figures(self) -> list[str]:
|
|
146
|
-
"""Get list of all saved figure names.
|
|
147
|
-
|
|
148
|
-
Returns:
|
|
149
|
-
List of figure names.
|
|
150
|
-
"""
|
|
151
|
-
return list(self.saved_figures.keys())
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
__all__ = [
|
|
155
|
-
"FigureManager",
|
|
156
|
-
]
|
oscura/workflow/__init__.py
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
"""Workflow execution and DAG-based analysis.
|
|
2
|
-
|
|
3
|
-
This module provides directed acyclic graph (DAG) execution for complex
|
|
4
|
-
multi-step analysis workflows with automatic dependency resolution and
|
|
5
|
-
parallel execution.
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
from oscura.workflow.dag import TaskNode, WorkflowDAG
|
|
9
|
-
|
|
10
|
-
__all__ = [
|
|
11
|
-
"TaskNode",
|
|
12
|
-
"WorkflowDAG",
|
|
13
|
-
]
|
oscura-0.5.0.dist-info/METADATA
DELETED
|
@@ -1,407 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: oscura
|
|
3
|
-
Version: 0.5.0
|
|
4
|
-
Summary: Unified hardware reverse engineering framework. Extract all information from any system through signals and data. Unknown protocol discovery, state machine extraction, CRC recovery, security analysis. 16+ protocols, 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: click<9.0.0,>=8.1.0
|
|
32
|
-
Requires-Dist: dpkt<2.0.0,>=1.9.0
|
|
33
|
-
Requires-Dist: jinja2<4.0.0,>=3.1
|
|
34
|
-
Requires-Dist: matplotlib<4.0.0,>=3.7.0
|
|
35
|
-
Requires-Dist: numpy<3.0.0,>=1.24.0
|
|
36
|
-
Requires-Dist: pandas<3.0.0,>=2.0.0
|
|
37
|
-
Requires-Dist: psutil<7.0.0,>=5.9.0
|
|
38
|
-
Requires-Dist: pyyaml<7.0.0,>=6.0
|
|
39
|
-
Requires-Dist: scipy<2.0.0,>=1.10.0
|
|
40
|
-
Requires-Dist: tm-data-types<1.0.0,>=0.3.0
|
|
41
|
-
Provides-Extra: all
|
|
42
|
-
Requires-Dist: asammdf<9.0.0,>=8.0.0; extra == 'all'
|
|
43
|
-
Requires-Dist: cantools<40.0.0,>=39.4.0; extra == 'all'
|
|
44
|
-
Requires-Dist: check-jsonschema<1.0.0,>=0.29.0; extra == 'all'
|
|
45
|
-
Requires-Dist: h5py<4.0.0,>=3.0.0; extra == 'all'
|
|
46
|
-
Requires-Dist: hypothesis<7.0.0,>=6.0.0; extra == 'all'
|
|
47
|
-
Requires-Dist: interrogate<2.0.0,>=1.7.0; extra == 'all'
|
|
48
|
-
Requires-Dist: ipython<9.0.0,>=8.0.0; extra == 'all'
|
|
49
|
-
Requires-Dist: jupyter<2.0.0,>=1.0.0; extra == 'all'
|
|
50
|
-
Requires-Dist: nbconvert<8.0.0,>=7.0.0; extra == 'all'
|
|
51
|
-
Requires-Dist: networkx<4.0.0,>=3.0; extra == 'all'
|
|
52
|
-
Requires-Dist: nptdms<2.0.0,>=1.7.0; extra == 'all'
|
|
53
|
-
Requires-Dist: openpyxl<4.0.0,>=3.0.0; extra == 'all'
|
|
54
|
-
Requires-Dist: pytest-benchmark<6.0.0,>=4.0.0; extra == 'all'
|
|
55
|
-
Requires-Dist: pytest-cov<8.0.0,>=6.0; extra == 'all'
|
|
56
|
-
Requires-Dist: pytest-timeout<3.0.0,>=2.3.0; extra == 'all'
|
|
57
|
-
Requires-Dist: pytest<10.0.0,>=8.0; extra == 'all'
|
|
58
|
-
Requires-Dist: python-can<5.0.0,>=4.4.0; extra == 'all'
|
|
59
|
-
Requires-Dist: python-pptx<1.0.0,>=0.6.21; extra == 'all'
|
|
60
|
-
Requires-Dist: pyvisa-py<1.0.0,>=0.7.0; extra == 'all'
|
|
61
|
-
Requires-Dist: pyvisa<2.0.0,>=1.13.0; extra == 'all'
|
|
62
|
-
Requires-Dist: pywavelets<2.0.0,>=1.0.0; extra == 'all'
|
|
63
|
-
Requires-Dist: reportlab<6.0.0,>=4.4.7; extra == 'all'
|
|
64
|
-
Requires-Dist: rigolwfm<2.0.0,>=1.0.0; extra == 'all'
|
|
65
|
-
Requires-Dist: scapy<3.0.0,>=2.5.0; extra == 'all'
|
|
66
|
-
Requires-Dist: types-pyyaml<7.0.0,>=6.0; extra == 'all'
|
|
67
|
-
Requires-Dist: yamllint<2.0.0,>=1.35; extra == 'all'
|
|
68
|
-
Provides-Extra: analysis
|
|
69
|
-
Requires-Dist: networkx<4.0.0,>=3.0; extra == 'analysis'
|
|
70
|
-
Requires-Dist: openpyxl<4.0.0,>=3.0.0; extra == 'analysis'
|
|
71
|
-
Requires-Dist: pywavelets<2.0.0,>=1.0.0; extra == 'analysis'
|
|
72
|
-
Provides-Extra: automotive
|
|
73
|
-
Requires-Dist: asammdf<9.0.0,>=8.0.0; extra == 'automotive'
|
|
74
|
-
Requires-Dist: cantools<40.0.0,>=39.4.0; extra == 'automotive'
|
|
75
|
-
Requires-Dist: python-can<5.0.0,>=4.4.0; extra == 'automotive'
|
|
76
|
-
Requires-Dist: scapy<3.0.0,>=2.5.0; extra == 'automotive'
|
|
77
|
-
Provides-Extra: dev
|
|
78
|
-
Requires-Dist: check-jsonschema<1.0.0,>=0.29.0; extra == 'dev'
|
|
79
|
-
Requires-Dist: hypothesis<7.0.0,>=6.0.0; extra == 'dev'
|
|
80
|
-
Requires-Dist: interrogate<2.0.0,>=1.7.0; extra == 'dev'
|
|
81
|
-
Requires-Dist: pytest-benchmark<6.0.0,>=4.0.0; extra == 'dev'
|
|
82
|
-
Requires-Dist: pytest-cov<8.0.0,>=6.0; extra == 'dev'
|
|
83
|
-
Requires-Dist: pytest-timeout<3.0.0,>=2.3.0; extra == 'dev'
|
|
84
|
-
Requires-Dist: pytest<10.0.0,>=8.0; extra == 'dev'
|
|
85
|
-
Requires-Dist: types-pyyaml<7.0.0,>=6.0; extra == 'dev'
|
|
86
|
-
Requires-Dist: yamllint<2.0.0,>=1.35; extra == 'dev'
|
|
87
|
-
Provides-Extra: hardware
|
|
88
|
-
Requires-Dist: pyvisa-py<1.0.0,>=0.7.0; extra == 'hardware'
|
|
89
|
-
Requires-Dist: pyvisa<2.0.0,>=1.13.0; extra == 'hardware'
|
|
90
|
-
Provides-Extra: hdf5
|
|
91
|
-
Requires-Dist: h5py<4.0.0,>=3.0.0; extra == 'hdf5'
|
|
92
|
-
Provides-Extra: jupyter
|
|
93
|
-
Requires-Dist: ipython<9.0.0,>=8.0.0; extra == 'jupyter'
|
|
94
|
-
Requires-Dist: jupyter<2.0.0,>=1.0.0; extra == 'jupyter'
|
|
95
|
-
Requires-Dist: nbconvert<8.0.0,>=7.0.0; extra == 'jupyter'
|
|
96
|
-
Provides-Extra: oscilloscopes
|
|
97
|
-
Requires-Dist: nptdms<2.0.0,>=1.7.0; extra == 'oscilloscopes'
|
|
98
|
-
Requires-Dist: rigolwfm<2.0.0,>=1.0.0; extra == 'oscilloscopes'
|
|
99
|
-
Provides-Extra: reporting
|
|
100
|
-
Requires-Dist: python-pptx<1.0.0,>=0.6.21; extra == 'reporting'
|
|
101
|
-
Requires-Dist: reportlab<6.0.0,>=4.4.7; extra == 'reporting'
|
|
102
|
-
Description-Content-Type: text/markdown
|
|
103
|
-
|
|
104
|
-
# Oscura
|
|
105
|
-
|
|
106
|
-
**Unified hardware reverse engineering framework. Extract all information from any system through signals and data.**
|
|
107
|
-
|
|
108
|
-
**Build Status:**
|
|
109
|
-
[](https://github.com/oscura-re/oscura/actions/workflows/ci.yml)
|
|
110
|
-
[](https://github.com/oscura-re/oscura/actions/workflows/code-quality.yml)
|
|
111
|
-
[](https://github.com/oscura-re/oscura/actions/workflows/docs.yml)
|
|
112
|
-
[](https://github.com/oscura-re/oscura/actions/workflows/test-quality.yml)
|
|
113
|
-
|
|
114
|
-
**Package:**
|
|
115
|
-
[](https://pypi.org/project/oscura/)
|
|
116
|
-
[](https://www.python.org/downloads/)
|
|
117
|
-
[](https://opensource.org/licenses/MIT)
|
|
118
|
-
[](https://pypi.org/project/oscura/)
|
|
119
|
-
|
|
120
|
-
**Code Quality:**
|
|
121
|
-
[](https://codecov.io/gh/oscura-re/oscura)
|
|
122
|
-
[](https://github.com/astral-sh/ruff)
|
|
123
|
-
[](https://github.com/oscura-re/oscura/tree/main/docs)
|
|
124
|
-
|
|
125
|
-
**Project Status:**
|
|
126
|
-
[](https://github.com/oscura-re/oscura/graphs/commit-activity)
|
|
127
|
-
[](https://github.com/oscura-re/oscura/commits/main)
|
|
128
|
-
|
|
129
|
-
---
|
|
130
|
-
|
|
131
|
-
## What is Oscura?
|
|
132
|
-
|
|
133
|
-
Oscura is a hardware reverse engineering framework for security researchers, right-to-repair advocates, defense analysts, and commercial intelligence teams. From oscilloscope captures to complete system understanding.
|
|
134
|
-
|
|
135
|
-
**Reverse Engineering**: Unknown protocol discovery • State machine extraction • CRC/checksum recovery • Proprietary device replication • Security vulnerability analysis • Black-box protocol analysis
|
|
136
|
-
|
|
137
|
-
**Signal Analysis**: IEEE-compliant measurements (181/1241/1459/2414) • Comprehensive protocol decoding (16+ protocols) • Spectral analysis • Timing characterization • Side-channel analysis (DPA/CPA/timing attacks)
|
|
138
|
-
|
|
139
|
-
**Unified Acquisition**: File-based • Hardware sources (SocketCAN, Saleae, PyVISA - Phase 2) • Synthetic generation • Polymorphic Source protocol
|
|
140
|
-
|
|
141
|
-
**Interactive Sessions**: Domain-specific analysis sessions • BlackBoxSession for protocol RE • Differential analysis • Field hypothesis generation • Protocol specification export
|
|
142
|
-
|
|
143
|
-
**Built For**: Exploitation • Replication • Defense analysis • Commercial intelligence • Right-to-repair • Cryptographic research
|
|
144
|
-
|
|
145
|
-
---
|
|
146
|
-
|
|
147
|
-
## Installation
|
|
148
|
-
|
|
149
|
-
```bash
|
|
150
|
-
# Using uv (recommended)
|
|
151
|
-
uv pip install oscura
|
|
152
|
-
|
|
153
|
-
# Or with pip
|
|
154
|
-
pip install oscura
|
|
155
|
-
|
|
156
|
-
# Development install (RECOMMENDED)
|
|
157
|
-
git clone https://github.com/oscura-re/oscura.git
|
|
158
|
-
cd oscura
|
|
159
|
-
./scripts/setup.sh # Complete setup (dependencies + hooks)
|
|
160
|
-
./scripts/verify-setup.sh # Verify environment is ready
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
---
|
|
164
|
-
|
|
165
|
-
## Quick Start
|
|
166
|
-
|
|
167
|
-
### Signal Analysis
|
|
168
|
-
|
|
169
|
-
```python
|
|
170
|
-
import oscura as osc
|
|
171
|
-
|
|
172
|
-
# Load oscilloscope capture
|
|
173
|
-
trace = osc.load("capture.wfm")
|
|
174
|
-
|
|
175
|
-
# Basic measurements
|
|
176
|
-
print(f"Frequency: {osc.frequency(trace) / 1e6:.3f} MHz")
|
|
177
|
-
print(f"Rise time: {osc.rise_time(trace) * 1e9:.1f} ns")
|
|
178
|
-
|
|
179
|
-
# Decode protocol
|
|
180
|
-
from oscura.protocols import UARTDecoder
|
|
181
|
-
decoder = UARTDecoder(baud_rate=115200)
|
|
182
|
-
messages = decoder.decode(trace)
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
### Black-Box Protocol Reverse Engineering
|
|
186
|
-
|
|
187
|
-
```python
|
|
188
|
-
from oscura.sessions import BlackBoxSession
|
|
189
|
-
from oscura.acquisition import FileSource
|
|
190
|
-
|
|
191
|
-
# Create analysis session
|
|
192
|
-
session = BlackBoxSession(name="IoT Device RE")
|
|
193
|
-
|
|
194
|
-
# Add recordings from different stimuli
|
|
195
|
-
session.add_recording("idle", FileSource("idle.bin"))
|
|
196
|
-
session.add_recording("button_press", FileSource("button.bin"))
|
|
197
|
-
|
|
198
|
-
# Differential analysis
|
|
199
|
-
diff = session.compare("idle", "button_press")
|
|
200
|
-
print(f"Changed bytes: {diff.changed_bytes}")
|
|
201
|
-
|
|
202
|
-
# Generate protocol specification
|
|
203
|
-
spec = session.generate_protocol_spec()
|
|
204
|
-
print(f"Detected {len(spec['fields'])} protocol fields")
|
|
205
|
-
|
|
206
|
-
# Export Wireshark dissector
|
|
207
|
-
session.export_results("dissector", "protocol.lua")
|
|
208
|
-
```
|
|
209
|
-
|
|
210
|
-
### CAN Protocol Analysis
|
|
211
|
-
|
|
212
|
-
```python
|
|
213
|
-
from oscura.automotive.can import CANSession
|
|
214
|
-
from oscura.acquisition import FileSource
|
|
215
|
-
|
|
216
|
-
# Create session
|
|
217
|
-
session = CANSession(name="Vehicle Analysis")
|
|
218
|
-
|
|
219
|
-
# Add recordings from CAN bus captures
|
|
220
|
-
session.add_recording("idle", FileSource("idle.blf"))
|
|
221
|
-
session.add_recording("accelerate", FileSource("accelerate.blf"))
|
|
222
|
-
|
|
223
|
-
# Analyze traffic
|
|
224
|
-
analysis = session.analyze()
|
|
225
|
-
print(f"Messages: {analysis['inventory']['total_messages']}")
|
|
226
|
-
print(f"Unique IDs: {len(analysis['inventory']['message_ids'])}")
|
|
227
|
-
|
|
228
|
-
# Compare recordings
|
|
229
|
-
diff = session.compare("idle", "accelerate")
|
|
230
|
-
print(f"Changed IDs: {len(diff.details['changed_ids'])}")
|
|
231
|
-
|
|
232
|
-
# Export DBC file
|
|
233
|
-
session.export_dbc("vehicle.dbc")
|
|
234
|
-
```
|
|
235
|
-
|
|
236
|
-
---
|
|
237
|
-
|
|
238
|
-
## Learn by Example
|
|
239
|
-
|
|
240
|
-
**Demos are the documentation.** Each category includes working code with comprehensive explanations.
|
|
241
|
-
|
|
242
|
-
### Core Capabilities
|
|
243
|
-
|
|
244
|
-
| Demo | Description |
|
|
245
|
-
|------|-------------|
|
|
246
|
-
| [01_waveform_analysis](demos/01_waveform_analysis/) | Load and analyze Tektronix, Rigol, LeCroy captures |
|
|
247
|
-
| [02_file_format_io](demos/02_file_format_io/) | CSV, HDF5, NumPy, custom binary formats |
|
|
248
|
-
| [03_custom_daq](demos/03_custom_daq/) | Streaming loaders for custom DAQ systems |
|
|
249
|
-
| [04_serial_protocols](demos/04_serial_protocols/) | UART, SPI, I2C, 1-Wire decoding |
|
|
250
|
-
| [05_protocol_decoding](demos/05_protocol_decoding/) | Protocol auto-detection and decoding |
|
|
251
|
-
| [06_udp_packet_analysis](demos/06_udp_packet_analysis/) | Network packet capture and analysis |
|
|
252
|
-
|
|
253
|
-
### Advanced Analysis
|
|
254
|
-
|
|
255
|
-
| Demo | Description |
|
|
256
|
-
|------|-------------|
|
|
257
|
-
| [07_protocol_inference](demos/07_protocol_inference/) | State machine learning, CRC reverse engineering |
|
|
258
|
-
| [08_automotive_protocols](demos/08_automotive_protocols/) | CAN, CAN-FD, LIN, FlexRay analysis |
|
|
259
|
-
| [09_automotive](demos/09_automotive/) | OBD-II, UDS, J1939 diagnostics |
|
|
260
|
-
| [10_timing_measurements](demos/10_timing_measurements/) | Rise/fall time, duty cycle (IEEE 181) |
|
|
261
|
-
| [11_mixed_signal](demos/11_mixed_signal/) | Analog + digital combined analysis |
|
|
262
|
-
| [12_spectral_compliance](demos/12_spectral_compliance/) | FFT, THD, SNR, SINAD (IEEE 1241) |
|
|
263
|
-
| [13_jitter_analysis](demos/13_jitter_analysis/) | TIE, RJ/DJ, eye diagrams (IEEE 2414) |
|
|
264
|
-
| [14_power_analysis](demos/14_power_analysis/) | DC-DC, ripple, efficiency (IEEE 1459) |
|
|
265
|
-
| [15_signal_integrity](demos/15_signal_integrity/) | TDR, S-parameters, setup/hold timing |
|
|
266
|
-
| [16_emc_compliance](demos/16_emc_compliance/) | CISPR, FCC, MIL-STD testing |
|
|
267
|
-
| [17_signal_reverse_engineering](demos/17_signal_reverse_engineering/) | Complete unknown signal analysis |
|
|
268
|
-
| [18_advanced_inference](demos/18_advanced_inference/) | Bayesian inference, Protocol DSL |
|
|
269
|
-
| [19_complete_workflows](demos/19_complete_workflows/) | End-to-end reverse engineering |
|
|
270
|
-
|
|
271
|
-
### Run Your First Demo
|
|
272
|
-
|
|
273
|
-
```bash
|
|
274
|
-
# Generate demo data
|
|
275
|
-
python demos/generate_all_demo_data.py
|
|
276
|
-
|
|
277
|
-
# Run a demo
|
|
278
|
-
uv run python demos/01_waveform_analysis/comprehensive_wfm_analysis.py
|
|
279
|
-
```
|
|
280
|
-
|
|
281
|
-
---
|
|
282
|
-
|
|
283
|
-
## Key Features
|
|
284
|
-
|
|
285
|
-
### Protocols (16+)
|
|
286
|
-
|
|
287
|
-
UART • SPI • I2C • 1-Wire • CAN • CAN-FD • LIN • FlexRay • JTAG • SWD • Manchester • Miller • USB • HDLC • I2S • MDIO • DMX512
|
|
288
|
-
|
|
289
|
-
### File Formats (18+)
|
|
290
|
-
|
|
291
|
-
Tektronix WFM • Rigol WFM • LeCroy TRC • Sigrok • VCD • CSV • NumPy • HDF5 • MATLAB • WAV • JSON • BLF • MF4 • PCAP • PCAPNG
|
|
292
|
-
|
|
293
|
-
### Standards Compliance
|
|
294
|
-
|
|
295
|
-
**IEEE 181-2011**: Rise/fall time, pulse width, overshoot
|
|
296
|
-
|
|
297
|
-
**IEEE 1241-2010**: SNR, SINAD, THD, SFDR, ENOB
|
|
298
|
-
|
|
299
|
-
**IEEE 1459-2010**: Power factor, harmonics, efficiency
|
|
300
|
-
|
|
301
|
-
**IEEE 2414-2020**: TIE, period jitter, RJ/DJ
|
|
302
|
-
|
|
303
|
-
---
|
|
304
|
-
|
|
305
|
-
## Command Line Interface
|
|
306
|
-
|
|
307
|
-
```bash
|
|
308
|
-
# Characterize signal measurements
|
|
309
|
-
oscura characterize capture.wfm
|
|
310
|
-
|
|
311
|
-
# Decode protocol
|
|
312
|
-
oscura decode uart.wfm --protocol uart
|
|
313
|
-
|
|
314
|
-
# Batch process multiple files
|
|
315
|
-
oscura batch '*.wfm' --analysis characterize
|
|
316
|
-
|
|
317
|
-
# Compare two signals
|
|
318
|
-
oscura compare before.wfm after.wfm
|
|
319
|
-
|
|
320
|
-
# Interactive shell
|
|
321
|
-
oscura shell
|
|
322
|
-
```
|
|
323
|
-
|
|
324
|
-
See [CLI Reference](docs/cli.md) for complete documentation.
|
|
325
|
-
|
|
326
|
-
---
|
|
327
|
-
|
|
328
|
-
## Contributing
|
|
329
|
-
|
|
330
|
-
We welcome contributions! See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup and guidelines.
|
|
331
|
-
|
|
332
|
-
```bash
|
|
333
|
-
# Quick setup
|
|
334
|
-
git clone https://github.com/oscura-re/oscura.git
|
|
335
|
-
cd oscura
|
|
336
|
-
uv sync --all-extras
|
|
337
|
-
./scripts/setup/install-hooks.sh
|
|
338
|
-
|
|
339
|
-
# Run tests
|
|
340
|
-
./scripts/test.sh
|
|
341
|
-
|
|
342
|
-
# Quality checks
|
|
343
|
-
./scripts/check.sh
|
|
344
|
-
```
|
|
345
|
-
|
|
346
|
-
---
|
|
347
|
-
|
|
348
|
-
## Documentation
|
|
349
|
-
|
|
350
|
-
### Getting Started
|
|
351
|
-
|
|
352
|
-
- **[Quick Start Guide](docs/guides/quick-start.md)** - Begin here
|
|
353
|
-
- **[Demos](demos/)** - Working examples for every feature
|
|
354
|
-
- **[Migration Guide](docs/migration/v0-to-v1.md)** - Upgrade from older versions
|
|
355
|
-
|
|
356
|
-
### User Guides
|
|
357
|
-
|
|
358
|
-
- **[Black-Box Protocol Analysis](docs/guides/blackbox-analysis.md)** - Unknown protocol reverse engineering
|
|
359
|
-
- **[Hardware Acquisition](docs/guides/hardware-acquisition.md)** - Direct hardware integration (Phase 2)
|
|
360
|
-
- **[Side-Channel Analysis](docs/guides/side-channel-analysis.md)** - Power/timing/EM attacks
|
|
361
|
-
- **[Workflows](docs/guides/workflows.md)** - Complete analysis workflows
|
|
362
|
-
|
|
363
|
-
### API Reference
|
|
364
|
-
|
|
365
|
-
- **[API Reference](docs/api/)** - Complete API documentation
|
|
366
|
-
- **[Session Management](docs/api/session-management.md)** - Interactive analysis sessions
|
|
367
|
-
- **[CLI Reference](docs/cli.md)** - Command line usage
|
|
368
|
-
|
|
369
|
-
### Development
|
|
370
|
-
|
|
371
|
-
- **[Architecture](docs/architecture/)** - Design principles and patterns
|
|
372
|
-
- **[Testing Guide](docs/testing/)** - Test suite architecture
|
|
373
|
-
- **[CHANGELOG](CHANGELOG.md)** - Version history
|
|
374
|
-
|
|
375
|
-
---
|
|
376
|
-
|
|
377
|
-
## License
|
|
378
|
-
|
|
379
|
-
MIT License - see [LICENSE](LICENSE) for details.
|
|
380
|
-
|
|
381
|
-
---
|
|
382
|
-
|
|
383
|
-
## Citation
|
|
384
|
-
|
|
385
|
-
If you use Oscura in research:
|
|
386
|
-
|
|
387
|
-
```bibtex
|
|
388
|
-
@software{oscura,
|
|
389
|
-
title = {Oscura: Signal Reverse Engineering Toolkit},
|
|
390
|
-
author = {Oscura Contributors},
|
|
391
|
-
year = {2026},
|
|
392
|
-
url = {https://github.com/oscura-re/oscura}
|
|
393
|
-
}
|
|
394
|
-
```
|
|
395
|
-
|
|
396
|
-
Machine-readable: [CITATION.cff](CITATION.cff)
|
|
397
|
-
|
|
398
|
-
---
|
|
399
|
-
|
|
400
|
-
## Support
|
|
401
|
-
|
|
402
|
-
- **[GitHub Issues](https://github.com/oscura-re/oscura/issues)** - Bug reports and feature requests
|
|
403
|
-
- **[Discussions](https://github.com/oscura-re/oscura/discussions)** - Questions and community
|
|
404
|
-
|
|
405
|
-
---
|
|
406
|
-
|
|
407
|
-
**Oscura** • Reverse engineer any system from captured waveforms
|