CrackNuts 0.0.1.dev2__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.
- cracknuts/__init__.py +5 -0
- cracknuts/__main__.py +33 -0
- cracknuts/acquisition/__init__.py +3 -0
- cracknuts/acquisition/acquisition.py +554 -0
- cracknuts/cracker/__init__.py +0 -0
- cracknuts/cracker/basic_cracker.py +334 -0
- cracknuts/cracker/cracker.py +548 -0
- cracknuts/cracker/mock_cracker.py +163 -0
- cracknuts/cracker/protocol.py +83 -0
- cracknuts/cracker/stateful_cracker.py +214 -0
- cracknuts/logger.py +88 -0
- cracknuts/solver/__init__.py +0 -0
- cracknuts/solver/trace.py +524 -0
- cracknuts/utils/__init__.py +0 -0
- cracknuts/utils/hex_util.py +38 -0
- cracknuts-0.0.1.dev2.dist-info/LICENSE +21 -0
- cracknuts-0.0.1.dev2.dist-info/METADATA +63 -0
- cracknuts-0.0.1.dev2.dist-info/RECORD +21 -0
- cracknuts-0.0.1.dev2.dist-info/WHEEL +5 -0
- cracknuts-0.0.1.dev2.dist-info/entry_points.txt +2 -0
- cracknuts-0.0.1.dev2.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import struct
|
|
2
|
+
|
|
3
|
+
__version__ = "1.0.0"
|
|
4
|
+
|
|
5
|
+
DEFAULT_PORT = 9761
|
|
6
|
+
|
|
7
|
+
MAGIC_STR = b"AHCC"
|
|
8
|
+
|
|
9
|
+
# ┌───────────────────────────────────────────┬───────┐
|
|
10
|
+
# │--------------Request Header---------------│-------│
|
|
11
|
+
# │Magic │Version│Direction│Command│RFU│Length│PayLoad│
|
|
12
|
+
# │-------------------------------------------│-------│
|
|
13
|
+
# │ 4B │ 2B │ 1B │ 2B │2B │ 4B │$Length│
|
|
14
|
+
# │-------------------------------------------│-------│
|
|
15
|
+
# │'AHCC'│ 1 │ 'S' │ │ │ │ │
|
|
16
|
+
# └───────────────────────────────────────────┴───────┘
|
|
17
|
+
|
|
18
|
+
REQ_HEADER_FORMAT = ">4sH1sHHI"
|
|
19
|
+
REQ_HEADER_SIZE = struct.calcsize(REQ_HEADER_FORMAT)
|
|
20
|
+
|
|
21
|
+
# ┌──────────────────────────────────────┬───────┐
|
|
22
|
+
# │--------------Response Header---------│-------│
|
|
23
|
+
# │Magic │Version│Direction│Status│Length│PayLoad│
|
|
24
|
+
# │--------------------------------------│-------│
|
|
25
|
+
# │ 4B │ 2B │ 1B │ 2B │ 4B │$Length│
|
|
26
|
+
# │--------------------------------------│-------│
|
|
27
|
+
# │'AHCC'│ 1 │ 'R' │ │ │ │
|
|
28
|
+
# └──────────────────────────────────────┴───────┘
|
|
29
|
+
|
|
30
|
+
RES_HEADER_FORMAT = ">4sH1sHI"
|
|
31
|
+
RES_HEADER_SIZE = struct.calcsize(RES_HEADER_FORMAT)
|
|
32
|
+
|
|
33
|
+
DIRECTION_SEND = b"S"
|
|
34
|
+
DIRECTION_RESPONSE = b"R"
|
|
35
|
+
|
|
36
|
+
# Status Code
|
|
37
|
+
STATUS_OK = 0x0000
|
|
38
|
+
STATUS_BUSY = 0x0001
|
|
39
|
+
STATUS_ERROR = 0x8000
|
|
40
|
+
STATUS_UNSUPPORTED = 0x8001
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def version():
|
|
44
|
+
return __version__
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _build_req_message(command: int, rfu: int = 0, payload: bytes = None):
|
|
48
|
+
content = struct.pack(
|
|
49
|
+
REQ_HEADER_FORMAT,
|
|
50
|
+
MAGIC_STR,
|
|
51
|
+
int(__version__.split(".")[0]),
|
|
52
|
+
DIRECTION_SEND,
|
|
53
|
+
command,
|
|
54
|
+
rfu,
|
|
55
|
+
0 if payload is None else len(payload),
|
|
56
|
+
)
|
|
57
|
+
if payload is not None:
|
|
58
|
+
content += payload
|
|
59
|
+
|
|
60
|
+
return content
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def _build_res_message(status: int, payload: bytes = None):
|
|
64
|
+
content = struct.pack(
|
|
65
|
+
RES_HEADER_FORMAT,
|
|
66
|
+
MAGIC_STR,
|
|
67
|
+
int(__version__.split(".")[0]),
|
|
68
|
+
DIRECTION_RESPONSE,
|
|
69
|
+
status,
|
|
70
|
+
0 if payload is None else len(payload),
|
|
71
|
+
)
|
|
72
|
+
if payload is not None:
|
|
73
|
+
content += payload
|
|
74
|
+
|
|
75
|
+
return content
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def build_send_message(command: int, rfu: int = 0, payload: bytes = None):
|
|
79
|
+
return _build_req_message(command, rfu, payload)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def build_response_message(status: int, payload: bytes = None):
|
|
83
|
+
return _build_res_message(status, payload)
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import typing
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
from cracknuts.cracker.cracker import Cracker, Config
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class StatefulCracker(Cracker):
|
|
9
|
+
def __init__(self, cracker: Cracker):
|
|
10
|
+
self._cracker = cracker
|
|
11
|
+
self._config: Config = self._cracker.get_default_config()
|
|
12
|
+
|
|
13
|
+
def get_current_config(self) -> Config:
|
|
14
|
+
return self._config
|
|
15
|
+
|
|
16
|
+
def sync_config_to_cracker(self):
|
|
17
|
+
"""
|
|
18
|
+
Sync config to cracker.
|
|
19
|
+
To prevent configuration inconsistencies between the host and the device,
|
|
20
|
+
so all configuration information needs to be written to the device.
|
|
21
|
+
User should call this function before get data from device.
|
|
22
|
+
"""
|
|
23
|
+
# if self._config.nut_voltage is not None:
|
|
24
|
+
# self._cracker.nut_voltage(self._config.nut_voltage)
|
|
25
|
+
# if self._config.nut_clock is not None:
|
|
26
|
+
# self._cracker.nut_clock(self._config.nut_clock)
|
|
27
|
+
# if self._config.nut_enable is not None:
|
|
28
|
+
# self._cracker.nut_enable(self._config.nut_enable)
|
|
29
|
+
# if self._config.osc_analog_channel_enable is not None:
|
|
30
|
+
# self._cracker.osc_set_analog_channel_enable(self._config.osc_analog_channel_enable)
|
|
31
|
+
... # comment for test.
|
|
32
|
+
# todo need complete...
|
|
33
|
+
|
|
34
|
+
def set_addr(self, ip, port) -> None:
|
|
35
|
+
return self._cracker.set_addr(ip, port)
|
|
36
|
+
|
|
37
|
+
def set_uri(self, uri: str) -> None:
|
|
38
|
+
return self._cracker.set_uri(uri)
|
|
39
|
+
|
|
40
|
+
def get_uri(self):
|
|
41
|
+
return self._cracker.get_uri()
|
|
42
|
+
|
|
43
|
+
def connect(self):
|
|
44
|
+
return self._cracker.connect()
|
|
45
|
+
|
|
46
|
+
def disconnect(self):
|
|
47
|
+
return self._cracker.disconnect()
|
|
48
|
+
|
|
49
|
+
def reconnect(self):
|
|
50
|
+
return self._cracker.reconnect()
|
|
51
|
+
|
|
52
|
+
def get_connection_status(self) -> bool:
|
|
53
|
+
return self._cracker.get_connection_status()
|
|
54
|
+
|
|
55
|
+
def send_and_receive(self, message) -> tuple[int, bytes]:
|
|
56
|
+
return self._cracker.send_and_receive(message)
|
|
57
|
+
|
|
58
|
+
def send_with_command(self, command: int, rfu: int = 0, payload: str | bytes = None) -> tuple[int, bytes | None]:
|
|
59
|
+
return self._cracker.send_with_command(command, rfu, payload)
|
|
60
|
+
|
|
61
|
+
def echo(self, payload: str) -> str:
|
|
62
|
+
return self._cracker.echo(payload)
|
|
63
|
+
|
|
64
|
+
def echo_hex(self, payload: str) -> str:
|
|
65
|
+
return self._cracker.echo_hex(payload)
|
|
66
|
+
|
|
67
|
+
def get_id(self) -> str:
|
|
68
|
+
return self._cracker.get_id()
|
|
69
|
+
|
|
70
|
+
def get_name(self) -> str:
|
|
71
|
+
return self._cracker.get_name()
|
|
72
|
+
|
|
73
|
+
def get_version(self) -> str:
|
|
74
|
+
return self._cracker.get_version()
|
|
75
|
+
|
|
76
|
+
def osc_set_analog_channel_enable(self, enable: dict[int, bool]):
|
|
77
|
+
self._config.osc_analog_channel_enable = enable
|
|
78
|
+
return self._cracker.osc_set_analog_channel_enable(enable)
|
|
79
|
+
|
|
80
|
+
def osc_set_analog_coupling(self, coupling: dict[int, int]):
|
|
81
|
+
return self._cracker.osc_set_analog_coupling(coupling)
|
|
82
|
+
|
|
83
|
+
def osc_set_analog_voltage(self, channel: int, voltage: int):
|
|
84
|
+
return self._cracker.osc_set_analog_voltage(channel, voltage)
|
|
85
|
+
|
|
86
|
+
def osc_set_analog_bias_voltage(self, channel: int, voltage: int):
|
|
87
|
+
return self._cracker.osc_set_analog_bias_voltage(channel, voltage)
|
|
88
|
+
|
|
89
|
+
def osc_set_digital_channel_enable(self, enable: dict[int, bool]):
|
|
90
|
+
return self._cracker.osc_set_digital_channel_enable(enable)
|
|
91
|
+
|
|
92
|
+
def osc_set_digital_voltage(self, voltage: int):
|
|
93
|
+
return self._cracker.osc_set_digital_voltage(voltage)
|
|
94
|
+
|
|
95
|
+
def osc_set_trigger_mode(self, source: int, stop: int):
|
|
96
|
+
return self._cracker.osc_set_trigger_mode(source, stop)
|
|
97
|
+
|
|
98
|
+
def osc_set_analog_trigger_source(self, channel: int):
|
|
99
|
+
return self._cracker.osc_set_analog_trigger_source(channel)
|
|
100
|
+
|
|
101
|
+
def osc_set_digital_trigger_source(self, channel: int):
|
|
102
|
+
return self._cracker.osc_set_digital_trigger_source(channel)
|
|
103
|
+
|
|
104
|
+
def osc_set_analog_trigger_voltage(self, voltage: int):
|
|
105
|
+
return self._cracker.osc_set_analog_trigger_voltage(voltage)
|
|
106
|
+
|
|
107
|
+
def osc_set_sample_delay(self, delay: int):
|
|
108
|
+
return self._cracker.osc_set_sample_delay(delay)
|
|
109
|
+
|
|
110
|
+
def osc_set_sample_len(self, length: int):
|
|
111
|
+
self._config.osc_sample_len = length
|
|
112
|
+
return self._cracker.osc_set_sample_len(length)
|
|
113
|
+
|
|
114
|
+
def get_default_config(self) -> typing.Optional["Config"]:
|
|
115
|
+
return self._cracker.get_default_config()
|
|
116
|
+
|
|
117
|
+
def osc_force(self):
|
|
118
|
+
return self._cracker.osc_force()
|
|
119
|
+
|
|
120
|
+
def osc_set_sample_clock(self, clock: int):
|
|
121
|
+
return self._cracker.osc_set_sample_clock(clock)
|
|
122
|
+
|
|
123
|
+
def osc_set_sample_phase(self, phase: int):
|
|
124
|
+
return self._cracker.osc_set_sample_phase(phase)
|
|
125
|
+
|
|
126
|
+
def osc_single(self):
|
|
127
|
+
return self._cracker.osc_single()
|
|
128
|
+
|
|
129
|
+
def osc_is_triggered(self):
|
|
130
|
+
return self._cracker.osc_is_triggered()
|
|
131
|
+
|
|
132
|
+
def osc_get_analog_wave(self, channel: int, offset: int, sample_count: int) -> tuple[int, np.ndarray]:
|
|
133
|
+
return self._cracker.osc_get_analog_wave(channel, offset, sample_count)
|
|
134
|
+
|
|
135
|
+
def osc_get_digital_wave(self, channel: int, offset: int, sample_count: int):
|
|
136
|
+
return self._cracker.osc_get_digital_wave(channel, offset, sample_count)
|
|
137
|
+
|
|
138
|
+
def osc_set_analog_gain(self, channel: int, gain: int):
|
|
139
|
+
return self._cracker.osc_set_analog_gain(channel, gain)
|
|
140
|
+
|
|
141
|
+
def nut_enable(self, enable: int):
|
|
142
|
+
self._config.cracker_nut_enable = enable
|
|
143
|
+
return self._cracker.nut_enable(enable)
|
|
144
|
+
|
|
145
|
+
def nut_voltage(self, voltage: int):
|
|
146
|
+
self._config.cracker_nut_voltage = voltage
|
|
147
|
+
return self._cracker.nut_voltage(voltage)
|
|
148
|
+
|
|
149
|
+
def osc_set_analog_gain_raw(self, channel: int, gain: int):
|
|
150
|
+
return self._cracker.osc_set_analog_gain_raw(channel, gain)
|
|
151
|
+
|
|
152
|
+
def nut_voltage_raw(self, voltage: int):
|
|
153
|
+
return self._cracker.nut_voltage_raw(voltage)
|
|
154
|
+
|
|
155
|
+
def nut_clock(self, clock: int):
|
|
156
|
+
self._config.cracker_nut_clock = clock
|
|
157
|
+
return self._cracker.nut_clock(clock)
|
|
158
|
+
|
|
159
|
+
def nut_interface(self, interface: dict[int, bool]):
|
|
160
|
+
return self._cracker.nut_interface(interface)
|
|
161
|
+
|
|
162
|
+
def nut_timeout(self, timeout: int):
|
|
163
|
+
return self._cracker.nut_timeout(timeout)
|
|
164
|
+
|
|
165
|
+
def cracker_serial_baud(self, baud: int):
|
|
166
|
+
return self._cracker.cracker_serial_baud(baud)
|
|
167
|
+
|
|
168
|
+
def cracker_serial_width(self, width: int):
|
|
169
|
+
return self._cracker.cracker_serial_width(width)
|
|
170
|
+
|
|
171
|
+
def cracker_serial_stop(self, stop: int):
|
|
172
|
+
return self._cracker.cracker_serial_stop(stop)
|
|
173
|
+
|
|
174
|
+
def cracker_serial_odd_eve(self, odd_eve: int):
|
|
175
|
+
return self._cracker.cracker_serial_odd_eve(odd_eve)
|
|
176
|
+
|
|
177
|
+
def cracker_serial_data(self, expect_len: int, data: bytes):
|
|
178
|
+
return self._cracker.cracker_serial_data(expect_len, data)
|
|
179
|
+
|
|
180
|
+
def cracker_spi_cpol(self, cpol: int):
|
|
181
|
+
return self._cracker.cracker_spi_cpol(cpol)
|
|
182
|
+
|
|
183
|
+
def cracker_spi_cpha(self, cpha: int):
|
|
184
|
+
return self._cracker.cracker_spi_cpha(cpha)
|
|
185
|
+
|
|
186
|
+
def cracker_spi_data_len(self, cpha: int):
|
|
187
|
+
return self._cracker.cracker_spi_data_len(cpha)
|
|
188
|
+
|
|
189
|
+
def cracker_spi_freq(self, freq: int):
|
|
190
|
+
return self._cracker.cracker_spi_freq(freq)
|
|
191
|
+
|
|
192
|
+
def cracker_spi_timeout(self, timeout: int):
|
|
193
|
+
return self._cracker.cracker_spi_timeout(timeout)
|
|
194
|
+
|
|
195
|
+
def cracker_spi_data(self, expect_len: int, data: bytes):
|
|
196
|
+
return self._cracker.cracker_spi_data(expect_len, data)
|
|
197
|
+
|
|
198
|
+
def cracker_i2c_freq(self, freq: int):
|
|
199
|
+
return self._cracker.cracker_i2c_freq(freq)
|
|
200
|
+
|
|
201
|
+
def cracker_i2c_timeout(self, timeout: int):
|
|
202
|
+
return self._cracker.cracker_i2c_timeout(timeout)
|
|
203
|
+
|
|
204
|
+
def cracker_i2c_data(self, expect_len: int, data: bytes):
|
|
205
|
+
return self._cracker.cracker_i2c_data(expect_len, data)
|
|
206
|
+
|
|
207
|
+
def cracker_can_freq(self, freq: int):
|
|
208
|
+
return self._cracker.cracker_can_freq(freq)
|
|
209
|
+
|
|
210
|
+
def cracker_can_timeout(self, timeout: int):
|
|
211
|
+
return self._cracker.cracker_can_timeout(timeout)
|
|
212
|
+
|
|
213
|
+
def cracker_can_data(self, expect_len: int, data: bytes):
|
|
214
|
+
return self._cracker.cracker_can_data(expect_len, data)
|
cracknuts/logger.py
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from types import ModuleType
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
_LOG_LEVEL = logging.WARNING
|
|
6
|
+
_LOG_FORMATTER = logging.Formatter("[%(levelname)s] %(asctime)s %(module)s.%(funcName)s:%(lineno)d %(message)s")
|
|
7
|
+
_LOGGERS: dict[str, logging.Logger] = {}
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def set_level(
|
|
11
|
+
level: str | int = logging.WARNING,
|
|
12
|
+
logger: str | type | ModuleType | object | None = None,
|
|
13
|
+
) -> None:
|
|
14
|
+
global _LOG_LEVEL
|
|
15
|
+
if isinstance(level, str):
|
|
16
|
+
level = level.upper()
|
|
17
|
+
if level == "DEBUG":
|
|
18
|
+
_LOG_LEVEL = logging.DEBUG
|
|
19
|
+
elif level == "INFO":
|
|
20
|
+
_LOG_LEVEL = logging.INFO
|
|
21
|
+
elif level == "WARN":
|
|
22
|
+
_LOG_LEVEL = logging.WARNING
|
|
23
|
+
elif level == "ERROR":
|
|
24
|
+
_LOG_LEVEL = logging.ERROR
|
|
25
|
+
elif level == "CRITICAL":
|
|
26
|
+
_LOG_LEVEL = logging.CRITICAL
|
|
27
|
+
else:
|
|
28
|
+
raise ValueError(f"Unrecognized log level {level}.")
|
|
29
|
+
elif level not in [
|
|
30
|
+
logging.DEBUG,
|
|
31
|
+
logging.INFO,
|
|
32
|
+
logging.WARNING,
|
|
33
|
+
logging.ERROR,
|
|
34
|
+
logging.CRITICAL,
|
|
35
|
+
]:
|
|
36
|
+
raise ValueError(f"Unrecognized log level {level}.")
|
|
37
|
+
else:
|
|
38
|
+
_LOG_LEVEL = level
|
|
39
|
+
|
|
40
|
+
_logger = None
|
|
41
|
+
|
|
42
|
+
if logger:
|
|
43
|
+
if isinstance(logger, ModuleType):
|
|
44
|
+
logger = logger.__name__
|
|
45
|
+
elif isinstance(logger, type):
|
|
46
|
+
logger = logger.__module__ + "." + logger.__name__
|
|
47
|
+
elif isinstance(logger, str):
|
|
48
|
+
logger = logger
|
|
49
|
+
else:
|
|
50
|
+
logger = logger.__class__.__module__ + "." + logger.__class__.__name__
|
|
51
|
+
|
|
52
|
+
_logger = _LOGGERS.get(logger)
|
|
53
|
+
|
|
54
|
+
if not _logger:
|
|
55
|
+
for _logger in _LOGGERS.values():
|
|
56
|
+
_logger.setLevel(_LOG_LEVEL)
|
|
57
|
+
else:
|
|
58
|
+
_logger.setLevel(_LOG_LEVEL)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def get_logger(name: str | type | object | ModuleType, level: int | None = None) -> logging.Logger:
|
|
62
|
+
if isinstance(name, ModuleType):
|
|
63
|
+
name = name.__name__
|
|
64
|
+
elif isinstance(name, type):
|
|
65
|
+
name = name.__module__ + "." + name.__name__
|
|
66
|
+
elif isinstance(name, str):
|
|
67
|
+
name = name
|
|
68
|
+
else:
|
|
69
|
+
name = name.__class__.__module__ + "." + name.__class__.__name__
|
|
70
|
+
|
|
71
|
+
if name in _LOGGERS:
|
|
72
|
+
return _LOGGERS[name]
|
|
73
|
+
|
|
74
|
+
logger = logging.getLogger(name)
|
|
75
|
+
if level is None:
|
|
76
|
+
logger.setLevel(_LOG_LEVEL)
|
|
77
|
+
else:
|
|
78
|
+
logger.setLevel(level)
|
|
79
|
+
stream_handler = logging.StreamHandler()
|
|
80
|
+
stream_handler.setFormatter(_LOG_FORMATTER)
|
|
81
|
+
logger.addHandler(stream_handler)
|
|
82
|
+
_LOGGERS[name] = logger
|
|
83
|
+
logger.propagate = False
|
|
84
|
+
return logger
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def default_logger() -> logging.Logger:
|
|
88
|
+
return get_logger("cracknuts")
|
|
File without changes
|