#!/bin/python3 import argparse import sys import os # Create a parser parser = argparse.ArgumentParser(description='Patch a M10 firmware for specific frequenc.\nThis is for M10 based on MSP430F233.') parser.add_argument('--verbose', action='store_true', help='Print the details', default=False) # Lecture du binaire subparsers = parser.add_subparsers() p_readbin = subparsers.add_parser("readbin", help='Read the binary file') p_readbin.add_argument('--input', type=str, help='Input file') p_readbin.set_defaults(func="readbin") # Ecriture du binaire p_writebin = subparsers.add_parser("writebin", help='Write the binary file') p_writebin.set_defaults(func="writebin") p_writebin.add_argument('--input', type=str, help='Input file') p_writebin.add_argument('--output', type=str, help='Output file') p_writebin.add_argument('--frequency', type=int, help='Frequency in Hz') args = parser.parse_args() if not hasattr(args, 'func'): print('error: arguments are required\n' 'use --help for more information', file=sys.stderr) sys.exit(os.EX_USAGE) if args.func == "writebin" and args.verbose: print("Writing the binary file") print("File : " + args.input) print("Output : " + args.output) print("Frequency : " + str(args.frequency)) def hex_to_freq(hex_value): inverted_hex_value = hex(int(hex_value[4:6] + hex_value[2:4] + hex_value[0:2], 16)) shifted_bin_value = bin(int(inverted_hex_value, 16) >> 2) if args.verbose: print("Binary value : \t\t" + bin(int(inverted_hex_value, 16))) print("Binary value shifted : \t" + str(shifted_bin_value)) return int(shifted_bin_value, 2) / 512 # function to convert frequence to hex # Coded on 20 bits in binary format. def freq_to_hex(freq_base): freq=freq_base/1000 if args.verbose: print("Frequency: " + str(freq) + "Hz") print("freq * 512 = " + str(freq*512)) print("arrondu freq * 512 = " + str(int(freq*512))) print("binary : " + str(bin(int(freq*512)))) print("binare + 01 : " + str(bin(int(freq*512)) + "01")) print("binary str : " + str(bin(int(freq*512)) + "01").replace("0b","")) value = str(hex(int(str(bin(int(freq*512)) + "01").replace("0b",""),2)))[2:] print("hex value calculated : 0x" + value) # invert the value # draft and dirty value flip-flop value1="0" + value[0:1] value2=value[1:3] value3=value[3:5] if args.verbose: print("value : " + value) print ("value1 : " + value1 + " value2 : " + value2 + " value3 : " + value3) print("hex value inverted : 0x" + value3 + value2 + value1) return value3 + value2 + value1 def write_output_line(line): # write the output line with open(args.output, 'a') as f_out: f_out.write(line) f_out.close() def fix_checksum(line): print("Fixing the checksum") # calculate the checksum checksum = 0 print("Checksum : \n" + line) byte1 = hex(int(line[1:3], 16)) byte2 = hex(int(line[3:5], 16)) byte3 = hex(int(line[5:7], 16)) byte4 = hex(int(line[7:9], 16)) byte5 = hex(int(line[9:11], 16)) byte6 = hex(int(line[11:13], 16)) byte7 = hex(int(line[13:15], 16)) byte8 = hex(int(line[15:17], 16)) byte9 = hex(int(line[17:19], 16)) byte10 = hex(int(line[19:21], 16)) byte11 = hex(int(line[21:23], 16)) byte12 = hex(int(line[23:25], 16)) byte13 = hex(int(line[25:27], 16)) byte14 = hex(int(line[27:29], 16)) byte15 = hex(int(line[29:31], 16)) byte16 = hex(int(line[31:33], 16)) byte17 = hex(int(line[33:35], 16)) byte18 = hex(int(line[35:37], 16)) byte19 = hex(int(line[37:39], 16)) byte20 = hex(int(line[39:41], 16)) # checksum intel hex format checksum = 0x100 - (int(byte1, 16) + int(byte2, 16) + int(byte3, 16) + int(byte4, 16) + int(byte5, 16) + int(byte6, 16) + int(byte7, 16) + int(byte8, 16) + int(byte9, 16) + int(byte10, 16) + int(byte11, 16) + int(byte12, 16) + int(byte13, 16) + int(byte14, 16) + int(byte15, 16) + int(byte16, 16) + int(byte17, 16) + int(byte18, 16) + int(byte19, 16) + int(byte20, 16)) % 0x100 print("Checksum : " + str(hex(checksum))) return checksum # check if the input file exists try: with open(args.input, 'rb') as f: pass except FileNotFoundError: print(f'Error: {args.input} does not exist') exit(1) if args.func == "readbin": print("") print("Reading the frequency value for M10...") # print each line of the input file with open(args.input, 'rb') as f: for line in f: if ":10101000" in line.decode('utf-8'): if args.verbose: print("Found the frequency sequence in Hex Intel format : " + line.decode('utf-8')[9:15]) print("Frequency read : " + str(hex_to_freq(line.decode('utf-8')[9:15]))) exit(0) if args.func == "writebin": if os.path.exists(args.output): os.remove(args.output) with open(args.output, 'wb') as f_new: f_new.close() print("Calculating the frequency "+ str(args.frequency) +"Hz value for M10...") # print each line of the input file with open(args.input, 'rb') as f_in: for line in f_in: if ":10101000" in line.decode('utf-8'): if args.verbose: print("Found the frequency line like this : " + str(line)) print("Frequency sequence in Hex Intel format : " + line.decode('utf-8')[9:15]) print("Actual frequency value : " + str(hex_to_freq(line.decode('utf-8')[9:15])) + "Hz") new_freq = freq_to_hex(args.frequency) print("New frequency value : " + str(args.frequency) + "Hz") # replace the frequency value new_line = line.decode('utf-8').replace(line.decode('utf-8')[9:15], new_freq).upper() print("New line : " + new_line) #replace two last bytes with the checksum new_line = new_line[0:41] + str(hex(fix_checksum(new_line)))[2:].upper() + "\n" print("New line with checksum : " + new_line) write_output_line(new_line) else: write_output_line(line.decode('utf-8')) f_in.close()