forked from letscontrolit/ESPEasy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
crc2.py
116 lines (100 loc) · 4.78 KB
/
crc2.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import sys
import binascii
import struct
import md5
import os
MD5DUMMY = "MD5_MD5_MD5_MD5_BoundariesOfTheSegmentsGoHere..." #48 chars
FILENAMEDUMMY = "ThisIsTheDummyPlaceHolderForTheBinaryFilename64ByteLongFilenames" #64 chars
MemorySegmentStart,MemorySegmentEnd,MemoryContent=[],[],[]
##################################################################
# this subroutine shows the segments of a part
##################################################################
def showSegments (fileContent,offset):
global MemorySegmentStart, MemorySegmentEnd, MemoryContent
header = struct.unpack("ii", fileContent[offset:offset+8])
herestr =""
herestr2 =""
MemorySegmentStart.append(struct.pack("I",header[0]))
MemorySegmentEnd.append(struct.pack("I",header[0]+header[1]))
MemoryContent.append(fileContent[offset+8:offset+8+header[1]])
if fileContent.find( MD5DUMMY, offset+8, offset+8+header[1]) >0 :
herestr= " <-- CRC is here."
if fileContent.find( FILENAMEDUMMY, offset+8, offset+8+header[1]) >0 :
herestr2= " <-- filename is here."
print ("SEGMENT "+ str(len(MemorySegmentStart)-1)+ ": memory position: " + hex(header[0])+" to " + hex(header[0]+header[1]) + " length: " + hex(header[1])+herestr+herestr2)
#print ("first byte positoin in file: " + hex( offset+8))
#print ("last byte postion in file: " + hex(offset+8+header[1]-1))
return (8+offset+ header[1]); # return start of next segment
##################################################################
# this subroutine shows the parts of a binary file
##################################################################
def showParts(fileContent, offset):
header = struct.unpack("BBBBi", fileContent[offset:offset+8])
print ('\n\nBINARY PART\nSegments: ') + (hex(header[1]))
nextpos =offset+8
for x in range (0,header[1]):
nextpos = showSegments(fileContent,nextpos)
nextSegmentOffset = (fileContent.find("\xe9", nextpos))
return nextSegmentOffset
##################################################################
# MAIN
##################################################################
#if len(sys.argv) !=2 :
# print ("please give a filename")
# k=input("press close to exit")
# sys.exit(1)
FileName = sys.argv[1]#"C:/ArduinoPortable/sketchbooks/build/sketch_jan15a.ino.bin"
#FileName = "C:/ArduinoPortable/sketchbooks/build/sketch_jan15a.ino.bin"
print( "\n\nReplacing dummy MD5 checksum in .bin file")
with open(FileName, mode='rb') as file: # b is important -> binary
nextpos =0;
fileContent = file.read()
while nextpos >=0:
nextpos = showParts(fileContent,nextpos)
startArray,endArray,hashString = "","",""
includeStr = "hash includes segments:"
# memory sections:
# 0: bootloader (not readable)
# 1: program memory (SPI flash)
# 2: unknown but stable
# 3: RAM (initialized by bin file. Can be read but changes as you go :-( )
# 4: RAM
for i in (1,2 ): # use only stable segments, must be 4 in total. We use 2.
startArray =startArray + MemorySegmentStart[i]
endArray = endArray + MemorySegmentEnd[i]
hashString =hashString + MemoryContent[i]
with open(FileName+str(i), mode='wb') as file: # b is important -> binary
file.write(MemoryContent[i])
includeStr = includeStr +" "+ str(i)
print (includeStr)
# IMPORTANT: pad array with zeros if you use only 3 segments (see above)
while len(startArray) < 16 :
startArray =startArray + struct.pack("I",0)
endArray = endArray + struct.pack("I",0)
# debug print (binascii.hexlify(startArray))
# debug print (binascii.hexlify(endArray))
if (len(endArray) + len (startArray)) != 32 :
print("ERROR: please make sure you add / remove padding if you change the semgents.")
BinaryFileName = "";
if fileContent.find( FILENAMEDUMMY) < 0:
print("ERROR: FILENAMEDUMMY dummy not found in binary")
else:
BinaryFileName=os.path.basename(FileName) +"\0"
if len(BinaryFileName) >64: # check that filename is <48 chars
BinaryFileName=BinaryFileName[0:64] # truncate if necessary. 49th char in ESP is zero already
else:
BinaryFileName= BinaryFileName.ljust(64,'\0'); # pad with zeros.
if fileContent.find( MD5DUMMY) < 0:
print("ERROR: MD5 dummy not found in binary")
else:
hashString=hashString.replace (MD5DUMMY,"",1)
m = md5.new()
m.update (hashString) #use segment 1
md5hash = m.digest()
print("MD5 hash: "+ m.hexdigest())
print("\nwriting output file:\n" + FileName)
fileContent=fileContent.replace(MD5DUMMY,md5hash+startArray+endArray)
fileContent=fileContent.replace(FILENAMEDUMMY,BinaryFileName)
with open(FileName, mode='wb') as file: # b is important -> binary
file.write(fileContent)
#k=input("press close to exit")