123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164 |
- #!/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()
|