-
Notifications
You must be signed in to change notification settings - Fork 11
/
decode_bdl.py
140 lines (110 loc) · 4.66 KB
/
decode_bdl.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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#!/usr/bin/python
#
# Script decode/re-encode 'BDL' files from Zoom F/W
# (c) Simon Wood, 16 Dec 2023
#
import zoomzt2
import hashlib
import crcmod
from argparse import ArgumentParser
from sys import exit
from re import match
# requires https://github.com/sashs/filebytes
from filebytes.elf import ELF
# requires https://github.com/construct/construct
from construct import *
TBL = Struct(
"Values" / GreedyRange(Float32l),
)
tables = ["LoFreqTBL", "LoGainTBL", "LoQTBL",
"MidFreqTBL", "MidGainTBL", "MidQTBL",
"HiFreqTBL", "HiGainTBL", "HiQTBL"]
# Values from 'B_OUT_EQ.BDL', uncomment/change the ones you want to update
#LoFreqTBL = [20, 20, 20, 20, 20, 100, 100, 100, 100, 100, 100]
#LoGainTBL = [-25, -20, -15, -10, -5, 0, 1.60000002384186, 3.20000004768372, 4.80000019073486, 6.40000009536743, 8]
#LoQTBL = [1.5, 1.25, 0.800000011920929, 0.699999988079071, 0.699999988079071, 0.699999988079071, 1, 1.25, 1.5, 1.75, 2]
#MidFreqTBL = [1000, 1000, 1000, 1000, 1000, 300, 300, 300, 300, 300, 300]
#MidGainTBL = [-20, -17.5, -15, -10, -5, 0, 2, 4, 6, 8, 10]
#MidQTBL = [4, 4, 4, 4, 2, 1, 1.5, 2, 2.5, 2.75, 3]
#HiFreqTBL = [4000, 4000, 4000, 4000, 4000, 3000, 3000, 3000, 3000, 3000, 3000]
#HiGainTBL = [-20, -15, -10, -5, -2.5, 0, 3.5, 7, 10.5, 14, 17.5]
#HiQTBL = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
#--------------------------------------------------
def main():
from argparse import ArgumentParser
parser = ArgumentParser(prog="decode_bdl")
parser.add_argument('files', metavar='FILE', nargs=1,
help='File to process')
parser.add_argument("-o", "--output",
help="output adjusted BDL to FILE", dest="output")
parser.add_argument("-l", "--list",
help="list available symbols",
action="store_true", dest="list")
options = parser.parse_args()
if not len(options.files):
parser.error("FILE not specified")
# Read data from BDL file
infile = open(options.files[0], "rb")
if not infile:
sys.exit("Unable to open FILE for reading")
else:
data = infile.read()
infile.close()
if data:
config = zoomzt2.ZD2.parse(data)
e = ELF("fake-elf", config["DATA"]["data"])
if not e:
exit("Error in extracting CODE/ELF blob")
for table in tables:
a = None
l = None
rawData = None
for s in e.sections:
if s.name == '.symtab':
if options.list:
for z in s.symbols:
print(z.name)
quit()
for z in s.symbols:
if match(table, z.name):
if z.header.st_size:
a = z.header.st_value
l = z.header.st_size
break
if not l:
print("Table not found: " + table)
else:
for s in e.segments:
if a >= s.vaddr and a < (s.vaddr + len(s.bytes)):
print("Table located:", table, hex(a))
rawData = bytes(s.bytes[a - s.vaddr : a - s.vaddr + l])
values = TBL.parse(rawData)
print(values['Values'])
# Update values as previously specified
if table in globals() and options.output:
print("Updating:", eval(table))
values['Values'] = eval(table)
newData = TBL.build(values)
if len(newData) <= len(rawData):
c = 0
for byte in newData:
s.raw[a - s.vaddr + c] = byte
c += 1
break
if options.output:
outfile = open(options.output, "wb")
if not outfile:
exit("Unable to open output FILE for writing")
# rewrite the processed ELF into the CODE section
config["DATA"]["data"] = bytes(e._bytes)
data = zoomzt2.ZD2.build(config)
# recalc the CRC32
crc32 = crcmod.Crc(0x104c11db7, rev=True, initCrc=0x00000000, xorOut=0xFFFFFFFF)
crc32.update(data[12:-16])
config['checksum'] = crc32.crcValue ^ 0xffffffff
print("Checksum Recalculated: 0x%8.8x" % config['checksum'])
data = zoomzt2.ZD2.build(config)
outfile.write(data)
outfile.close()
if __name__ == "__main__":
main()