Skip to content

Commit d08730e

Browse files
committed
FrameDetector: Fix editor instruction parser
- Fix regex so it can match xor instructions - Force bitwise operators to use unsigned parameters - Only set the endianness bit for add/mul/smul instructions - Allow using signed values as parameter for add instructions
1 parent cefb635 commit d08730e

File tree

1 file changed

+18
-9
lines changed

1 file changed

+18
-9
lines changed

zbnt/FrameDetector.py

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class FrameDetector(AxiDevice):
4747
}
4848

4949
_regex_comp_instr = re.compile("^(?:nop|(s?[lg]tq?|eq|or|and)(8|16|24|32|40|48|56|64|[fd])(l?)|eof)$")
50-
_regex_edit_instr = re.compile("^(?:nop|setr|(set|(?:xn)?or|and|add|s?mul)(8|16|32|64|[fd])(l?)|drop|corrupt)$")
50+
_regex_edit_instr = re.compile("^(?:nop|setr|(set|(?:xn|x)?or|and|add|s?mul)(8|16|32|64|[fd])(l?)|drop|corrupt)$")
5151

5252
_edit_opcode_dict = {
5353
"nop": 0b00_00_000_0,
@@ -241,7 +241,7 @@ def __parse_comparator_instr(self, i, instr, param, offset):
241241
else:
242242
instr_size = int(op_size) // 8
243243
instr_param = int(param, 0).to_bytes(instr_size, byteorder="little", signed=bool(opcode & 0b1000))
244-
except ValueError:
244+
except:
245245
raise ValueError("line {0}: Invalid parameter for instruction: '{1}'".format(i, param))
246246

247247
opcode |= ["eq", "gt", "lt", "gtq", "ltq", "or", "and"].index(base) << 4
@@ -288,14 +288,23 @@ def __parse_editor_instr(self, i, instr, param, offset):
288288
instr_param = b""
289289
instr_size = 0
290290
opcode = FrameDetector._edit_opcode_dict[base]
291+
big_endian = False
292+
signed = False
291293

292-
if len(endianness) == 0 and base != "set":
293-
# Big-endian
294-
opcode |= 0b10000
294+
if len(endianness) == 0:
295+
big_endian = True
296+
297+
if base in ["add", "mul", "smul"]:
298+
# Big-endian
299+
opcode |= 0b10000
300+
301+
if (opcode & 0b0100) != 0b0100:
302+
# Bitwise operations are always unsigned, for everything else check the signed bit
303+
signed = bool(opcode & 0b100000)
295304

296305
if base == "add" and param[0] == "-":
297306
# Set as signed, allows using negative parameters
298-
opcode |= 0b100000
307+
signed = True
299308

300309
try:
301310
if op_size == "f":
@@ -306,16 +315,16 @@ def __parse_editor_instr(self, i, instr, param, offset):
306315
instr_param = encode_double(float(param))
307316
else:
308317
instr_size = int(op_size) // 8
309-
instr_param = int(param, 0).to_bytes(instr_size, byteorder="little", signed=bool(opcode & 0b100000))
310-
except ValueError:
318+
instr_param = int(param, 0).to_bytes(instr_size, byteorder="little", signed=signed)
319+
except:
311320
raise ValueError("line {0}: Invalid parameter for instruction: '{1}'".format(i, param))
312321

313322
if offset + instr_size > self.max_script_size:
314323
raise ValueError("line {0}: Instruction ends beyond the script size limit: {1} + {2} > {3}".format(i, offset, instr_size, self.max_script_size))
315324

316325
opcode |= int(math.log2(instr_size)) << 6
317326

318-
if opcode & 0b10000:
327+
if big_endian:
319328
instr_param = instr_param[::-1]
320329

321330
res = [ (offset, opcode, instr_param[0]) ]

0 commit comments

Comments
 (0)