#!/usr/bin/env python3
"""
More aggressive SPI parser - look at all MISO data
"""
import csv

def parse_all_miso_data(filename):
    """Extract all MISO bytes across all transactions"""
    print(f"[*] Parsing {filename}...")
    
    with open(filename, 'r') as f:
        reader = csv.DictReader(f)
        
        all_miso_bytes = []
        current_byte = 0
        bit_count = 0
        last_clock = 0
        last_cs = 1
        
        for row in reader:
            cs = int(row['Channel 3'])
            clock = int(row['Channel 2'])
            miso = int(row['Channel 0'])
            
            # Only process when CS is active (LOW)
            if cs == 0:
                # Sample on rising edge
                if clock == 1 and last_clock == 0:
                    current_byte = (current_byte << 1) | miso
                    bit_count += 1
                    
                    if bit_count == 8:
                        all_miso_bytes.append(current_byte)
                        current_byte = 0
                        bit_count = 0
            elif cs == 1 and last_cs == 0:
                # Transaction ended, reset
                if bit_count > 0:
                    # Partial byte, ignore
                    current_byte = 0
                    bit_count = 0
            
            last_clock = clock
            last_cs = cs
    
    print(f"[+] Extracted {len(all_miso_bytes)} MISO bytes total")
    return all_miso_bytes

def find_16_byte_blocks(data):
    """Find interesting 16-byte blocks in the data"""
    print("\n[*] Searching for 16-byte blocks...")
    
    blocks_found = []
    
    for i in range(len(data) - 15):
        block = data[i:i+16]
        
        # Skip all zeros or all FFs
        if all(b == 0 for b in block) or all(b == 0xff for b in block):
            continue
        
        # Check for variation
        unique_bytes = len(set(block))
        if unique_bytes < 2:
            continue
        
        # Check for ASCII
        ascii_count = sum(1 for b in block if 32 <= b < 127)
        
        hex_str = ''.join(f'{b:02x}' for b in block)
        ascii_str = ''.join(chr(b) if 32 <= b < 127 else '.' for b in block)
        
        # Look for teptast
        if b'teptast' in bytes(block):
            print(f"\n[+] SECTOR 8 (Username) at offset {i}:")
            print(f"    {hex_str}")
            print(f"    '{ascii_str}'")
            blocks_found.append(('sector8', hex_str))
        elif ascii_count < 4 and unique_bytes >= 4:
            # Binary data - likely sector 22 or 34
            print(f"\n[+] Potential sector at offset {i}:")
            print(f"    {hex_str}")
            print(f"    '{ascii_str}' ({ascii_count} ASCII, {unique_bytes} unique)")
            blocks_found.append(('unknown', hex_str))
    
    return blocks_found

# Parse
miso_data = parse_all_miso_data('digital.csv')

# Show first 256 bytes
print("\n[*] First 256 MISO bytes:")
for i in range(0, min(256, len(miso_data)), 16):
    chunk = miso_data[i:i+16]
    hex_str = ' '.join(f'{b:02x}' for b in chunk)
    ascii_str = ''.join(chr(b) if 32 <= b < 127 else '.' for b in chunk)
    print(f"  {i:04x}: {hex_str:<48} {ascii_str}")

# Find blocks
blocks = find_16_byte_blocks(miso_data)

print(f"\n[*] Found {len(blocks)} interesting 16-byte blocks")

# Look for specific patterns
print("\n[*] Searching for 'teptast' pattern...")
for i in range(len(miso_data) - 6):
    if miso_data[i:i+7] == [0x74, 0x65, 0x70, 0x74, 0x61, 0x73, 0x74]:  # 'teptast'
        print(f"\n[+] Found 'teptast' at offset {i}!")
        # Show context
        start = max(0, i - 16)
        end = min(len(miso_data), i + 32)
        context = miso_data[start:end]
        for j in range(0, len(context), 16):
            chunk = context[j:j+16]
            hex_str = ' '.join(f'{b:02x}' for b in chunk)
            ascii_str = ''.join(chr(b) if 32 <= b < 127 else '.' for b in chunk)
            print(f"  {start+j:06x}: {hex_str:<48} {ascii_str}")
