i give up on can

This commit is contained in:
2026-03-27 18:10:51 +01:00
parent 7b4ff4b8bb
commit 7a9dfeda60
10 changed files with 4637 additions and 990 deletions

View File

@@ -0,0 +1,51 @@
import csv
# 1. Load the raw edges from the CSV
edges = []
with open('capture.csv', 'r') as f:
reader = csv.reader(f)
next(reader) # Skip the header row
for row in reader:
# row[0] is time in seconds, row[1] is logic state (0 or 1)
edges.append((float(row[0]), int(row[1])))
# 2. Reconstruct the physical bitstream (1 Mbps = 1 microsecond per bit)
bit_time = 1e-6
bits = []
for i in range(len(edges)-1):
duration = edges[i+1][0] - edges[i][0]
num_bits = int(round(duration / bit_time))
bits.extend([edges[i][1]] * num_bits)
# 3. Parse the CAN frames directly (Ignoring Bit Stuffing Rules)
idx = 0
print("Hunting for payloads...\n")
while idx < len(bits) - 50:
# Look for Start of Frame (0) after an idle bus (1)
if bits[idx] == 0 and (idx == 0 or bits[idx-1] == 1):
idx += 1 # Skip SOF
id_bits = bits[idx : idx+11] # 11-bit ID
idx += 11
idx += 3 # Skip RTR, IDE, and r0 control bits
dlc_bits = bits[idx : idx+4] # 4-bit Data Length Code
dlc = int("".join(map(str, dlc_bits)), 2)
idx += 4
# If payload exists, decode it into ASCII
if 0 < dlc <= 8:
payload = []
for _ in range(dlc):
byte_bits = bits[idx : idx+8]
byte_val = int("".join(map(str, byte_bits)), 2)
payload.append(chr(byte_val))
idx += 8
print(f"Decoded Payload: {''.join(payload)}")
else:
idx += 1 # Step forward if it was a false start
else:
idx += 1

View File

@@ -1,21 +0,0 @@
import struct
with open("digital-0.bin", "rb") as f:
data = f.read()
num_transitions = (len(data) - 44) // 8
# Read integers as little-endian (normal), but doubles as big-endian
initial_state = struct.unpack_from('<I', data, 16)[0]
begin_time = struct.unpack_from('>d', data, 20)[0] # big-endian
end_time = struct.unpack_from('>d', data, 28)[0] # big-endian
print(f"initial_state={initial_state}, begin={begin_time:.9f}, end={end_time:.9f}")
transitions = []
for i in range(num_transitions):
t = struct.unpack_from('>d', data, 44 + i * 8)[0]
transitions.append(t)
for i, t in enumerate(transitions[:20]):
print(f" [{i}] {t:.9f}s")

File diff suppressed because it is too large Load Diff

View File

@@ -1,23 +0,0 @@
import struct
with open("digital-0.bin", "rb") as f:
data = f.read()
# Skip header (already known to be mangled)
offset = 16
# Try Version 0 interpretation
v0_initial_state = struct.unpack_from('<I', data, offset)[0]
v0_begin_time = struct.unpack_from('<d', data, offset + 4)[0]
v0_end_time = struct.unpack_from('<d', data, offset + 12)[0]
v0_num_trans = struct.unpack_from('<Q', data, offset + 20)[0]
print(f"V0: init={v0_initial_state}, begin={v0_begin_time:.4f}, end={v0_end_time:.4f}, transitions={v0_num_trans}")
# Try Version 1 interpretation
v1_chunk_count = struct.unpack_from('<Q', data, offset)[0]
v1_initial_state = struct.unpack_from('<I', data, offset + 8)[0]
v1_sample_rate = struct.unpack_from('<d', data, offset + 12)[0]
v1_begin_time = struct.unpack_from('<d', data, offset + 20)[0]
v1_end_time = struct.unpack_from('<d', data, offset + 28)[0]
v1_num_trans = struct.unpack_from('<Q', data, offset + 36)[0]
print(f"V1: chunks={v1_chunk_count}, init={v1_initial_state}, rate={v1_sample_rate:.0f}, begin={v1_begin_time:.4f}, end={v1_end_time:.4f}, transitions={v1_num_trans}")

