-
Notifications
You must be signed in to change notification settings - Fork 11
/
extract_device_icon.py
134 lines (108 loc) · 3.89 KB
/
extract_device_icon.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
# Extract images embedded in the ELF/Code section of ZD2 file
from PIL import Image
def destripe(src, stripes=4, width=None, height=None):
x, y = src.size
h = int(y / stripes)
if not width:
width = int(y / stripes)
if not height:
height = int(8 * stripes)
dest = Image.new('1', (width, height),"white")
for s in range(stripes):
try:
copy = src.crop((0, s * h, 8, (s + 1) * h)).transpose(Image.ROTATE_90)
except:
copy = src.crop((0, s * h, 8, (s + 1) * h)).transpose(Image.Transpose.ROTATE_90)
dest.paste(copy, (0, s * 8, h, (s + 1) * 8))
return(dest)
#--------------------------------------------------
def main():
from argparse import ArgumentParser
from sys import exit
from re import match
import zoomzt2
# from https://github.com/sashs/filebytes
from filebytes.elf import ELF
parser = ArgumentParser(prog="extract_device_icon")
parser.add_argument('files', metavar='FILE', nargs=1,
help='File to process')
parser.add_argument("-e", "--elf",
help="read elf directly, rather than ZD2",
action="store_true", dest="elf")
parser.add_argument("-l", "--list",
help="list available symbols",
action="store_true", dest="list")
parser.add_argument("-t", "--target",
default = "_*picTotalDisplay_.*", dest="target",
help="regex to describe target icon (_*picTotalDisplay_.*)")
parser.add_argument("-S", "--skip",
default = 0, type=int,
help="skip a number of targets when found", dest="skip")
parser.add_argument("-s", "--stripes",
default = 4, type=int,
help="number of 'stripes' in image", dest="stripes")
parser.add_argument("-r", "--raw",
help="saw as raw bytes",
action="store_true", dest="raw")
parser.add_argument("-o", "--output",
help="output image to FILE", dest="output")
options = parser.parse_args()
e = None
if options.elf:
# Read ELF file directly from disk
e = ELF(options.files[0])
else:
# Read data from 'code' section of ZD2 file
infile = open(options.files[0], "rb")
if not infile:
exit("Unable to open FILE for reading")
else:
data = infile.read()
infile.close()
config = zoomzt2.ZD2.parse(data)
e = ELF("fake-elf", config["DATA"]["data"])
if not e:
exit("Error in reading ELF file")
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(options.target, z.name):
print("Target matched:", z.name)
if options.skip:
options.skip -= 1
elif z.header.st_size:
a = z.header.st_value
l = z.header.st_size
break
if not l:
exit("Target not found: " + options.target)
for s in e.segments:
if a >= s.vaddr and a < (s.vaddr + len(s.bytes)):
print("Symbol located:", hex(a))
rawData = bytes(s.bytes[a - s.vaddr : a - s.vaddr + l])
break
if rawData:
if options.raw:
if options.output:
output = open(options.output, "wb")
else:
output = open("raw.bin", "wb")
output.write(rawData)
output.close()
else:
imgSize = (8, len(rawData))
img = Image.frombytes('1', imgSize, rawData, 'raw', '1;I')
img2 = destripe(img, options.stripes)
if options.output:
img2.save(options.output)
else:
img2.save("icon.png")
if __name__ == "__main__":
main()