-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathkaitai2WxHexEditor.py
151 lines (120 loc) · 4.29 KB
/
kaitai2WxHexEditor.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
141
142
143
144
145
146
147
148
149
150
151
#!/usr/bin/env python3
import sys
from kaitaistruct import KaitaiStruct
from plumbum import cli
from pathlib import Path
from bs4 import BeautifulSoup, Tag
import typing
from reprlib import Repr, recursive_repr
import math
import random
def randColor():
a = hex(random.randrange(0, 256))
b = hex(random.randrange(0, 256))
c = hex(random.randrange(0, 256))
a = a[2:]
b = b[2:]
c = c[2:]
if len(a) < 2:
a = "0" + a
if len(b) < 2:
b = "0" + b
if len(c) < 2:
c = "0" + c
z = a + b + c
return "#" + z.upper()
rootElName = "wxHexEditor_XML_TAG"
id = 0
def createTag(name, start, end, fontColor, noteColor):
global id
tg = Tag(None, None, "TAG")
tg.attrs["id"] = str(id)
id += 1
dic = {"start_offset": start, "end_offset": end, "font_colour": fontColor, "note_colour": noteColor, "tag_text": name}
for k, v in dic.items():
st = Tag(None, None, k)
st.string = str(v)
tg.append(st)
return tg
# @recursive_repr()
def dumpStruct(s, root, prefix="", nest=False):
if isinstance(s, list):
for i, item in enumerate(s):
dumpStruct(item, root, prefix + "[" + str(i) + "]")
elif isinstance(s, KaitaiStruct):
if hasattr(s, "_debug"):
for name, descr in s._debug.items():
prop = getattr(s, name)
if not isinstance(prop, KaitaiStruct) or nest:
root.append(createTag(prefix + "." + name, descr["start"], descr["end"], randColor(), randColor())) # WTF with signatures?
#print("name", name)
dumpStruct(prop, root, prefix + "." + name)
if not nest:
p = s._io.pos()
rest = math.ceil(s._io.bits_left)
#print(prefix, "p", p, "rest", rest)
if rest:
root.append(createTag(prefix + ".$rest", p, p + rest, randColor(), randColor()))
def createTags(parsed, filePath=None, nest=False):
x = BeautifulSoup('<?xml version="1.0" encoding="UTF-8"?>\n<' + rootElName + "/>", "xml")
x = x.select_one(rootElName)
fn = Tag(None, None, "filename")
fn.attrs["path"] = str(filePath)
x.append(fn)
dumpStruct(parsed, fn, nest=nest)
return x
from kaitaiStructCompile.utils import KSCDirs, transformName
import kaitaiStructCompile.importer as ksimporter
from kaitaiStructCompile.defaults import subDirsNames
dirs = KSCDirs(subDirsNames, root=None)
ksimporter._importer._searchDirs = ksimporter._importer._searchDirs.__class__((".", dirs.formats))
ksimporter._importer.recursiveSearch = True
import importlib
import warnings
def importKSYSpec(specName:str, dir:Path=None):
assert ksimporter is not None
if dir:
ksimporter._importer.searchDirs.append(dir)
print("Importing "+ksimporter.KSYImporter.marker+"."+specName)
m = __import__(ksimporter.KSYImporter.marker+"."+specName, globals(), locals(), ())
resDict = getattr(ksimporter, specName).__dict__
return resDict
class APPCLI(cli.Application):
nest = cli.Flag("--nest", help="Create parent blocks. Don't use: it is just for my convenience")
specDir = cli.SwitchAttr("--formatsDir", argtype=cli.ExistingDirectory, default=".", list=True, argname='DIR', help="a dir with KSY specs")
def main(self, specName:str, fileName:str):
if ksimporter is not None:
for d in self.specDir:
if d != ".":
d = Path(d)
ksimporter._importer.searchDirs.insert(0, d)
else:
warnings.warn("install kaitaiStructCompile with kaitaiStructCompile.importer!")
if "." in specName: # assumme file name
specPath = Path(specName).absolute()
if specPath.is_file():
specName = specPath.stem
if specPath.suffix.lower() == ".ksy":
specName = specPath.stem
resDict = importKSYSpec(specName, specPath.parent)
else: # assumme python module
pathBackup=sys.path
sys.path=list(sys.path)
try:
parentDir = specPath.parent
sys.path.append(str(parentDir.parent.absolute()))
source=specPath.read_text()
resDict = ksimporter.KSYImporter._runCompiledCode(source, str(specPath), None, {"__builtins__":{"__import__": __import__}, "__name__": parentDir.name})
finally:
sys.path=pathBackup
else:
raise ValueError("No such file "+str(specPath))
else:
resDict = importKSYSpec(specName, None)
className = transformName(specName, True)
specClass = resDict[className]
print("Spec class: ", specClass, file=sys.stderr)
parsed = specClass.from_file(fileName)
Path(str(fileName) + ".tags").write_text(str(createTags(parsed, fileName, nest=self.nest)))
if __name__ == "__main__":
APPCLI.run()