View File

@@ -1,18 +0,0 @@
import struct
with open("digital-0.bin", "rb") as f:
data = f.read()
num_transitions = (len(data) - 44) // 8
SAMPLE_RATE = 125_000_000
initial_state = struct.unpack_from('<I', data, 16)[0]
print(f"initial_state={initial_state}")
transitions = []
for i in range(num_transitions):
raw = struct.unpack_from('<Q', data, 44 + i * 8)[0] # uint64 little-endian
t = raw / SAMPLE_RATE
transitions.append(t)
if i < 30:
print(f" [{i}] raw={raw}, time={t:.9f}s")

View File

@@ -1,26 +0,0 @@
from collections import Counter
HEADER = bytes.fromhex("4769495E417C4370")
idx = []
with open("./digital-0.bin", "rb") as f:
data = f.read()
four_bytes = [data[i:i+4] for i in range(0, len(data), 4)]
eight_bytes = [data[i:i+8] for i in range(0, len(data), 8)]
counts_four = Counter(four_bytes)
counts_eight = Counter(eight_bytes)
print(counts_four)
print(counts_eight)
for i in range(len(idx)):
if i > 0:
print(idx[i] - idx[i-1])
else:
print(idx[i] )

File diff suppressed because one or more lines are too long

View File

@@ -1,17 +0,0 @@
import struct
with open("digital-0.bin", "rb") as f:
data = f.read()
file_size = len(data)
num_transitions = (file_size - 44) // 8
print(f"File size: {file_size}")
print(f"Computed transitions: {num_transitions}")
# Parse transitions
transitions = struct.unpack_from(f'<{num_transitions}d', data, 44)
# Print first few
for i, t in enumerate(transitions[:20]):
print(f" [{i}] {t:.9f}s")

View File

@@ -1,54 +0,0 @@
import struct
def parse_saleae_analog(filepath):
with open(filepath, 'rb') as f:
# 1. Parse the Main Header
# Format: < (little-endian), 8s (8-byte string), i (int32), i (int32), Q (uint64)
header_data = f.read(24) # 8 + 4 + 4 + 8 bytes
identifier, version, data_type, waveform_count = struct.unpack('<8s i i Q', header_data)
print(f"Identifier: {identifier.decode('ascii', errors='ignore')}")
print(f"Version: {version}")
print(f"Type: {data_type}")
print(f"Waveforms: {waveform_count}")
print("-" * 20)
# 2. Iterate through each waveform
for w in range(waveform_count):
# Parse Waveform Header
# Format: <, d (double), d (double), d (double), q (int64), Q (uint64)
wave_header_data = f.read(40) # 8 + 8 + 8 + 8 + 8 bytes
begin_time, trigger_time, sample_rate, downsample, num_samples = struct.unpack('<d d d q Q', wave_header_data)
print(f"Waveform {w+1}:")
print(f" Sample Rate: {sample_rate} Hz")
print(f" Total Samples: {num_samples}")
# 3. Read the Voltage Samples
# Format: <, f (float32). Reading chunk by chunk is much faster than loop by loop.
# We construct a dynamic format string based on num_samples
chunk_format = f'<{num_samples}f'
chunk_size = num_samples * 4 # 4 bytes per float32
raw_floats = f.read(chunk_size)
voltages = struct.unpack(chunk_format, raw_floats)
# Print the first 10 voltages just to verify
print(f" First 10 Voltages: {voltages[:10]}")
# --- CTF EXTRACTION LOGIC ---
# Let's turn these voltages back into a digital signal
# You will need to adjust this threshold based on what voltages you see!
threshold = 2.5
bitstream = []
for v in voltages:
if v > threshold:
bitstream.append('0') # Dominant
else:
bitstream.append('1') # Recessive
print(f" First 50 raw digital bits: {''.join(bitstream[:50])}")
# Run the parser
parse_saleae_analog('./patched.bin')