BenKrueger

decode_i2c_xor.py

Nov 13th, 2025
20
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.79 KB | Cybersecurity | 0 0
  1. #!/usr/bin/env python3
  2. import json
  3. import sys
  4. from itertools import cycle
  5. from collections import defaultdict
  6.  
  7. # 7-bit temperature sensor address
  8. SENSOR_ADDR_7BIT = 0x30
  9.  
  10. # XOR key for decrypting the I2C payload
  11. XOR_KEY = "bananza"
  12.  
  13.  
  14. def load_events(path):
  15.     events = []
  16.     with open(path, "r") as f:
  17.         for line in f:
  18.             line = line.strip()
  19.             if not line:
  20.                 continue
  21.             events.append(json.loads(line))
  22.     return events
  23.  
  24.  
  25. def bits_map_to_bytes(bits_map):
  26.     """
  27.    bits_map: {byteIndex: {bitIndex: bit_value}}
  28.    bitIndex 0 is treated as MSB (bit7), I²C is MSB-first.
  29.    """
  30.     out = {}
  31.     for byte_index, bit_dict in bits_map.items():
  32.         # Ensure bits are in ascending bitIndex order
  33.         bits = [bit_dict[i] for i in sorted(bit_dict.keys())]
  34.         val = 0
  35.         for i, b in enumerate(bits):
  36.             # MSB-first: bitIndex 0 -> bit7, 1 -> bit6, ..., 7 -> bit0
  37.             val |= (b & 1) << (7 - i)
  38.         out[byte_index] = val
  39.     return out
  40.  
  41.  
  42. def parse_i2c_bytes_from_sda(events):
  43.     """
  44.    Uses only SDA markers:
  45.    - 'address-bit' for the address byte
  46.    - 'data-bit' for the data bytes
  47.    """
  48.     addr_bits = defaultdict(dict)  # {byteIndex: {bitIndex: v}}
  49.     data_bits = defaultdict(dict)
  50.  
  51.     for e in events:
  52.         marker = e.get("marker", "")
  53.         etype = e.get("type", "")
  54.         if marker == "address-bit" and etype == "address":
  55.             addr_bits[e["byteIndex"]][e["bitIndex"]] = e["v"]
  56.         elif marker == "data-bit" and etype == "data":
  57.             data_bits[e["byteIndex"]][e["bitIndex"]] = e["v"]
  58.  
  59.     addr_bytes = bits_map_to_bytes(addr_bits)
  60.     data_bytes = bits_map_to_bytes(data_bits)
  61.     return addr_bytes, data_bytes
  62.  
  63.  
  64. def bytes_to_ascii(data_bytes):
  65.     return "".join(chr(b) if 32 <= b < 127 else "." for b in data_bytes)
  66.  
  67.  
  68. def xor_decrypt(data_bytes, key_str):
  69.     key_bytes = key_str.encode("ascii")
  70.     return [b ^ k for b, k in zip(data_bytes, cycle(key_bytes))]
  71.  
  72.  
  73. def main():
  74.     if len(sys.argv) != 2:
  75.         print(f"Usage: {sys.argv[0]} sda.json", file=sys.stderr)
  76.         sys.exit(1)
  77.  
  78.     sda_path = sys.argv[1]
  79.  
  80.     # 1. Load SDA events
  81.     events = load_events(sda_path)
  82.     if not events:
  83.         print("No events found in SDA file.", file=sys.stderr)
  84.         sys.exit(1)
  85.  
  86.     # 2. Rebuild address + data bytes from bit markers
  87.     addr_bytes, data_bytes_map = parse_i2c_bytes_from_sda(events)
  88.  
  89.     if 0 not in addr_bytes:
  90.         print("No address byte decoded (byteIndex 0 missing).", file=sys.stderr)
  91.         sys.exit(1)
  92.  
  93.     addr_byte = addr_bytes[0]
  94.     addr_7bit = (addr_byte >> 1) & 0x7F
  95.     rw_bit = addr_byte & 1
  96.  
  97.     print(f"I2C address byte: 0x{addr_byte:02X}")
  98.     print(f"  -> 7-bit address: 0x{addr_7bit:02X}")
  99.     print(f"  -> R/W bit      : {rw_bit} ({'read' if rw_bit else 'write'})")
  100.  
  101.     if addr_7bit != SENSOR_ADDR_7BIT:
  102.         print(
  103.             f"WARNING: decoded 7-bit address 0x{addr_7bit:02X} "
  104.             f"!= expected temperature sensor address 0x{SENSOR_ADDR_7BIT:02X}"
  105.         )
  106.  
  107.     # 3. Collect data bytes in byteIndex order
  108.     if not data_bytes_map:
  109.         print("No data bytes decoded.", file=sys.stderr)
  110.         sys.exit(1)
  111.  
  112.     data_bytes = [data_bytes_map[i] for i in sorted(data_bytes_map.keys())]
  113.  
  114.     print("\nRaw I2C data (from sensor):")
  115.     print("HEX  :", " ".join(f"{b:02X}" for b in data_bytes))
  116.     print("ASCII:", bytes_to_ascii(data_bytes))
  117.  
  118.     # 4. Read and decrypt the I2C bus data using the XOR key: bananza
  119.     decrypted = xor_decrypt(data_bytes, XOR_KEY)
  120.  
  121.     print(f"\nDecrypted I2C data using XOR key '{XOR_KEY}':")
  122.     print("HEX  :", " ".join(f"{b:02X}" for b in decrypted))
  123.     print("ASCII:", bytes_to_ascii(decrypted))
  124.  
  125.  
  126. if __name__ == "__main__":
  127.     main()
  128.  
Advertisement
Add Comment
Please, Sign In to add comment