explodethosebits 0.3.0__cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.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.
- etb/__init__.py +351 -0
- etb/__init__.pyi +976 -0
- etb/_etb.cpython-39-x86_64-linux-gnu.so +0 -0
- etb/_version.py +34 -0
- etb/py.typed +2 -0
- explodethosebits-0.3.0.dist-info/METADATA +405 -0
- explodethosebits-0.3.0.dist-info/RECORD +88 -0
- explodethosebits-0.3.0.dist-info/WHEEL +6 -0
- explodethosebits-0.3.0.dist-info/licenses/LICENSE +21 -0
- explodethosebits-0.3.0.dist-info/sboms/auditwheel.cdx.json +1 -0
- explodethosebits.libs/libcudart-c3a75b33.so.12.8.90 +0 -0
- include/etb/bit_coordinate.hpp +45 -0
- include/etb/bit_extraction.hpp +79 -0
- include/etb/bit_pruning.hpp +122 -0
- include/etb/config.hpp +284 -0
- include/etb/cuda/arch_optimizations.cuh +358 -0
- include/etb/cuda/blackwell_optimizations.cuh +300 -0
- include/etb/cuda/cuda_common.cuh +265 -0
- include/etb/cuda/etb_cuda.cuh +200 -0
- include/etb/cuda/gpu_memory.cuh +406 -0
- include/etb/cuda/heuristics_kernel.cuh +315 -0
- include/etb/cuda/path_generator_kernel.cuh +272 -0
- include/etb/cuda/prefix_pruner_kernel.cuh +370 -0
- include/etb/cuda/signature_kernel.cuh +328 -0
- include/etb/early_stopping.hpp +246 -0
- include/etb/etb.hpp +20 -0
- include/etb/heuristics.hpp +165 -0
- include/etb/memoization.hpp +285 -0
- include/etb/path.hpp +86 -0
- include/etb/path_count.hpp +87 -0
- include/etb/path_generator.hpp +175 -0
- include/etb/prefix_trie.hpp +339 -0
- include/etb/reporting.hpp +437 -0
- include/etb/scoring.hpp +269 -0
- include/etb/signature.hpp +190 -0
- include/gmock/gmock-actions.h +2297 -0
- include/gmock/gmock-cardinalities.h +159 -0
- include/gmock/gmock-function-mocker.h +518 -0
- include/gmock/gmock-matchers.h +5623 -0
- include/gmock/gmock-more-actions.h +658 -0
- include/gmock/gmock-more-matchers.h +120 -0
- include/gmock/gmock-nice-strict.h +277 -0
- include/gmock/gmock-spec-builders.h +2148 -0
- include/gmock/gmock.h +96 -0
- include/gmock/internal/custom/README.md +18 -0
- include/gmock/internal/custom/gmock-generated-actions.h +7 -0
- include/gmock/internal/custom/gmock-matchers.h +37 -0
- include/gmock/internal/custom/gmock-port.h +40 -0
- include/gmock/internal/gmock-internal-utils.h +487 -0
- include/gmock/internal/gmock-port.h +139 -0
- include/gmock/internal/gmock-pp.h +279 -0
- include/gtest/gtest-assertion-result.h +237 -0
- include/gtest/gtest-death-test.h +345 -0
- include/gtest/gtest-matchers.h +923 -0
- include/gtest/gtest-message.h +252 -0
- include/gtest/gtest-param-test.h +546 -0
- include/gtest/gtest-printers.h +1161 -0
- include/gtest/gtest-spi.h +250 -0
- include/gtest/gtest-test-part.h +192 -0
- include/gtest/gtest-typed-test.h +331 -0
- include/gtest/gtest.h +2321 -0
- include/gtest/gtest_pred_impl.h +279 -0
- include/gtest/gtest_prod.h +60 -0
- include/gtest/internal/custom/README.md +44 -0
- include/gtest/internal/custom/gtest-port.h +37 -0
- include/gtest/internal/custom/gtest-printers.h +42 -0
- include/gtest/internal/custom/gtest.h +37 -0
- include/gtest/internal/gtest-death-test-internal.h +307 -0
- include/gtest/internal/gtest-filepath.h +227 -0
- include/gtest/internal/gtest-internal.h +1560 -0
- include/gtest/internal/gtest-param-util.h +1026 -0
- include/gtest/internal/gtest-port-arch.h +122 -0
- include/gtest/internal/gtest-port.h +2481 -0
- include/gtest/internal/gtest-string.h +178 -0
- include/gtest/internal/gtest-type-util.h +220 -0
- lib/libetb_core.a +0 -0
- lib64/cmake/GTest/GTestConfig.cmake +33 -0
- lib64/cmake/GTest/GTestConfigVersion.cmake +43 -0
- lib64/cmake/GTest/GTestTargets-release.cmake +49 -0
- lib64/cmake/GTest/GTestTargets.cmake +139 -0
- lib64/libgmock.a +0 -0
- lib64/libgmock_main.a +0 -0
- lib64/libgtest.a +0 -0
- lib64/libgtest_main.a +0 -0
- lib64/pkgconfig/gmock.pc +10 -0
- lib64/pkgconfig/gmock_main.pc +10 -0
- lib64/pkgconfig/gtest.pc +9 -0
- lib64/pkgconfig/gtest_main.pc +10 -0
etb/__init__.py
ADDED
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
"""
|
|
2
|
+
ExplodeThoseBits (etb) - CUDA-Accelerated exhaustive bit-tree/bit-explosion analysis for digital forensics.
|
|
3
|
+
|
|
4
|
+
This library provides tools for extracting individual bits from bytes and
|
|
5
|
+
systematically reconstructing all possible forward-traversal combinations
|
|
6
|
+
to discover hidden/encoded data.
|
|
7
|
+
|
|
8
|
+
Example:
|
|
9
|
+
>>> import etb
|
|
10
|
+
>>>
|
|
11
|
+
>>> # Basic extraction from bytes
|
|
12
|
+
>>> candidates = etb.extract(b'\\x89PNG...', etb.EtbConfig())
|
|
13
|
+
>>> for c in candidates:
|
|
14
|
+
... print(f"{c.format_name}: {c.confidence:.2f}")
|
|
15
|
+
>>>
|
|
16
|
+
>>> # Extract from file
|
|
17
|
+
>>> candidates = etb.extract_from_file("data.bin")
|
|
18
|
+
>>>
|
|
19
|
+
>>> # Custom configuration
|
|
20
|
+
>>> config = etb.EtbConfig()
|
|
21
|
+
>>> config.output.top_n_results = 20
|
|
22
|
+
>>> config.bit_pruning = etb.BitPruningConfig(etb.BitPruningMode.MSB_ONLY)
|
|
23
|
+
>>> candidates = etb.extract(data, config)
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
# Version from setuptools_scm
|
|
27
|
+
try:
|
|
28
|
+
from etb._version import __version__
|
|
29
|
+
except ImportError:
|
|
30
|
+
__version__ = "0.0.0.dev0"
|
|
31
|
+
|
|
32
|
+
__author__ = "Odin Glynn-Martin"
|
|
33
|
+
|
|
34
|
+
# Import the native extension module
|
|
35
|
+
try:
|
|
36
|
+
from etb._etb import *
|
|
37
|
+
from etb._etb import (
|
|
38
|
+
# Core data structures
|
|
39
|
+
BitCoordinate,
|
|
40
|
+
Path,
|
|
41
|
+
# Bit extraction
|
|
42
|
+
extract_bit,
|
|
43
|
+
extract_bits_from_path,
|
|
44
|
+
bits_to_bytes,
|
|
45
|
+
path_to_bytes,
|
|
46
|
+
bytes_to_bits,
|
|
47
|
+
# Path generation
|
|
48
|
+
PathGeneratorConfig,
|
|
49
|
+
PathGenerator,
|
|
50
|
+
PathCountResult,
|
|
51
|
+
estimate_path_count,
|
|
52
|
+
path_count_exceeds_threshold,
|
|
53
|
+
# Signature detection
|
|
54
|
+
FileSignature,
|
|
55
|
+
FooterSignature,
|
|
56
|
+
FormatDefinition,
|
|
57
|
+
SignatureMatch,
|
|
58
|
+
SignatureDictionary,
|
|
59
|
+
SignatureMatcher,
|
|
60
|
+
# Heuristics
|
|
61
|
+
HeuristicResult,
|
|
62
|
+
HeuristicWeights,
|
|
63
|
+
HeuristicsEngine,
|
|
64
|
+
# Early stopping
|
|
65
|
+
StopLevel,
|
|
66
|
+
StopDecision,
|
|
67
|
+
EarlyStoppingConfig,
|
|
68
|
+
EarlyStoppingController,
|
|
69
|
+
# Prefix trie
|
|
70
|
+
PrefixStatus,
|
|
71
|
+
PrefixTrieConfig,
|
|
72
|
+
PrefixTrieStats,
|
|
73
|
+
PrefixTrie,
|
|
74
|
+
# Memoization
|
|
75
|
+
MemoizationConfig,
|
|
76
|
+
MemoizationStats,
|
|
77
|
+
PrefixCacheEntry,
|
|
78
|
+
PrefixCache,
|
|
79
|
+
# Bit pruning
|
|
80
|
+
BitPruningMode,
|
|
81
|
+
BitPruningConfig,
|
|
82
|
+
# Scoring
|
|
83
|
+
ScoringWeights,
|
|
84
|
+
StructuralValidation,
|
|
85
|
+
Candidate,
|
|
86
|
+
ScoreCalculator,
|
|
87
|
+
CandidateQueue,
|
|
88
|
+
# Configuration
|
|
89
|
+
ConfigError,
|
|
90
|
+
ConfigResult,
|
|
91
|
+
OutputConfig,
|
|
92
|
+
PerformanceConfig,
|
|
93
|
+
EtbConfig,
|
|
94
|
+
ConfigManager,
|
|
95
|
+
load_config,
|
|
96
|
+
get_default_config,
|
|
97
|
+
# High-level functions
|
|
98
|
+
extract,
|
|
99
|
+
extract_from_file,
|
|
100
|
+
)
|
|
101
|
+
except ImportError as e:
|
|
102
|
+
raise ImportError(
|
|
103
|
+
f"Failed to import etb native extension: {e}\n"
|
|
104
|
+
"Make sure the package was built correctly with CUDA support."
|
|
105
|
+
) from e
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
# Additional Python-only utilities
|
|
109
|
+
from dataclasses import dataclass
|
|
110
|
+
from typing import List, Optional, Dict, Any
|
|
111
|
+
from pathlib import Path as PathLib
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
@dataclass
|
|
115
|
+
class ExtractionResult:
|
|
116
|
+
"""
|
|
117
|
+
Complete result of an extraction operation.
|
|
118
|
+
|
|
119
|
+
Attributes:
|
|
120
|
+
success: Whether extraction found any candidates
|
|
121
|
+
candidates: List of candidate reconstructions sorted by score
|
|
122
|
+
metrics: Extraction metrics and statistics
|
|
123
|
+
"""
|
|
124
|
+
success: bool
|
|
125
|
+
candidates: List[Candidate]
|
|
126
|
+
metrics: "ExtractionMetrics"
|
|
127
|
+
|
|
128
|
+
def __bool__(self) -> bool:
|
|
129
|
+
return self.success and len(self.candidates) > 0
|
|
130
|
+
|
|
131
|
+
@property
|
|
132
|
+
def best_candidate(self) -> Optional[Candidate]:
|
|
133
|
+
"""Get the highest-scoring candidate, or None if no candidates."""
|
|
134
|
+
return self.candidates[0] if self.candidates else None
|
|
135
|
+
|
|
136
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
137
|
+
"""Convert to dictionary for serialization."""
|
|
138
|
+
return {
|
|
139
|
+
"success": self.success,
|
|
140
|
+
"candidates": [
|
|
141
|
+
{
|
|
142
|
+
"format_name": c.format_name,
|
|
143
|
+
"confidence": c.confidence,
|
|
144
|
+
"composite_score": c.composite_score,
|
|
145
|
+
"data_length": len(c.data),
|
|
146
|
+
"path_length": c.path.length(),
|
|
147
|
+
}
|
|
148
|
+
for c in self.candidates
|
|
149
|
+
],
|
|
150
|
+
"metrics": self.metrics.to_dict() if self.metrics else None,
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
@dataclass
|
|
155
|
+
class ExtractionMetrics:
|
|
156
|
+
"""
|
|
157
|
+
Metrics from an extraction operation.
|
|
158
|
+
|
|
159
|
+
Attributes:
|
|
160
|
+
total_paths_possible: Theoretical total number of paths
|
|
161
|
+
paths_evaluated: Number of paths actually evaluated
|
|
162
|
+
paths_pruned_level1: Paths pruned at level 1 (2-4 bytes)
|
|
163
|
+
paths_pruned_level2: Paths pruned at level 2 (8 bytes)
|
|
164
|
+
paths_pruned_level3: Paths pruned at level 3 (16 bytes)
|
|
165
|
+
effective_branching_factor: Average branches per level after pruning
|
|
166
|
+
effective_depth: Average depth at which paths were pruned
|
|
167
|
+
cache_hit_rate: Memoization cache hit rate [0.0, 1.0]
|
|
168
|
+
wall_clock_seconds: Total extraction time in seconds
|
|
169
|
+
gpu_utilization: GPU utilization percentage (if CUDA used)
|
|
170
|
+
"""
|
|
171
|
+
total_paths_possible: int = 0
|
|
172
|
+
paths_evaluated: int = 0
|
|
173
|
+
paths_pruned_level1: int = 0
|
|
174
|
+
paths_pruned_level2: int = 0
|
|
175
|
+
paths_pruned_level3: int = 0
|
|
176
|
+
effective_branching_factor: float = 0.0
|
|
177
|
+
effective_depth: float = 0.0
|
|
178
|
+
cache_hit_rate: float = 0.0
|
|
179
|
+
wall_clock_seconds: float = 0.0
|
|
180
|
+
gpu_utilization: float = 0.0
|
|
181
|
+
|
|
182
|
+
@property
|
|
183
|
+
def prune_rate(self) -> float:
|
|
184
|
+
"""Calculate overall prune rate."""
|
|
185
|
+
total_pruned = (
|
|
186
|
+
self.paths_pruned_level1 +
|
|
187
|
+
self.paths_pruned_level2 +
|
|
188
|
+
self.paths_pruned_level3
|
|
189
|
+
)
|
|
190
|
+
total = self.paths_evaluated + total_pruned
|
|
191
|
+
return total_pruned / total if total > 0 else 0.0
|
|
192
|
+
|
|
193
|
+
@property
|
|
194
|
+
def complexity_reduction(self) -> str:
|
|
195
|
+
"""Get human-readable complexity reduction description."""
|
|
196
|
+
if self.effective_branching_factor > 0 and self.effective_depth > 0:
|
|
197
|
+
return (
|
|
198
|
+
f"Reduced from O(8^n) to O({self.effective_branching_factor:.1f}^"
|
|
199
|
+
f"{self.effective_depth:.1f})"
|
|
200
|
+
)
|
|
201
|
+
return "N/A"
|
|
202
|
+
|
|
203
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
204
|
+
"""Convert to dictionary for serialization."""
|
|
205
|
+
return {
|
|
206
|
+
"total_paths_possible": self.total_paths_possible,
|
|
207
|
+
"paths_evaluated": self.paths_evaluated,
|
|
208
|
+
"paths_pruned_level1": self.paths_pruned_level1,
|
|
209
|
+
"paths_pruned_level2": self.paths_pruned_level2,
|
|
210
|
+
"paths_pruned_level3": self.paths_pruned_level3,
|
|
211
|
+
"effective_branching_factor": self.effective_branching_factor,
|
|
212
|
+
"effective_depth": self.effective_depth,
|
|
213
|
+
"cache_hit_rate": self.cache_hit_rate,
|
|
214
|
+
"wall_clock_seconds": self.wall_clock_seconds,
|
|
215
|
+
"gpu_utilization": self.gpu_utilization,
|
|
216
|
+
"prune_rate": self.prune_rate,
|
|
217
|
+
"complexity_reduction": self.complexity_reduction,
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
def extract_with_metrics(
|
|
222
|
+
input_data: bytes,
|
|
223
|
+
config: Optional[EtbConfig] = None,
|
|
224
|
+
max_paths: int = 1000000,
|
|
225
|
+
) -> ExtractionResult:
|
|
226
|
+
"""
|
|
227
|
+
Extract hidden data with detailed metrics.
|
|
228
|
+
|
|
229
|
+
This is a convenience wrapper around extract() that also returns
|
|
230
|
+
extraction metrics for analysis and debugging.
|
|
231
|
+
|
|
232
|
+
Args:
|
|
233
|
+
input_data: Input bytes to analyze
|
|
234
|
+
config: Configuration options (uses defaults if None)
|
|
235
|
+
max_paths: Maximum paths to evaluate
|
|
236
|
+
|
|
237
|
+
Returns:
|
|
238
|
+
ExtractionResult with candidates and metrics
|
|
239
|
+
|
|
240
|
+
Example:
|
|
241
|
+
>>> result = etb.extract_with_metrics(data)
|
|
242
|
+
>>> if result:
|
|
243
|
+
... print(f"Found {len(result.candidates)} candidates")
|
|
244
|
+
... print(f"Prune rate: {result.metrics.prune_rate:.1%}")
|
|
245
|
+
"""
|
|
246
|
+
import time
|
|
247
|
+
|
|
248
|
+
if config is None:
|
|
249
|
+
config = EtbConfig()
|
|
250
|
+
|
|
251
|
+
start_time = time.perf_counter()
|
|
252
|
+
candidates = extract(input_data, config, max_paths)
|
|
253
|
+
elapsed = time.perf_counter() - start_time
|
|
254
|
+
|
|
255
|
+
# Estimate path count
|
|
256
|
+
path_result = estimate_path_count(len(input_data))
|
|
257
|
+
|
|
258
|
+
metrics = ExtractionMetrics(
|
|
259
|
+
total_paths_possible=path_result.estimated_count,
|
|
260
|
+
paths_evaluated=len(candidates), # Simplified - actual would track internally
|
|
261
|
+
wall_clock_seconds=elapsed,
|
|
262
|
+
)
|
|
263
|
+
|
|
264
|
+
return ExtractionResult(
|
|
265
|
+
success=len(candidates) > 0,
|
|
266
|
+
candidates=candidates,
|
|
267
|
+
metrics=metrics,
|
|
268
|
+
)
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
# Convenience aliases
|
|
272
|
+
Config = EtbConfig
|
|
273
|
+
Result = ExtractionResult
|
|
274
|
+
Metrics = ExtractionMetrics
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
__all__ = [
|
|
278
|
+
# Version info
|
|
279
|
+
"__version__",
|
|
280
|
+
"__author__",
|
|
281
|
+
# Core data structures
|
|
282
|
+
"BitCoordinate",
|
|
283
|
+
"Path",
|
|
284
|
+
# Bit extraction
|
|
285
|
+
"extract_bit",
|
|
286
|
+
"extract_bits_from_path",
|
|
287
|
+
"bits_to_bytes",
|
|
288
|
+
"path_to_bytes",
|
|
289
|
+
"bytes_to_bits",
|
|
290
|
+
# Path generation
|
|
291
|
+
"PathGeneratorConfig",
|
|
292
|
+
"PathGenerator",
|
|
293
|
+
"PathCountResult",
|
|
294
|
+
"estimate_path_count",
|
|
295
|
+
"path_count_exceeds_threshold",
|
|
296
|
+
# Signature detection
|
|
297
|
+
"FileSignature",
|
|
298
|
+
"FooterSignature",
|
|
299
|
+
"FormatDefinition",
|
|
300
|
+
"SignatureMatch",
|
|
301
|
+
"SignatureDictionary",
|
|
302
|
+
"SignatureMatcher",
|
|
303
|
+
# Heuristics
|
|
304
|
+
"HeuristicResult",
|
|
305
|
+
"HeuristicWeights",
|
|
306
|
+
"HeuristicsEngine",
|
|
307
|
+
# Early stopping
|
|
308
|
+
"StopLevel",
|
|
309
|
+
"StopDecision",
|
|
310
|
+
"EarlyStoppingConfig",
|
|
311
|
+
"EarlyStoppingController",
|
|
312
|
+
# Prefix trie
|
|
313
|
+
"PrefixStatus",
|
|
314
|
+
"PrefixTrieConfig",
|
|
315
|
+
"PrefixTrieStats",
|
|
316
|
+
"PrefixTrie",
|
|
317
|
+
# Memoization
|
|
318
|
+
"MemoizationConfig",
|
|
319
|
+
"MemoizationStats",
|
|
320
|
+
"PrefixCacheEntry",
|
|
321
|
+
"PrefixCache",
|
|
322
|
+
# Bit pruning
|
|
323
|
+
"BitPruningMode",
|
|
324
|
+
"BitPruningConfig",
|
|
325
|
+
# Scoring
|
|
326
|
+
"ScoringWeights",
|
|
327
|
+
"StructuralValidation",
|
|
328
|
+
"Candidate",
|
|
329
|
+
"ScoreCalculator",
|
|
330
|
+
"CandidateQueue",
|
|
331
|
+
# Configuration
|
|
332
|
+
"ConfigError",
|
|
333
|
+
"ConfigResult",
|
|
334
|
+
"OutputConfig",
|
|
335
|
+
"PerformanceConfig",
|
|
336
|
+
"EtbConfig",
|
|
337
|
+
"ConfigManager",
|
|
338
|
+
"load_config",
|
|
339
|
+
"get_default_config",
|
|
340
|
+
# High-level functions
|
|
341
|
+
"extract",
|
|
342
|
+
"extract_from_file",
|
|
343
|
+
"extract_with_metrics",
|
|
344
|
+
# Python-only classes
|
|
345
|
+
"ExtractionResult",
|
|
346
|
+
"ExtractionMetrics",
|
|
347
|
+
# Aliases
|
|
348
|
+
"Config",
|
|
349
|
+
"Result",
|
|
350
|
+
"Metrics",
|
|
351
|
+
]
|