mirror of
https://github.com/DragonMinded/bemaniutils.git
synced 2026-07-12 08:41:32 -05:00
Finish initial RE on bytecode, every opcode is now accounted for.
This commit is contained in:
parent
79b31c7fa2
commit
142ee31d56
|
|
@ -315,7 +315,7 @@ class SWF(TrackedCoverage, VerboseOutput):
|
|||
self.vprint(f"{prefix} {lineno}: {action_name} Flags: {hex(function_flags)}, Name: {funcname}, ByteCode Offset: {hex(bytecode_offset)}, ByteCode Length: {hex(bytecode_count)}")
|
||||
|
||||
# TODO: Need to do something with this parsed function bytecode.
|
||||
function = self.__parse_bytecode(datachunk[offset_ptr:(offset_ptr + bytecode_count)], string_offsets=string_offsets, prefix=prefix + " ")
|
||||
function = self.__parse_bytecode(datachunk[offset_ptr:(offset_ptr + bytecode_count)], string_offsets=string_offsets, prefix=prefix + " ") # NOQA
|
||||
self.vprint(f"{prefix} END_{action_name}")
|
||||
|
||||
offset_ptr += bytecode_count
|
||||
|
|
@ -452,6 +452,19 @@ class SWF(TrackedCoverage, VerboseOutput):
|
|||
obj_count -= 1
|
||||
|
||||
self.vprint(f"{prefix} END_{action_name}")
|
||||
elif opcode == AP2Action.INIT_REGISTER:
|
||||
obj_count = struct.unpack(">B", datachunk[(offset_ptr + 1):(offset_ptr + 2)])[0]
|
||||
offset_ptr += 2
|
||||
|
||||
self.vprint(f"{prefix} {lineno}: {action_name}")
|
||||
|
||||
while obj_count > 0:
|
||||
register_no = struct.unpack(">B", datachunk[offset_ptr:(offset_ptr + 1)])[0]
|
||||
offset_ptr += 1
|
||||
obj_count -= 1
|
||||
|
||||
self.vprint(f"{prefix} REGISTER NO: {register_no}")
|
||||
self.vprint(f"{prefix} END_{action_name}")
|
||||
elif opcode == AP2Action.STORE_REGISTER:
|
||||
obj_count = struct.unpack(">B", datachunk[(offset_ptr + 1):(offset_ptr + 2)])[0]
|
||||
offset_ptr += 2
|
||||
|
|
@ -517,11 +530,25 @@ class SWF(TrackedCoverage, VerboseOutput):
|
|||
# to be absolute instead of relative.
|
||||
jump_offset += offset_ptr - start_offset
|
||||
self.vprint(f"{prefix} {lineno}: {action_name} Offset: {jump_offset}")
|
||||
elif opcode == AP2Action.WITH:
|
||||
skip_offset = struct.unpack(">H", datachunk[(offset_ptr + 1):(offset_ptr + 3)])[0]
|
||||
offset_ptr += 3
|
||||
|
||||
# TODO: I have absolutely no idea what the data which exists in the bytecode buffer at this point
|
||||
# represents...
|
||||
unknown_data = datachunk[offset_ptr:(offset_ptr + skip_offset)] # NOQA
|
||||
offset_ptr += skip_offset
|
||||
self.vprint(f"{prefix} {lineno}: {action_name} Unknown Data Length: {skip_offset}")
|
||||
elif opcode == AP2Action.ADD_NUM_VARIABLE:
|
||||
amount_to_add = struct.unpack(">B", datachunk[(offset_ptr + 1):(offset_ptr + 2)])[0]
|
||||
offset_ptr += 2
|
||||
|
||||
self.vprint(f"{prefix} {lineno}: {action_name} Add Value: {amount_to_add}")
|
||||
elif opcode == AP2Action.GET_URL2:
|
||||
action = struct.unpack(">B", datachunk[(offset_ptr + 1):(offset_ptr + 2)])[0]
|
||||
offset_ptr += 2
|
||||
|
||||
self.vprint(f"{prefix} {lineno}: {action_name} URL Action: {action >> 6}")
|
||||
elif opcode == AP2Action.START_DRAG:
|
||||
constraint = struct.unpack(">b", datachunk[(offset_ptr + 1):(offset_ptr + 2)])[0]
|
||||
offset_ptr += 2
|
||||
|
|
|
|||
|
|
@ -299,6 +299,8 @@ class AP2Action:
|
|||
# Takes the top of the stack and duplicates the object before pushing that object to the stack.
|
||||
PUSH_DUPLICATE = 44
|
||||
|
||||
# Swaps the position of the two two objects on the stack. If there isn't enough to swap, does
|
||||
# nothing.
|
||||
STACK_SWAP = 45
|
||||
|
||||
# Get a member value and place it on the stack.
|
||||
|
|
@ -317,8 +319,15 @@ class AP2Action:
|
|||
# stack for the number of params, and then that many values from the stack as function parameters.
|
||||
CALL_METHOD = 50
|
||||
|
||||
# Takes at least 3 objects on the stack, the third being the number of parameters, the second being
|
||||
# the object to add a method to and the first being the member name.
|
||||
NEW_METHOD = 51
|
||||
|
||||
# Takes two objects, pops them off the stack and adds a boolean object to the stack set to true
|
||||
# if one is an instance of the other or false otherwise.
|
||||
INSTANCEOF = 52
|
||||
|
||||
# Enumerates some sort of object into a variable on the top of the stack.
|
||||
ENUMERATE2 = 53
|
||||
|
||||
# Pop two values from the stack, bitwise and them, push the result.
|
||||
|
|
@ -346,6 +355,8 @@ class AP2Action:
|
|||
# the second or not.
|
||||
GREATER = 61
|
||||
|
||||
# Pops two objects off the stack and does some sort of OOP with them, the first being the superclass
|
||||
# and the second being the subclass.
|
||||
EXTENDS = 62
|
||||
|
||||
# Pop a value from the stack and store it in a register specified by the opcode param. Also push
|
||||
|
|
@ -356,6 +367,12 @@ class AP2Action:
|
|||
# as parameters, and uses that to read the next N bytes of bytecode as the function definition.
|
||||
DEFINE_FUNCTION2 = 64
|
||||
|
||||
# Grabs a 16 bit offset pointer as the opcode param, then skips bytecode processing forward
|
||||
# that many bytes, passing the skipped bytes as pointer data to a function that adds it to the
|
||||
# stack as a pointer type, and then adds a copy of the top of the stack before the pointer as a
|
||||
# second new stack entry. Strangely enough, if the object on the top of the stack doesn't meet
|
||||
# some criteria, the skipped bytes are processed as bytecode. I am not sure what the hell is going
|
||||
# on here.
|
||||
WITH = 66
|
||||
|
||||
# Push an object onto the stack. Creates objects based on the bytecode parameters and pushes
|
||||
|
|
@ -365,6 +382,9 @@ class AP2Action:
|
|||
# Unconditional jump based on bytecode value.
|
||||
JUMP = 68
|
||||
|
||||
# Gets a single 8-bit integer as an opcode param, take the top two bits of that param as the
|
||||
# action to take. Looks like it is similar to SWF GET_URL2 action. Supported actions are 0,
|
||||
# 2 and 3. It pops two objects from the stack to perform against.
|
||||
GET_URL2 = 69
|
||||
|
||||
# Pops a value from the stack, jumps to offset from opcode params if value is truthy.
|
||||
|
|
@ -375,6 +395,8 @@ class AP2Action:
|
|||
# in opcode params.
|
||||
GOTO_FRAME2 = 71
|
||||
|
||||
# Pops the top of the stack, uses that to get a target, pushes a pointer to that target on
|
||||
# the stack.
|
||||
GET_TARGET = 72
|
||||
|
||||
# Given a subtype of check and a positive offset to jump to on true, perform a conditional check.
|
||||
|
|
@ -385,6 +407,9 @@ class AP2Action:
|
|||
# Similar to STORE_REGISTER but does not preserve the value on the stack afterwards.
|
||||
STORE_REGISTER2 = 74
|
||||
|
||||
# Take one opcode parameter for the number of registers to in it, and then one opcode parameter
|
||||
# per the number of registers param as the register number to init, initializing that register
|
||||
# as an "Undefined" object.
|
||||
INIT_REGISTER = 75
|
||||
|
||||
# Similar to ADD_NUM_VARIABLE, but operating on a register number instead of the stack. Takes
|
||||
|
|
@ -447,7 +472,7 @@ class AP2Action:
|
|||
cls.DECREMENT: 'DECREMENT',
|
||||
cls.CALL_METHOD: 'CALL_METHOD',
|
||||
cls.NEW_METHOD: 'NEW_METHOD',
|
||||
cls.INSTANCEOF: 'INSTANCEOF',
|
||||
cls.INSTANCEOF: 'INSTANCE,OF',
|
||||
cls.ENUMERATE2: 'ENUMERATE2',
|
||||
cls.BIT_AND: 'BIT_AND',
|
||||
cls.BIT_OR: 'BIT_OR',
|
||||
|
|
@ -505,10 +530,13 @@ class AP2Action:
|
|||
cls.REMOVE_SPRITE,
|
||||
cls.TRACE,
|
||||
cls.TYPEOF,
|
||||
cls.INSTANCEOF,
|
||||
cls.TARGET_PATH,
|
||||
cls.ENUMERATE2,
|
||||
cls.THROW,
|
||||
cls.CAST_OP,
|
||||
cls.IMPLEMENTS_OP,
|
||||
cls.STACK_SWAP,
|
||||
cls.GET_TIME,
|
||||
cls.RETURN,
|
||||
cls.POP,
|
||||
|
|
@ -516,6 +544,7 @@ class AP2Action:
|
|||
cls.DELETE,
|
||||
cls.DELETE2,
|
||||
cls.NEW_OBJECT,
|
||||
cls.EXTENDS,
|
||||
cls.INIT_ARRAY,
|
||||
cls.INIT_OBJECT,
|
||||
cls.END_DRAG,
|
||||
|
|
@ -529,10 +558,12 @@ class AP2Action:
|
|||
cls.SET_MEMBER,
|
||||
cls.GET_PROPERTY,
|
||||
cls.SET_PROPERTY,
|
||||
cls.NEW_METHOD,
|
||||
cls.CALL_METHOD,
|
||||
cls.CALL_FUNCTION,
|
||||
cls.TO_NUMBER,
|
||||
cls.TO_STRING,
|
||||
cls.GET_TARGET,
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user