#!/usr/bin/env python3
"""
Parse SPI export from Saleae and find MIFARE sectors
"""
import csv

def parse_spi_export(filename):
    """Parse SPI export CSV and extract MISO byte sequences"""
    print(f"[*] Parsing {filename}...")
    
    with open(filename, 'r') as f:
        reader = csv.DictReader(f)
        
        transactions = []
        current_transaction = []
        
        for row in reader:
            if row['type'] == 'result':
                mosi = row['mosi']
                miso = row['miso']
                
                # Parse hex values
                if miso and miso.startswith('0x'):
                    miso_byte = int(miso, 16)
                    current_transaction.append(miso_byte)
                    
            elif row['type'] == 'disable':
                # End of transaction
                if current_transaction:
                    transactions.append(current_transaction)
                current_transaction = []
        
        # Add last transaction if exists
        if current_transaction:
            transactions.append(current_transaction)
    
    print(f"[+] Found {len(transactions)} SPI transactions")
    return transactions

def find_sector_data(transactions):
    """Look for MIFARE sector data (16-byte blocks)"""
    print("\n[*] Looking for 16-byte blocks (MIFARE sectors)...")
    
    sectors_found = []
    
    for idx, trans in enumerate(transactions):
        if len(trans) >= 16:
            # Check for 16-byte aligned blocks
            for offset in range(len(trans) - 15):
                block = trans[offset:offset+16]
                
                # Skip all zeros or all 0xFF
                if all(b == 0 for b in block) or all(b == 0xff for b in block):
                    continue
                
                # Check for interesting data
                unique = len(set(block))
                ascii_count = sum(1 for b in block if 32 <= b < 127)
                
                if unique >= 3:  # At least 3 different bytes
                    hex_str = ''.join(f'{b:02x}' for b in block)
                    ascii_str = ''.join(chr(b) if 32 <= b < 127 else '.' for b in block)
                    
                    # Check if it's "teptast"
                    if b'teptast' in bytes(block):
                        print(f"\n[+++] SECTOR 8 (Username) - Transaction {idx}, offset {offset}:")
                        print(f"      {hex_str}")
                        print(f"      '{ascii_str}'")
                        sectors_found.append(('sector8', hex_str))
                    elif ascii_count < 4:  # Binary data
                        print(f"\n[+] Potential sector - Transaction {idx}, offset {offset}:")
                        print(f"    {hex_str}")
                        print(f"    '{ascii_str}' (ASCII: {ascii_count}, Unique: {unique})")
                        sectors_found.append(('unknown', hex_str))
    
    return sectors_found

# Parse the export
transactions = parse_spi_export('export.csv')

# Show some sample transactions
print("\n[*] Sample transactions (first 20 with data):")
count = 0
for idx, trans in enumerate(transactions):
    if len(trans) > 0 and count < 20:
        hex_bytes = ' '.join(f'{b:02x}' for b in trans[:16])
        print(f"  Trans {idx} ({len(trans)} bytes): {hex_bytes}")
        count += 1

# Find sector data
sectors = find_sector_data(transactions)

print(f"\n[*] Total interesting blocks found: {len(sectors)}")

# Look specifically for 'teptast' pattern
print("\n[*] Searching all transactions for 'teptast' pattern...")
target = [0x74, 0x65, 0x70, 0x74, 0x61, 0x73, 0x74]  # 'teptast'

for idx, trans in enumerate(transactions):
    for i in range(len(trans) - 6):
        if trans[i:i+7] == target:
            print(f"\n[+++] Found 'teptast' in transaction {idx} at offset {i}!")
            print(f"[+++] Transaction has {len(trans)} bytes total")
            
            # Show the 16-byte block containing it
            block_start = (i // 16) * 16
            block = trans[block_start:block_start+16]
            hex_str = ''.join(f'{b:02x}' for b in block)
            ascii_str = ''.join(chr(b) if 32 <= b < 127 else '.' for b in block)
            print(f"\n      Sector 8:  {hex_str}")
            print(f"      ASCII:     '{ascii_str}'")
            
            # Show next blocks (likely sectors 22 and 34)
            for j in range(1, 6):
                next_offset = block_start + (j * 16)
                if next_offset + 16 <= len(trans):
                    next_block = trans[next_offset:next_offset+16]
                    next_hex = ''.join(f'{b:02x}' for b in next_block)
                    next_ascii = ''.join(chr(b) if 32 <= b < 127 else '.' for b in next_block)
                    
                    # Skip all zeros/FFs
                    if not (all(b == 0 for b in next_block) or all(b == 0xff for b in next_block)):
                        print(f"      Block +{j}:  {next_hex}")
                        print(f"      ASCII:     '{next_ascii}'")
                        
                        if j == 1:
                            print(f"      ^^^ Likely SECTOR 22 (auth_code)")
                        elif j == 2:
                            print(f"      ^^^ Likely SECTOR 34 (access_level)")
