From 5d817530b39eb8ad7ce544258b0ba153a7a75c8e Mon Sep 17 00:00:00 2001 From: NMSTEC Date: Fri, 31 Mar 2023 14:54:24 -0700 Subject: [PATCH] Init commit --- ChecksumTools/crcfinder.py | 36 +++++++++++++++++ ChecksumTools/crcfinderusage.jpg | Bin 0 -> 18004 bytes ChecksumTools/fuckbmw.py | 8 ++++ ChecksumTools/fuckbmw2unique.py | 19 +++++++++ ChecksumTools/fuckbmw2uniqueCounter.py | 54 +++++++++++++++++++++++++ ChecksumTools/whatchecksum.py | 51 +++++++++++++++++++++++ ChecksumTools/whatchecksumusage.jpg | Bin 0 -> 31875 bytes 7 files changed, 168 insertions(+) create mode 100644 ChecksumTools/crcfinder.py create mode 100644 ChecksumTools/crcfinderusage.jpg create mode 100644 ChecksumTools/fuckbmw.py create mode 100644 ChecksumTools/fuckbmw2unique.py create mode 100644 ChecksumTools/fuckbmw2uniqueCounter.py create mode 100644 ChecksumTools/whatchecksum.py create mode 100644 ChecksumTools/whatchecksumusage.jpg diff --git a/ChecksumTools/crcfinder.py b/ChecksumTools/crcfinder.py new file mode 100644 index 0000000..d2fa07c --- /dev/null +++ b/ChecksumTools/crcfinder.py @@ -0,0 +1,36 @@ +import sys +import argparse +from typing import List, Tuple + + +def crc(data: List[int], len_: int, start_val: int, poly: int) -> int: + crc_val = start_val + for i in range(len_): + crc_val ^= data[i] + for _ in range(8): + if (crc_val & 0x80) != 0: + crc_val = ((crc_val << 1) ^ poly) & 0xFF + else: + crc_val <<= 1 + crc_val &= 0xFF + return crc_val ^ 0xFF + +def main(data: List[List[int]]): + for poly in range(0x01, 0xFF): + for start in range(0x00, 0x100): + found = 0 + for pkt in data: + if crc(pkt[:7], 7, start, poly) == pkt[7]: + found += 1 + if found >= 4: + print(f"found = {found}! poly = {poly:02X} start = {start:02X}") +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="CRC finder") + parser.add_argument("data", nargs="+", help="Data packets (8-byte hex strings)") + + args = parser.parse_args() + + data = [list(bytes.fromhex(pkt)) for pkt in args.data] + + main(data) +#thank you Alexey Esaulenko for original program design in CAN decoders \ No newline at end of file diff --git a/ChecksumTools/crcfinderusage.jpg b/ChecksumTools/crcfinderusage.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7a6993b60bfffe7bdb7f52deaff052162f25a21f GIT binary patch literal 18004 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 M<-8C70Byhj*_fsHX8-^I literal 0 HcmV?d00001 diff --git a/ChecksumTools/fuckbmw.py b/ChecksumTools/fuckbmw.py new file mode 100644 index 0000000..5fd84af --- /dev/null +++ b/ChecksumTools/fuckbmw.py @@ -0,0 +1,8 @@ +import sys + +input_bytes = bytearray.fromhex(sys.argv[1]) +checksum = bytearray.fromhex(sys.argv[2]) +gayness = sum(input_bytes) +gayness += int.from_bytes(checksum, byteorder='big') +result = (gayness >> 8) + (gayness & 0xFF) +print(hex(result)) \ No newline at end of file diff --git a/ChecksumTools/fuckbmw2unique.py b/ChecksumTools/fuckbmw2unique.py new file mode 100644 index 0000000..fa3f0d6 --- /dev/null +++ b/ChecksumTools/fuckbmw2unique.py @@ -0,0 +1,19 @@ +import csv + +unique_addresses = set() +with open('input.csv', 'r') as in_file, open('output.csv', 'w', newline='') as out_file: + + csv_reader = csv.DictReader(in_file) + csv_writer = csv.writer(out_file) + csv_writer.writerow(['Time Stamp', 'ID', 'Extended', 'Dir', 'Bus', 'LEN', 'D1', 'D2', 'D3', 'D4', 'D5', 'D6', 'D7', 'D8']) + for row in csv_reader: + d_values = [int(row[f"D{i}"], 16) for i in range(2, 9)] + + gaysome = sum(d_values) + int(row['ID'], 16) + gaysome = (gaysome & 0xFF) + (gaysome >> 8) + + if gaysome == int(row['D1'], 16): + address = row['ID'] + if address not in unique_addresses: + csv_writer.writerow([row['Time Stamp'], row['ID'], row['Extended'], row['Dir'], row['Bus'], row['LEN'], row['D1'], row['D2'], row['D3'], row['D4'], row['D5'], row['D6'], row['D7'], row['D8']]) + unique_addresses.add(address) diff --git a/ChecksumTools/fuckbmw2uniqueCounter.py b/ChecksumTools/fuckbmw2uniqueCounter.py new file mode 100644 index 0000000..6485fe6 --- /dev/null +++ b/ChecksumTools/fuckbmw2uniqueCounter.py @@ -0,0 +1,54 @@ +import csv +failed_rows = [] +unique_addresses = {} + +with open('input.csv', 'r') as in_file, open('output.csv', 'w', newline='') as out_file, open('failedoutputs.csv', 'w', newline='') as fail_file: + + + csv_reader = csv.DictReader(in_file) + csv_writer = csv.writer(out_file) + fail_writer = csv.writer(fail_file) + + + csv_writer.writerow(['Time Stamp', 'ID', 'Extended', 'Dir', 'Bus', 'LEN', 'D1', 'D2', 'D3', 'D4', 'D5', 'D6', 'D7', 'D8']) + fail_writer.writerow(['Time Stamp', 'ID', 'Extended', 'Dir', 'Bus', 'LEN', 'D1', 'D2', 'D3', 'D4', 'D5', 'D6', 'D7', 'D8']) + + for row in csv_reader: + d_values = [int(row[f"D{i}"], 16) for i in range(2, 9)] + checksum = sum(d_values) + int(row['ID'], 16) + checksum = (checksum & 0xFF) + (checksum >> 8) + d1 = int(row['D1'], 16) + if d1 <= checksum or (d1 > checksum and d1 - checksum == 256): + address = row['ID'] + if address not in unique_addresses: + + csv_writer.writerow([row['Time Stamp'], row['ID'], row['Extended'], row['Dir'], row['Bus'], row['LEN'], row['D1'], row['D2'], row['D3'], row['D4'], row['D5'], row['D6'], row['D7'], row['D8']]) + unique_addresses[address] = [1, 0] + else: + unique_addresses[address][0] += 1 + else: + failed_rows.append(row) + fail_writer.writerow([row['Time Stamp'], row['ID'], row['Extended'], row['Dir'], row['Bus'], row['LEN'], row['D1'], row['D2'], row['D3'], row['D4'], row['D5'], row['D6'], row['D7'], row['D8']]) + + address = row['ID'] + if address not in unique_addresses: + unique_addresses[address] = [0, 1] + else: + unique_addresses[address][1] += 1 + for row in failed_rows: + address = row['ID'] + d1 = int(row['D1'], 16) + d8 = int(row['D8'], 16) + if address not in unique_addresses: + unique_addresses[address] = [0, 1, 0, 0] # Initialize with D1 and D8 matched counts set to 0 + if is_d1_checksum: + unique_addresses[address][2] += 1 + if is_d8_checksum: + unique_addresses[address][3] += 1 + + sorted_addresses = sorted(unique_addresses.items(), key=lambda x: x[1][0], reverse=True) + print("Address Successes Failures Total D1_Matched D8_Matched") + for address, counts in sorted_addresses: + total = counts[0] + counts[1] + if total > 0: + print(f"{address} {counts[0]} {counts[1]} {total} {counts[2]} {counts[3]}") diff --git a/ChecksumTools/whatchecksum.py b/ChecksumTools/whatchecksum.py new file mode 100644 index 0000000..813ff33 --- /dev/null +++ b/ChecksumTools/whatchecksum.py @@ -0,0 +1,51 @@ +import argparse +from typing import List +import numpy as np + +def crc(data: List[int], len_: int, start_val: int, poly: int) -> int: + crc_val = start_val + for i in range(len_): + crc_val ^= data[i] + for _ in range(8): + if (crc_val & 0x80) != 0: + crc_val = ((crc_val << 1) ^ poly) & 0xFF + else: + crc_val <<= 1 + crc_val &= 0xFF + return crc_val ^ 0xFF + +def is_sum_checksum_valid(messages: List[List[int]], correlation_threshold: float) -> bool: + for idx in [0, -1]: + sums = [sum(message[:idx] + message[idx+1:]) % 256 for message in messages] + checksums = [message[idx] for message in messages] + stddev_sums = np.std(sums) + stddev_checksums = np.std(checksums) + if stddev_sums == 0 or stddev_checksums == 0: + continue + correlation = np.corrcoef(sums, checksums)[0, 1] + if correlation > correlation_threshold: + return True + return False + +def detect_checksum_type(messages: List[List[int]], threshold: float = 0.5, correlation_threshold: float = 0.9): + total_messages = len(messages) + crc_matches = 0 + if is_sum_checksum_valid(messages, correlation_threshold): + return "Sum" + for message in messages: + data_len = len(message) - 1 + for poly in range(0x01, 0xFF): + for start in range(0x00, 0x100): + if crc(message[:data_len], data_len, start, poly) == message[-1]: + crc_matches += 1 + if crc_matches / total_messages > threshold: + return "CRC" + return "Unknown" + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Checksum type detector for CAN bus messages") + parser.add_argument("messages", nargs="+", help="CAN bus messages (AABBCCDDEEFF0011)") + args = parser.parse_args() + messages = [list(bytes.fromhex(msg)) for msg in args.messages] + checksum_type = detect_checksum_type(messages) + print(f"The detected checksum type is: {checksum_type}") diff --git a/ChecksumTools/whatchecksumusage.jpg b/ChecksumTools/whatchecksumusage.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ad581c6e3d3e61d05eef72372adabbf0514c51d8 GIT binary patch literal 31875 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 G+4x_Ju|W9% literal 0 HcmV?d00001