-
Notifications
You must be signed in to change notification settings - Fork 22
/
Copy pathfwtool.py
115 lines (101 loc) · 3.31 KB
/
fwtool.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
from intelhex import IntelHex
import tools.asm as asm
import tracker.firmware as firmware
import argparse
import hashlib
def read_infile(infile):
try:
fi = open(infile, "rb")
data = fi.read()
fi.close()
except:
data = None
return data
def pack(infile, outfile):
print("Opening %s" % infile)
fw = IntelHex()
fw.loadbin(infile)
print("Packing to %s" % outfile)
fw.write_hex_file(outfile, write_start_addr=False)
print("Done")
def unpack(infile, outfile):
print("Opening %s" % infile)
fw = IntelHex(infile)
print("Unpacking to %s" % outfile)
fw.tobinfile(outfile)
print("Done")
def build(infile, outfile):
print("Opening %s" % infile)
data = read_infile(infile)
if not data:
print("Input file could not be opened")
return
digest = hashlib.md5(data).hexdigest()
print("MD5: %s" % digest)
patches = firmware.get_patches(digest)
if not patches:
print("This firmware currently is not supported")
return
count = len(patches)
print("Found %d patch%s" % (count, "es" if count > 1 else ""))
if not count:
print("No patch available. Aborting.")
return
print("Decoding input file")
fw = IntelHex(infile)
n = 0
for patch in patches:
code_snippets = []
n += 1
print("\nPatch #%d\nDescription: \"%s\"" % (n, patch.description))
apply_patch = input("Would you like to apply this patch (y/n)? ")
if apply_patch.upper() != "Y":
print("Skipping patch #%d" % n)
continue
for loc in patch.PatchLocs:
a = asm.Assembler(
loc.entry,
loc.code,
symbols=loc.symbols,
max_size=loc.max_size,
thumb=loc.thumbmode)
success = a.assemble()
if not success:
print("Error: could not assemble patch. Aborting.")
return
code_snippets.append(a)
print("Applying patch #%d" % n)
for cs in code_snippets:
fw.puts(cs.get_entry(), bytes.fromhex(cs.get_as_hex_string()))
print("Creating output file: %s" % outfile)
fw.write_hex_file(outfile, write_start_addr=False)
print("Done")
return
def main():
parser = argparse.ArgumentParser()
parser.add_argument("infile", help="name/path of input file")
parser.add_argument("outfile", help="name/path of output file")
g = parser.add_mutually_exclusive_group()
g.add_argument(
"-b", "--build",
help="apply RETracker patches to Tracker firmware",
action="store_true")
g.add_argument(
"-u", "--unpack",
help="unpack Tracker firmware (.ptf) to binary format",
action="store_true")
g.add_argument("-p", "--pack",
help="create Tracker firmware (.ptf) from binary",
action="store_true")
args = parser.parse_args()
if args.build:
build(args.infile, args.outfile)
elif args.unpack:
unpack(args.infile, args.outfile)
elif args.pack:
pack(args.infile, args.outfile)
else:
parser.print_help()
return
if __name__ == "__main__":
main()