oscura 0.1.2__py3-none-any.whl → 0.4.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.
Files changed (116) hide show
  1. oscura/__init__.py +1 -7
  2. oscura/acquisition/__init__.py +147 -0
  3. oscura/acquisition/file.py +255 -0
  4. oscura/acquisition/hardware.py +186 -0
  5. oscura/acquisition/saleae.py +340 -0
  6. oscura/acquisition/socketcan.py +315 -0
  7. oscura/acquisition/streaming.py +38 -0
  8. oscura/acquisition/synthetic.py +229 -0
  9. oscura/acquisition/visa.py +376 -0
  10. oscura/analyzers/__init__.py +3 -0
  11. oscura/analyzers/digital/clock.py +9 -1
  12. oscura/analyzers/digital/edges.py +1 -1
  13. oscura/analyzers/digital/timing.py +41 -11
  14. oscura/analyzers/packet/payload_extraction.py +2 -4
  15. oscura/analyzers/packet/stream.py +5 -5
  16. oscura/analyzers/patterns/__init__.py +4 -3
  17. oscura/analyzers/patterns/clustering.py +3 -1
  18. oscura/analyzers/power/ac_power.py +0 -2
  19. oscura/analyzers/power/basic.py +0 -2
  20. oscura/analyzers/power/ripple.py +0 -2
  21. oscura/analyzers/side_channel/__init__.py +52 -0
  22. oscura/analyzers/side_channel/power.py +690 -0
  23. oscura/analyzers/side_channel/timing.py +369 -0
  24. oscura/analyzers/signal_integrity/embedding.py +0 -2
  25. oscura/analyzers/signal_integrity/sparams.py +28 -206
  26. oscura/analyzers/spectral/fft.py +0 -2
  27. oscura/analyzers/statistical/__init__.py +3 -3
  28. oscura/analyzers/statistical/checksum.py +2 -0
  29. oscura/analyzers/statistical/classification.py +2 -0
  30. oscura/analyzers/statistical/entropy.py +11 -9
  31. oscura/analyzers/statistical/ngrams.py +4 -2
  32. oscura/api/fluent.py +2 -2
  33. oscura/automotive/__init__.py +4 -4
  34. oscura/automotive/can/__init__.py +0 -2
  35. oscura/automotive/can/patterns.py +3 -1
  36. oscura/automotive/can/session.py +277 -78
  37. oscura/automotive/can/state_machine.py +5 -2
  38. oscura/automotive/dbc/__init__.py +0 -2
  39. oscura/automotive/dtc/__init__.py +0 -2
  40. oscura/automotive/dtc/data.json +2763 -0
  41. oscura/automotive/dtc/database.py +37 -2769
  42. oscura/automotive/j1939/__init__.py +0 -2
  43. oscura/automotive/loaders/__init__.py +0 -2
  44. oscura/automotive/loaders/asc.py +0 -2
  45. oscura/automotive/loaders/blf.py +0 -2
  46. oscura/automotive/loaders/csv_can.py +0 -2
  47. oscura/automotive/obd/__init__.py +0 -2
  48. oscura/automotive/uds/__init__.py +0 -2
  49. oscura/automotive/uds/models.py +0 -2
  50. oscura/builders/__init__.py +9 -11
  51. oscura/builders/signal_builder.py +99 -191
  52. oscura/cli/main.py +0 -2
  53. oscura/cli/shell.py +0 -2
  54. oscura/config/loader.py +0 -2
  55. oscura/core/backend_selector.py +1 -1
  56. oscura/core/correlation.py +0 -2
  57. oscura/core/exceptions.py +61 -3
  58. oscura/core/lazy.py +5 -3
  59. oscura/core/memory_limits.py +0 -2
  60. oscura/core/numba_backend.py +5 -7
  61. oscura/core/uncertainty.py +3 -3
  62. oscura/dsl/interpreter.py +2 -0
  63. oscura/dsl/parser.py +8 -6
  64. oscura/exploratory/error_recovery.py +3 -3
  65. oscura/exploratory/parse.py +2 -0
  66. oscura/exploratory/recovery.py +2 -0
  67. oscura/exploratory/sync.py +2 -0
  68. oscura/export/wireshark/generator.py +1 -1
  69. oscura/export/wireshark/type_mapping.py +2 -0
  70. oscura/exporters/hdf5.py +1 -3
  71. oscura/extensibility/templates.py +0 -8
  72. oscura/inference/active_learning/lstar.py +2 -4
  73. oscura/inference/active_learning/observation_table.py +0 -2
  74. oscura/inference/active_learning/oracle.py +3 -1
  75. oscura/inference/active_learning/teachers/simulator.py +1 -3
  76. oscura/inference/alignment.py +2 -0
  77. oscura/inference/message_format.py +2 -0
  78. oscura/inference/protocol_dsl.py +7 -5
  79. oscura/inference/sequences.py +12 -14
  80. oscura/inference/state_machine.py +2 -0
  81. oscura/integrations/llm.py +3 -1
  82. oscura/jupyter/display.py +0 -2
  83. oscura/loaders/__init__.py +68 -51
  84. oscura/loaders/chipwhisperer.py +393 -0
  85. oscura/loaders/pcap.py +1 -1
  86. oscura/loaders/touchstone.py +221 -0
  87. oscura/math/arithmetic.py +0 -2
  88. oscura/optimization/parallel.py +9 -6
  89. oscura/pipeline/composition.py +0 -2
  90. oscura/plugins/cli.py +0 -2
  91. oscura/reporting/comparison.py +0 -2
  92. oscura/reporting/config.py +1 -1
  93. oscura/reporting/formatting/emphasis.py +2 -0
  94. oscura/reporting/formatting/numbers.py +0 -2
  95. oscura/reporting/output.py +1 -3
  96. oscura/reporting/sections.py +0 -2
  97. oscura/search/anomaly.py +2 -0
  98. oscura/session/session.py +91 -16
  99. oscura/sessions/__init__.py +70 -0
  100. oscura/sessions/base.py +323 -0
  101. oscura/sessions/blackbox.py +640 -0
  102. oscura/sessions/generic.py +189 -0
  103. oscura/testing/synthetic.py +2 -0
  104. oscura/ui/formatters.py +4 -2
  105. oscura/utils/buffer.py +2 -2
  106. oscura/utils/lazy.py +5 -5
  107. oscura/utils/memory_advanced.py +2 -2
  108. oscura/utils/memory_extensions.py +2 -2
  109. oscura/visualization/colors.py +0 -2
  110. oscura/visualization/power.py +2 -0
  111. oscura/workflows/multi_trace.py +2 -0
  112. {oscura-0.1.2.dist-info → oscura-0.4.0.dist-info}/METADATA +122 -20
  113. {oscura-0.1.2.dist-info → oscura-0.4.0.dist-info}/RECORD +116 -98
  114. {oscura-0.1.2.dist-info → oscura-0.4.0.dist-info}/WHEEL +0 -0
  115. {oscura-0.1.2.dist-info → oscura-0.4.0.dist-info}/entry_points.txt +0 -0
  116. {oscura-0.1.2.dist-info → oscura-0.4.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,189 @@
1
+ """Generic analysis session implementation.
2
+
3
+ This module provides GenericSession - a concrete implementation of AnalysisSession
4
+ for general-purpose signal analysis. It wraps the existing session.Session class
5
+ to provide the unified AnalysisSession interface while maintaining backward
6
+ compatibility.
7
+
8
+ Example:
9
+ >>> from oscura.sessions import GenericSession
10
+ >>> from oscura.acquisition import FileSource
11
+ >>>
12
+ >>> # Create generic session
13
+ >>> session = GenericSession(name="Debug Session")
14
+ >>> session.add_recording("capture1", FileSource("signal1.wfm"))
15
+ >>> session.add_recording("capture2", FileSource("signal2.wfm"))
16
+ >>>
17
+ >>> # Compare recordings
18
+ >>> diff = session.compare("capture1", "capture2")
19
+ >>> print(f"Similarity: {diff.similarity_score:.2%}")
20
+ >>>
21
+ >>> # Analyze
22
+ >>> results = session.analyze() # Generic waveform analysis
23
+
24
+ Pattern:
25
+ GenericSession is the default session type for non-domain-specific
26
+ analysis. Use domain-specific sessions (CANSession, SerialSession, etc.)
27
+ when working within a specific protocol or analysis domain.
28
+
29
+ Migration:
30
+ The existing oscura.session.Session class continues to work unchanged.
31
+ GenericSession provides the new AnalysisSession interface while
32
+ delegating to the existing Session implementation internally.
33
+
34
+ References:
35
+ Architecture Plan Phase 0.3: AnalysisSession Generic Implementation
36
+ src/oscura/session/session.py: Legacy Session class
37
+ """
38
+
39
+ from __future__ import annotations
40
+
41
+ from pathlib import Path
42
+ from typing import Any
43
+
44
+ from oscura.sessions.base import AnalysisSession
45
+
46
+
47
+ class GenericSession(AnalysisSession):
48
+ """Generic analysis session for general-purpose signal analysis.
49
+
50
+ Provides the unified AnalysisSession interface for non-domain-specific
51
+ analysis. This is the default session type when you don't need CAN,
52
+ Serial, or other specialized functionality.
53
+
54
+ Example:
55
+ >>> from oscura.sessions import GenericSession
56
+ >>> from oscura.acquisition import FileSource
57
+ >>>
58
+ >>> session = GenericSession()
59
+ >>> session.add_recording("test1", FileSource("capture1.wfm"))
60
+ >>> session.add_recording("test2", FileSource("capture2.wfm"))
61
+ >>>
62
+ >>> # Compare traces
63
+ >>> diff = session.compare("test1", "test2")
64
+ >>> print(f"Changed: {diff.changed_bytes} samples")
65
+ >>>
66
+ >>> # Generic analysis
67
+ >>> results = session.analyze()
68
+ >>> print(results["num_recordings"])
69
+ """
70
+
71
+ def analyze(self) -> dict[str, Any]:
72
+ """Perform generic waveform analysis on all recordings.
73
+
74
+ Analyzes all loaded recordings and provides summary statistics,
75
+ basic waveform measurements, and comparison results.
76
+
77
+ Returns:
78
+ Dictionary with analysis results:
79
+ - num_recordings: Number of recordings
80
+ - recordings: List of recording names
81
+ - summary: Summary statistics for each recording
82
+
83
+ Example:
84
+ >>> session = GenericSession()
85
+ >>> session.add_recording("sig", FileSource("capture.wfm"))
86
+ >>> results = session.analyze()
87
+ >>> print(results["summary"]["sig"]["mean"])
88
+ """
89
+ import numpy as np
90
+
91
+ results: dict[str, Any] = {
92
+ "num_recordings": len(self.recordings),
93
+ "recordings": self.list_recordings(),
94
+ "summary": {},
95
+ }
96
+
97
+ # Analyze each recording
98
+ from oscura.core.types import IQTrace
99
+
100
+ for name in self.list_recordings():
101
+ trace = self.get_recording(name)
102
+
103
+ # Handle IQTrace separately
104
+ if isinstance(trace, IQTrace):
105
+ raise TypeError("IQTrace analysis not yet supported in GenericSession")
106
+
107
+ # Basic statistics
108
+ summary = {
109
+ "num_samples": len(trace.data),
110
+ "sample_rate": trace.metadata.sample_rate,
111
+ "duration": len(trace.data) / trace.metadata.sample_rate,
112
+ "mean": float(np.mean(trace.data)),
113
+ "std": float(np.std(trace.data)),
114
+ "min": float(np.min(trace.data)),
115
+ "max": float(np.max(trace.data)),
116
+ "rms": float(np.sqrt(np.mean(trace.data**2))),
117
+ }
118
+
119
+ results["summary"][name] = summary
120
+
121
+ # If multiple recordings, add comparisons
122
+ if len(self.recordings) >= 2:
123
+ results["comparisons"] = {}
124
+ names = self.list_recordings()
125
+ for i in range(len(names)):
126
+ for j in range(i + 1, len(names)):
127
+ comparison_key = f"{names[i]}_vs_{names[j]}"
128
+ comp_result = self.compare(names[i], names[j])
129
+ results["comparisons"][comparison_key] = {
130
+ "similarity": comp_result.similarity_score,
131
+ "changed_samples": comp_result.changed_bytes,
132
+ }
133
+
134
+ return results
135
+
136
+ def export_results(self, format: str, path: str | Path) -> None:
137
+ """Export analysis results to file.
138
+
139
+ Extends base export with additional formats for generic analysis.
140
+
141
+ Args:
142
+ format: Export format ("report", "json", "csv").
143
+ path: Output file path.
144
+
145
+ Raises:
146
+ ValueError: If format not supported.
147
+
148
+ Example:
149
+ >>> session.export_results("report", "analysis.txt")
150
+ >>> session.export_results("json", "results.json")
151
+ """
152
+ path = Path(path)
153
+
154
+ if format == "json":
155
+ # Export as JSON
156
+ import json
157
+
158
+ results = self.analyze()
159
+
160
+ with open(path, "w") as f:
161
+ json.dump(results, f, indent=2)
162
+
163
+ elif format == "csv":
164
+ # Export summary as CSV
165
+ import csv
166
+
167
+ results = self.analyze()
168
+
169
+ with open(path, "w", newline="") as f:
170
+ if not results["summary"]:
171
+ return # No data to export
172
+
173
+ # Get fieldnames from first recording
174
+ first_rec = next(iter(results["summary"].values()))
175
+ fieldnames = ["recording"] + list(first_rec.keys())
176
+
177
+ writer = csv.DictWriter(f, fieldnames=fieldnames)
178
+ writer.writeheader()
179
+
180
+ for name, summary in results["summary"].items():
181
+ row = {"recording": name, **summary}
182
+ writer.writerow(row)
183
+
184
+ else:
185
+ # Fall back to base implementation (text report)
186
+ super().export_results(format, path)
187
+
188
+
189
+ __all__ = ["GenericSession"]
@@ -4,6 +4,8 @@ Provides utilities for generating synthetic test data with known properties
4
4
  for validation and testing purposes.
5
5
  """
6
6
 
7
+ from __future__ import annotations
8
+
7
9
  import struct
8
10
  from dataclasses import dataclass, field
9
11
  from pathlib import Path
oscura/ui/formatters.py CHANGED
@@ -19,10 +19,12 @@ from __future__ import annotations
19
19
 
20
20
  from dataclasses import dataclass
21
21
  from enum import Enum
22
- from typing import Any, Literal
22
+ from typing import Any, Literal, TypeAlias
23
23
 
24
24
  # Type alias for color names accepted by colorize()
25
- type ColorName = Literal["black", "red", "green", "yellow", "blue", "magenta", "cyan", "white"]
25
+ ColorName: TypeAlias = Literal[
26
+ "black", "red", "green", "yellow", "blue", "magenta", "cyan", "white"
27
+ ]
26
28
 
27
29
 
28
30
  class Color(Enum):
oscura/utils/buffer.py CHANGED
@@ -16,7 +16,7 @@ References:
16
16
 
17
17
  from __future__ import annotations
18
18
 
19
- from typing import TYPE_CHECKING, Any, TypeVar, overload
19
+ from typing import TYPE_CHECKING, Any, Generic, TypeVar, overload
20
20
 
21
21
  import numpy as np
22
22
 
@@ -26,7 +26,7 @@ if TYPE_CHECKING:
26
26
  T = TypeVar("T")
27
27
 
28
28
 
29
- class CircularBuffer[T]:
29
+ class CircularBuffer(Generic[T]):
30
30
  """Fixed-size circular buffer with O(1) operations.
31
31
 
32
32
  Thread-safe for single producer, single consumer pattern.
oscura/utils/lazy.py CHANGED
@@ -18,18 +18,18 @@ References:
18
18
  from __future__ import annotations
19
19
 
20
20
  from abc import ABC, abstractmethod
21
- from typing import TYPE_CHECKING, Any, TypeVar
21
+ from typing import TYPE_CHECKING, Any, Generic, TypeVar
22
22
 
23
23
  import numpy as np
24
24
  from numpy.typing import NDArray
25
25
 
26
+ T = TypeVar("T")
27
+
26
28
  if TYPE_CHECKING:
27
29
  from collections.abc import Callable
28
30
 
29
- T = TypeVar("T")
30
-
31
31
 
32
- class LazyProxy[T](ABC):
32
+ class LazyProxy(ABC, Generic[T]):
33
33
  """Abstract base class for lazy evaluation proxies.
34
34
 
35
35
  Defers computation until explicitly requested via .compute().
@@ -169,7 +169,7 @@ class LazyOperation(LazyProxy[Any]):
169
169
  return self._operation(*evaluated_operands, **self._kwargs)
170
170
 
171
171
 
172
- def lazy_operation[T](
172
+ def lazy_operation(
173
173
  func: Callable[..., T],
174
174
  *args: Any,
175
175
  **kwargs: Any,
@@ -20,7 +20,7 @@ from collections import OrderedDict
20
20
  from dataclasses import dataclass
21
21
  from enum import Enum
22
22
  from pathlib import Path
23
- from typing import TYPE_CHECKING, Any, TypeVar
23
+ from typing import TYPE_CHECKING, Any, Generic, TypeVar
24
24
 
25
25
  import numpy as np
26
26
 
@@ -664,7 +664,7 @@ T = TypeVar("T")
664
664
 
665
665
 
666
666
  @dataclass
667
- class CacheEntry[T]:
667
+ class CacheEntry(Generic[T]):
668
668
  """Cache entry with metadata.
669
669
 
670
670
  Attributes:
@@ -22,7 +22,7 @@ import hashlib
22
22
  import os
23
23
  import time
24
24
  from collections import OrderedDict
25
- from typing import TYPE_CHECKING, Any, TypeVar
25
+ from typing import TYPE_CHECKING, Any, Generic, TypeVar
26
26
 
27
27
  import numpy as np
28
28
 
@@ -102,7 +102,7 @@ class ArrayManager(ResourceManager):
102
102
  # =============================================================================
103
103
 
104
104
 
105
- class LRUCache[T]:
105
+ class LRUCache(Generic[T]):
106
106
  """Least-Recently-Used cache with memory-based eviction.
107
107
 
108
108
  Caches intermediate results with automatic eviction when
@@ -14,8 +14,6 @@ References:
14
14
  ColorBrewer schemes
15
15
  """
16
16
 
17
- from __future__ import annotations
18
-
19
17
  from typing import Literal
20
18
 
21
19
  import numpy as np
@@ -5,6 +5,8 @@ This module provides comprehensive power visualization including
5
5
  time-domain plots, energy accumulation, and multi-channel views.
6
6
  """
7
7
 
8
+ from __future__ import annotations
9
+
8
10
  from pathlib import Path
9
11
 
10
12
  import matplotlib.pyplot as plt
@@ -3,6 +3,8 @@
3
3
  Provides workflows for processing and analyzing multiple traces together.
4
4
  """
5
5
 
6
+ from __future__ import annotations
7
+
6
8
  import concurrent.futures
7
9
  from collections.abc import Iterator
8
10
  from dataclasses import dataclass, field
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: oscura
3
- Version: 0.1.2
3
+ Version: 0.4.0
4
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
5
  Project-URL: Homepage, https://github.com/oscura-re/oscura
6
6
  Project-URL: Documentation, https://github.com/oscura-re/oscura/tree/main/docs
@@ -39,7 +39,7 @@ Requires-Dist: pyyaml<7.0.0,>=6.0
39
39
  Requires-Dist: scipy<2.0.0,>=1.10.0
40
40
  Requires-Dist: tm-data-types<1.0.0,>=0.3.0
41
41
  Provides-Extra: all
42
- Requires-Dist: asammdf<8.0.0,>=7.4.0; extra == 'all'
42
+ Requires-Dist: asammdf<9.0.0,>=8.0.0; extra == 'all'
43
43
  Requires-Dist: cantools<40.0.0,>=39.4.0; extra == 'all'
44
44
  Requires-Dist: check-jsonschema<1.0.0,>=0.29.0; extra == 'all'
45
45
  Requires-Dist: h5py<4.0.0,>=3.0.0; extra == 'all'
@@ -51,11 +51,14 @@ Requires-Dist: nbconvert<8.0.0,>=7.0.0; extra == 'all'
51
51
  Requires-Dist: networkx<4.0.0,>=3.0; extra == 'all'
52
52
  Requires-Dist: nptdms<2.0.0,>=1.7.0; extra == 'all'
53
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'
54
55
  Requires-Dist: pytest-cov<8.0.0,>=6.0; extra == 'all'
55
56
  Requires-Dist: pytest-timeout<3.0.0,>=2.3.0; extra == 'all'
56
57
  Requires-Dist: pytest<10.0.0,>=8.0; extra == 'all'
57
58
  Requires-Dist: python-can<5.0.0,>=4.4.0; extra == 'all'
58
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'
59
62
  Requires-Dist: pywavelets<2.0.0,>=1.0.0; extra == 'all'
60
63
  Requires-Dist: reportlab<6.0.0,>=4.4.7; extra == 'all'
61
64
  Requires-Dist: rigolwfm<2.0.0,>=1.0.0; extra == 'all'
@@ -67,7 +70,7 @@ Requires-Dist: networkx<4.0.0,>=3.0; extra == 'analysis'
67
70
  Requires-Dist: openpyxl<4.0.0,>=3.0.0; extra == 'analysis'
68
71
  Requires-Dist: pywavelets<2.0.0,>=1.0.0; extra == 'analysis'
69
72
  Provides-Extra: automotive
70
- Requires-Dist: asammdf<8.0.0,>=7.4.0; extra == 'automotive'
73
+ Requires-Dist: asammdf<9.0.0,>=8.0.0; extra == 'automotive'
71
74
  Requires-Dist: cantools<40.0.0,>=39.4.0; extra == 'automotive'
72
75
  Requires-Dist: python-can<5.0.0,>=4.4.0; extra == 'automotive'
73
76
  Requires-Dist: scapy<3.0.0,>=2.5.0; extra == 'automotive'
@@ -75,11 +78,15 @@ Provides-Extra: dev
75
78
  Requires-Dist: check-jsonschema<1.0.0,>=0.29.0; extra == 'dev'
76
79
  Requires-Dist: hypothesis<7.0.0,>=6.0.0; extra == 'dev'
77
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'
78
82
  Requires-Dist: pytest-cov<8.0.0,>=6.0; extra == 'dev'
79
83
  Requires-Dist: pytest-timeout<3.0.0,>=2.3.0; extra == 'dev'
80
84
  Requires-Dist: pytest<10.0.0,>=8.0; extra == 'dev'
81
85
  Requires-Dist: types-pyyaml<7.0.0,>=6.0; extra == 'dev'
82
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'
83
90
  Provides-Extra: hdf5
84
91
  Requires-Dist: h5py<4.0.0,>=3.0.0; extra == 'hdf5'
85
92
  Provides-Extra: jupyter
@@ -98,10 +105,26 @@ Description-Content-Type: text/markdown
98
105
 
99
106
  **Unified hardware reverse engineering framework. Extract all information from any system through signals and data.**
100
107
 
101
- [![PyPI version](https://badge.fury.io/py/oscura.svg)](https://badge.fury.io/py/oscura)
108
+ **Build Status:**
109
+ [![CI](https://github.com/oscura-re/oscura/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/oscura-re/oscura/actions/workflows/ci.yml)
110
+ [![Code Quality](https://github.com/oscura-re/oscura/actions/workflows/code-quality.yml/badge.svg?branch=main)](https://github.com/oscura-re/oscura/actions/workflows/code-quality.yml)
111
+ [![Documentation](https://github.com/oscura-re/oscura/actions/workflows/docs.yml/badge.svg?branch=main)](https://github.com/oscura-re/oscura/actions/workflows/docs.yml)
112
+ [![Test Quality](https://github.com/oscura-re/oscura/actions/workflows/test-quality.yml/badge.svg?branch=main)](https://github.com/oscura-re/oscura/actions/workflows/test-quality.yml)
113
+
114
+ **Package:**
115
+ [![PyPI version](https://img.shields.io/pypi/v/oscura)](https://pypi.org/project/oscura/)
102
116
  [![Python 3.12+](https://img.shields.io/badge/python-3.12+-blue.svg)](https://www.python.org/downloads/)
103
117
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
104
- [![CI](https://github.com/oscura-re/oscura/workflows/CI/badge.svg)](https://github.com/oscura-re/oscura/actions)
118
+ [![PyPI Downloads](https://img.shields.io/pypi/dm/oscura)](https://pypi.org/project/oscura/)
119
+
120
+ **Code Quality:**
121
+ [![codecov](https://codecov.io/gh/oscura-re/oscura/graph/badge.svg)](https://codecov.io/gh/oscura-re/oscura)
122
+ [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
123
+ [![Docstring Coverage](https://raw.githubusercontent.com/oscura-re/oscura/main/docs/badges/interrogate_badge.svg)](https://github.com/oscura-re/oscura/tree/main/docs)
124
+
125
+ **Project Status:**
126
+ [![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-green.svg)](https://github.com/oscura-re/oscura/graphs/commit-activity)
127
+ [![Last Commit](https://img.shields.io/github/last-commit/oscura-re/oscura)](https://github.com/oscura-re/oscura/commits/main)
105
128
 
106
129
  ---
107
130
 
@@ -109,11 +132,15 @@ Description-Content-Type: text/markdown
109
132
 
110
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.
111
134
 
112
- **Reverse Engineering**: Unknown protocol discovery • State machine extraction • CRC/checksum recovery • Proprietary device replication • Security vulnerability analysis
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
113
140
 
114
- **Signal Analysis**: IEEE-compliant measurements (181/1241/1459/2414)Comprehensive protocol decoding (16+ protocols)Spectral analysisTiming characterization
141
+ **Interactive Sessions**: Domain-specific analysis sessionsBlackBoxSession for protocol RE Differential analysis Field hypothesis generation Protocol specification export
115
142
 
116
- **Built For**: Exploitation • Replication • Defense analysis • Commercial intelligence • Right-to-repair
143
+ **Built For**: Exploitation • Replication • Defense analysis • Commercial intelligence • Right-to-repair • Cryptographic research
117
144
 
118
145
  ---
119
146
 
@@ -126,17 +153,19 @@ uv pip install oscura
126
153
  # Or with pip
127
154
  pip install oscura
128
155
 
129
- # Development install
156
+ # Development install (RECOMMENDED)
130
157
  git clone https://github.com/oscura-re/oscura.git
131
158
  cd oscura
132
- uv sync --all-extras
133
- ./scripts/setup/install-hooks.sh
159
+ ./scripts/setup.sh # Complete setup (dependencies + hooks)
160
+ ./scripts/verify-setup.sh # Verify environment is ready
134
161
  ```
135
162
 
136
163
  ---
137
164
 
138
165
  ## Quick Start
139
166
 
167
+ ### Signal Analysis
168
+
140
169
  ```python
141
170
  import oscura as osc
142
171
 
@@ -153,6 +182,57 @@ decoder = UARTDecoder(baud_rate=115200)
153
182
  messages = decoder.decode(trace)
154
183
  ```
155
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
+
156
236
  ---
157
237
 
158
238
  ## Learn by Example
@@ -192,7 +272,7 @@ messages = decoder.decode(trace)
192
272
 
193
273
  ```bash
194
274
  # Generate demo data
195
- python demos/data_generation/generate_all_demo_data.py
275
+ python demos/generate_all_demo_data.py
196
276
 
197
277
  # Run a demo
198
278
  uv run python demos/01_waveform_analysis/comprehensive_wfm_analysis.py
@@ -225,17 +305,20 @@ Tektronix WFM • Rigol WFM • LeCroy TRC • Sigrok • VCD • CSV • NumPy
225
305
  ## Command Line Interface
226
306
 
227
307
  ```bash
228
- # Analyze a waveform
229
- oscura analyze capture.wfm
308
+ # Characterize signal measurements
309
+ oscura characterize capture.wfm
230
310
 
231
311
  # Decode protocol
232
- oscura decode capture.wfm --protocol uart --baud 115200
312
+ oscura decode uart.wfm --protocol uart
233
313
 
234
- # Generate report
235
- oscura report capture.wfm -o report.pdf
314
+ # Batch process multiple files
315
+ oscura batch '*.wfm' --analysis characterize
236
316
 
237
- # Convert formats
238
- oscura convert input.wfm output.csv
317
+ # Compare two signals
318
+ oscura compare before.wfm after.wfm
319
+
320
+ # Interactive shell
321
+ oscura shell
239
322
  ```
240
323
 
241
324
  See [CLI Reference](docs/cli.md) for complete documentation.
@@ -264,9 +347,28 @@ uv sync --all-extras
264
347
 
265
348
  ## Documentation
266
349
 
267
- - **[Demos](demos/)** - Start here (working examples)
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
+
268
365
  - **[API Reference](docs/api/)** - Complete API documentation
366
+ - **[Session Management](docs/api/session-management.md)** - Interactive analysis sessions
269
367
  - **[CLI Reference](docs/cli.md)** - Command line usage
368
+
369
+ ### Development
370
+
371
+ - **[Architecture](docs/architecture/)** - Design principles and patterns
270
372
  - **[Testing Guide](docs/testing/)** - Test suite architecture
271
373
  - **[CHANGELOG](CHANGELOG.md)** - Version history
272
374